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:
commit
f1ca95eec7
|
@ -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.
|
||||||
|
|
|
@ -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) {}
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue