From 4486a126ad8d186b9af4c4bfcd0f76fdca27990b Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 8 Nov 2015 19:03:12 -0800 Subject: [PATCH] Fix some listener bugs in the XB1 driver --- .../input/driver/UsbDriverService.java | 63 ++++++++++++++----- .../input/driver/XboxOneController.java | 32 +++++----- 2 files changed, 63 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/com/limelight/binding/input/driver/UsbDriverService.java b/app/src/main/java/com/limelight/binding/input/driver/UsbDriverService.java index 92091bee..fdafbcc0 100644 --- a/app/src/main/java/com/limelight/binding/input/driver/UsbDriverService.java +++ b/app/src/main/java/com/limelight/binding/input/driver/UsbDriverService.java @@ -14,7 +14,7 @@ import android.os.IBinder; import java.util.ArrayList; -public class UsbDriverService extends Service { +public class UsbDriverService extends Service implements UsbDriverListener { private static final String ACTION_USB_PERMISSION = "com.limelight.USB_PERMISSION"; @@ -29,6 +29,38 @@ public class UsbDriverService extends Service { private UsbDriverListener listener; private static int nextDeviceId; + @Override + public void reportControllerState(int controllerId, short buttonFlags, float leftStickX, float leftStickY, float rightStickX, float rightStickY, float leftTrigger, float rightTrigger) { + // Call through to the client's listener + if (listener != null) { + listener.reportControllerState(controllerId, buttonFlags, leftStickX, leftStickY, rightStickX, rightStickY, leftTrigger, rightTrigger); + } + } + + @Override + public void deviceRemoved(int controllerId) { + // Remove the the controller from our list (if not removed already) + for (XboxOneController controller : controllers) { + if (controller.getControllerId() == controllerId) { + controllers.remove(controller); + break; + } + } + + // Call through to the client's listener + if (listener != null) { + listener.deviceRemoved(controllerId); + } + } + + @Override + public void deviceAdded(int controllerId) { + // Call through to the client's listener + if (listener != null) { + listener.deviceAdded(controllerId); + } + } + public class UsbEventReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { @@ -56,13 +88,13 @@ public class UsbDriverService extends Service { public class UsbDriverBinder extends Binder { public void setListener(UsbDriverListener listener) { UsbDriverService.this.listener = listener; - updateListeners(); - } - } - private void updateListeners() { - for (XboxOneController controller : controllers) { - controller.setListener(listener); + // Report all controllerMap that already exist + if (listener != null) { + for (XboxOneController controller : controllers) { + listener.deviceAdded(controller.getControllerId()); + } + } } } @@ -80,23 +112,20 @@ public class UsbDriverService extends Service { UsbDeviceConnection connection = usbManager.openDevice(device); // Try to initialize it - XboxOneController controller = new XboxOneController(device, connection, nextDeviceId++); + XboxOneController controller = new XboxOneController(device, connection, nextDeviceId++, this); if (!controller.start()) { connection.close(); return; } - // Add to the list + // Add this controller to the list controllers.add(controller); - - // Add listener - updateListeners(); } } @Override public void onCreate() { - usbManager = (UsbManager) getSystemService(Context.USB_SERVICE); + this.usbManager = (UsbManager) getSystemService(Context.USB_SERVICE); // Register for USB attach broadcasts and permission completions IntentFilter filter = new IntentFilter(); @@ -118,13 +147,13 @@ public class UsbDriverService extends Service { // Stop the attachment receiver unregisterReceiver(receiver); - // Remove all listeners + // Remove listeners listener = null; - updateListeners(); // Stop all controllers - for (XboxOneController controller : controllers) { - controller.stop(); + while (controllers.size() > 0) { + // Stop and remove the controller + controllers.remove(0).stop(); } } diff --git a/app/src/main/java/com/limelight/binding/input/driver/XboxOneController.java b/app/src/main/java/com/limelight/binding/input/driver/XboxOneController.java index 79072792..acbcabb5 100644 --- a/app/src/main/java/com/limelight/binding/input/driver/XboxOneController.java +++ b/app/src/main/java/com/limelight/binding/input/driver/XboxOneController.java @@ -5,7 +5,6 @@ import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbEndpoint; import android.hardware.usb.UsbInterface; -import android.media.MediaCodec; import com.limelight.LimeLog; import com.limelight.binding.video.MediaCodecHelper; @@ -35,18 +34,15 @@ public class XboxOneController { // FIXME: odata_serial private static final byte[] XB1_INIT_DATA = {0x05, 0x20, 0x00, 0x01, 0x00}; - public XboxOneController(UsbDevice device, UsbDeviceConnection connection, int deviceId) { + public XboxOneController(UsbDevice device, UsbDeviceConnection connection, int deviceId, UsbDriverListener listener) { this.device = device; this.connection = connection; this.deviceId = deviceId; + this.listener = listener; } - public void setListener(UsbDriverListener listener) { - this.listener = listener; - - if (listener != null) { - listener.deviceAdded(deviceId); - } + public int getControllerId() { + return this.deviceId; } private void setButtonFlag(int buttonFlag, int data) { @@ -59,10 +55,8 @@ public class XboxOneController { } private void reportInput() { - if (listener != null) { - listener.reportControllerState(deviceId, buttonFlags, leftStickX, leftStickY, - rightStickX, rightStickY, leftTrigger, rightTrigger); - } + listener.reportControllerState(deviceId, buttonFlags, leftStickX, leftStickY, + rightStickX, rightStickY, leftTrigger, rightTrigger); } private void processButtons(ByteBuffer buffer) { @@ -203,21 +197,29 @@ public class XboxOneController { // Start listening for controller input startInputThread(inEndpt); + // Report this device added via the listener + listener.deviceAdded(deviceId); + return true; } public void stop() { + if (stopped) { + return; + } + stopped = true; + // Stop the input thread if (inputThread != null) { inputThread.interrupt(); inputThread = null; } - if (listener != null) { - listener.deviceRemoved(deviceId); - } + // Report the device removed + listener.deviceRemoved(deviceId); + // Close the USB connection connection.close(); }