From 6cc40b12357ae339abcb44517810af304bab77ea Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sat, 13 Feb 2016 08:17:20 -0600 Subject: Improve stability of the Wii U Gamecube Controller adapter under Android. Under failure conditions of the GC Adapter, When interface count is zero and we can't open the device. Then there were race conditions on shutdown of the threads which could result in crashing. Make adapter opening more robust like the Mayflash DolphinBar. Make shutdown more robust by making the read thread control the write thread. Make sure that there is actual data to be written when kicking the write thread. So it doesn't attempt a write a shutdown. Make a toast on screen to tell the user that the adapter needs to be unplugged and plugged back in again for it to work. --- .../dolphinemu/utils/Java_GCAdapter.java | 74 +++++++++++++--------- 1 file changed, 43 insertions(+), 31 deletions(-) (limited to 'Source/Android/app/src/main/java') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/Java_GCAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/Java_GCAdapter.java index 87d816d93e..37ab4c6b5f 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/Java_GCAdapter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/Java_GCAdapter.java @@ -9,6 +9,7 @@ import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbEndpoint; import android.hardware.usb.UsbInterface; import android.hardware.usb.UsbManager; +import android.widget.Toast; import org.dolphinemu.dolphinemu.NativeLibrary; import org.dolphinemu.dolphinemu.services.USBPermService; @@ -76,32 +77,16 @@ public class Java_GCAdapter { } public static int Input() { - if (usb_in != null) - { - int read = usb_con.bulkTransfer(usb_in, controller_payload, controller_payload.length, 16); - return read; - } - else - { - // TODO Is this right? - return 0; - } + int read = usb_con.bulkTransfer(usb_in, controller_payload, controller_payload.length, 16); + return read; } public static int Output(byte[] rumble) { - if (usb_out != null) - { - int size = usb_con.bulkTransfer(usb_out, rumble, 5, 16); - return size; - } - else - { - // TODO Is this right? - return 0; - } + int size = usb_con.bulkTransfer(usb_out, rumble, 5, 16); + return size; } - public static void OpenAdapter() + public static boolean OpenAdapter() { HashMap devices = manager.getDeviceList(); Iterator it = devices.entrySet().iterator(); @@ -113,20 +98,47 @@ public class Java_GCAdapter { if (manager.hasPermission(dev)) { usb_con = manager.openDevice(dev); - UsbConfiguration conf = dev.getConfiguration(0); - usb_intf = conf.getInterface(0); - usb_con.claimInterface(usb_intf, true); - for (int i = 0; i < usb_intf.getEndpointCount(); ++i) - if (usb_intf.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN) - usb_in = usb_intf.getEndpoint(i); + + Log.info("GCAdapter: Number of configurations: " + dev.getConfigurationCount()); + Log.info("GCAdapter: Number of interfaces: " + dev.getInterfaceCount()); + + if (dev.getConfigurationCount() > 0 && dev.getInterfaceCount() > 0) + { + UsbConfiguration conf = dev.getConfiguration(0); + usb_intf = conf.getInterface(0); + usb_con.claimInterface(usb_intf, true); + + Log.info("GCAdapter: Number of endpoints: " + usb_intf.getEndpointCount()); + + if (usb_intf.getEndpointCount() == 2) + { + for (int i = 0; i < usb_intf.getEndpointCount(); ++i) + if (usb_intf.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN) + usb_in = usb_intf.getEndpoint(i); + else + usb_out = usb_intf.getEndpoint(i); + + InitAdapter(); + return true; + } else - usb_out = usb_intf.getEndpoint(i); + { + usb_con.releaseInterface(usb_intf); + } + } - InitAdapter(); - return; + NativeLibrary.sEmulationActivity.runOnUiThread(new Runnable() + { + @Override + public void run() + { + Toast.makeText(NativeLibrary.sEmulationActivity, "GameCube Adapter couldn't be opened. Please re-plug the device.", Toast.LENGTH_LONG).show(); + } + }); + usb_con.close(); } } - } + return false; } } -- cgit v1.2.3