Merge pull request #3553 from Sonicadvance1/more_android_gc_adapter

Implement requesting permission for using the GC Wii U Adapter.
This commit is contained in:
Ryan Houdek 2016-01-29 23:12:37 -05:00
commit f1ca95eec7
4 changed files with 59 additions and 7 deletions

View File

@ -3,7 +3,9 @@ package org.dolphinemu.dolphinemu.activities;
import android.app.Activity; import android.app.Activity;
import android.app.ActivityOptions; import android.app.ActivityOptions;
import android.app.Fragment; import android.app.Fragment;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.hardware.usb.UsbManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
@ -30,6 +32,7 @@ import org.dolphinemu.dolphinemu.fragments.MenuFragment;
import org.dolphinemu.dolphinemu.fragments.SaveStateFragment; import org.dolphinemu.dolphinemu.fragments.SaveStateFragment;
import org.dolphinemu.dolphinemu.ui.main.MainPresenter; import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
import org.dolphinemu.dolphinemu.utils.Animations; import org.dolphinemu.dolphinemu.utils.Animations;
import org.dolphinemu.dolphinemu.utils.Java_GCAdapter;
import org.dolphinemu.dolphinemu.utils.Log; import org.dolphinemu.dolphinemu.utils.Log;
import java.util.List; import java.util.List;
@ -115,6 +118,8 @@ public final class EmulationActivity extends AppCompatActivity
setTheme(themeId); setTheme(themeId);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Java_GCAdapter.our_activity = this;
Java_GCAdapter.manager = (UsbManager) getSystemService(Context.USB_SERVICE);
// Picasso will take a while to load these big-ass screenshots. So don't run // Picasso will take a while to load these big-ass screenshots. So don't run
// the animation until we say so. // the animation until we say so.

View File

@ -0,0 +1,14 @@
package org.dolphinemu.dolphinemu.services;
import android.app.IntentService;
import android.content.Intent;
public final class USBPermService extends IntentService
{
public USBPermService() { super("USBPermService"); }
// Needed when extending IntentService.
// We don't care about the results of the intent handler for this.
@Override
protected void onHandleIntent(Intent intent) {}
}

View File

@ -1,6 +1,9 @@
package org.dolphinemu.dolphinemu.utils; package org.dolphinemu.dolphinemu.utils;
import android.app.Activity; import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.hardware.usb.UsbConfiguration; import android.hardware.usb.UsbConfiguration;
import android.hardware.usb.UsbConstants; import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDevice;
@ -9,8 +12,11 @@ import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface; import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager;
import org.dolphinemu.dolphinemu.services.USBPermService;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map;
public class Java_GCAdapter { public class Java_GCAdapter {
public static UsbManager manager; public static UsbManager manager;
@ -23,6 +29,26 @@ public class Java_GCAdapter {
static UsbEndpoint usb_in; static UsbEndpoint usb_in;
static UsbEndpoint usb_out; static UsbEndpoint usb_out;
private static void RequestPermission()
{
HashMap<String, UsbDevice> devices = manager.getDeviceList();
for (Map.Entry<String, UsbDevice> pair : devices.entrySet())
{
UsbDevice dev = (UsbDevice) pair.getValue();
if (dev.getProductId() == 0x0337 && dev.getVendorId() == 0x057e)
{
if (!manager.hasPermission(dev))
{
Intent intent = new Intent();
PendingIntent pend_intent;
intent.setClass(our_activity, USBPermService.class);
pend_intent = PendingIntent.getService(our_activity, 0, intent, 0);
manager.requestPermission(dev, pend_intent);
}
}
}
}
public static void Shutdown() public static void Shutdown()
{ {
usb_con.close(); usb_con.close();
@ -32,14 +58,16 @@ public class Java_GCAdapter {
public static boolean QueryAdapter() public static boolean QueryAdapter()
{ {
HashMap<String, UsbDevice> devices = manager.getDeviceList(); HashMap<String, UsbDevice> devices = manager.getDeviceList();
Iterator it = devices.entrySet().iterator(); for (Map.Entry<String, UsbDevice> pair : devices.entrySet())
while (it.hasNext())
{ {
HashMap.Entry pair = (HashMap.Entry) it.next();
UsbDevice dev = (UsbDevice) pair.getValue(); UsbDevice dev = (UsbDevice) pair.getValue();
if (dev.getProductId() == 0x0337 && dev.getVendorId() == 0x057e) if (dev.getProductId() == 0x0337 && dev.getVendorId() == 0x057e)
{
if (manager.hasPermission(dev)) if (manager.hasPermission(dev))
return true; return true;
else
RequestPermission();
}
} }
return false; return false;
} }

View File

@ -35,7 +35,7 @@ static u8 s_controller_rumble[4];
// Input handling // Input handling
static std::mutex s_read_mutex; static std::mutex s_read_mutex;
static u8 s_controller_payload[37]; static u8 s_controller_payload[37];
static int s_controller_payload_size = 0; static std::atomic<int> s_controller_payload_size{0};
// Output handling // Output handling
static std::mutex s_write_mutex; static std::mutex s_write_mutex;
@ -102,12 +102,13 @@ static void Read()
while (s_read_adapter_thread_running.IsSet()) while (s_read_adapter_thread_running.IsSet())
{ {
s_controller_payload_size = env->CallStaticIntMethod(s_adapter_class, input_func); int read_size = env->CallStaticIntMethod(s_adapter_class, input_func);
jbyte* java_data = env->GetByteArrayElements(*java_controller_payload, nullptr); jbyte* java_data = env->GetByteArrayElements(*java_controller_payload, nullptr);
{ {
std::lock_guard<std::mutex> lk(s_read_mutex); std::lock_guard<std::mutex> lk(s_read_mutex);
memcpy(s_controller_payload, java_data, 0x37); memcpy(s_controller_payload, java_data, 0x37);
s_controller_payload_size.store(read_size);
} }
env->ReleaseByteArrayElements(*java_controller_payload, java_data, 0); env->ReleaseByteArrayElements(*java_controller_payload, java_data, 0);
@ -187,6 +188,8 @@ void Init()
void Setup() void Setup()
{ {
s_fd = 0;
s_read_adapter_thread_running.Set(true); s_read_adapter_thread_running.Set(true);
s_read_adapter_thread = std::thread(Read); s_read_adapter_thread = std::thread(Read);
@ -244,16 +247,18 @@ void Input(int chan, GCPadStatus* pad)
if (!UseAdapter() || !s_detected || !s_fd) if (!UseAdapter() || !s_detected || !s_fd)
return; return;
int payload_size = 0;
u8 controller_payload_copy[37]; u8 controller_payload_copy[37];
{ {
std::lock_guard<std::mutex> lk(s_read_mutex); std::lock_guard<std::mutex> lk(s_read_mutex);
std::copy(std::begin(s_controller_payload), std::end(s_controller_payload), std::begin(controller_payload_copy)); std::copy(std::begin(s_controller_payload), std::end(s_controller_payload), std::begin(controller_payload_copy));
payload_size = s_controller_payload_size.load();
} }
if (s_controller_payload_size != sizeof(controller_payload_copy)) if (payload_size != sizeof(controller_payload_copy))
{ {
ERROR_LOG(SERIALINTERFACE, "error reading payload (size: %d, type: %02x)", s_controller_payload_size, controller_payload_copy[0]); ERROR_LOG(SERIALINTERFACE, "error reading payload (size: %d, type: %02x)", payload_size, controller_payload_copy[0]);
Reset(); Reset();
} }
else else