From 88f9b68db7dde3078e499ab1a2b82e7e2c0bc14c Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 24 Feb 2018 20:17:14 -0800 Subject: [PATCH] Add mouse emulation and bind all USB devices options --- app/src/main/java/com/limelight/Game.java | 2 +- .../binding/input/ControllerHandler.java | 32 +++++++++++-------- .../input/driver/UsbDriverService.java | 11 ++++--- .../preferences/PreferenceConfiguration.java | 8 +++++ app/src/main/res/values/strings.xml | 8 +++-- app/src/main/res/xml/preferences.xml | 10 ++++++ 6 files changed, 51 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/limelight/Game.java b/app/src/main/java/com/limelight/Game.java index a657188f..94dca216 100644 --- a/app/src/main/java/com/limelight/Game.java +++ b/app/src/main/java/com/limelight/Game.java @@ -367,7 +367,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, // Initialize the connection conn = new NvConnection(host, uniqueId, config, PlatformBinding.getCryptoProvider(this)); - controllerHandler = new ControllerHandler(this, conn, this, prefConfig.multiController, prefConfig.deadzonePercentage); + controllerHandler = new ControllerHandler(this, conn, this, prefConfig); InputManager inputManager = (InputManager) getSystemService(Context.INPUT_SERVICE); inputManager.registerInputDeviceListener(controllerHandler, null); diff --git a/app/src/main/java/com/limelight/binding/input/ControllerHandler.java b/app/src/main/java/com/limelight/binding/input/ControllerHandler.java index 77c5341d..edef2fa4 100644 --- a/app/src/main/java/com/limelight/binding/input/ControllerHandler.java +++ b/app/src/main/java/com/limelight/binding/input/ControllerHandler.java @@ -18,6 +18,7 @@ import com.limelight.binding.input.driver.UsbDriverService; import com.limelight.nvstream.NvConnection; import com.limelight.nvstream.input.ControllerPacket; import com.limelight.nvstream.input.MouseButtonPacket; +import com.limelight.preferences.PreferenceConfiguration; import com.limelight.ui.GameGestures; import com.limelight.utils.Vector2d; @@ -50,18 +51,18 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD private final GameGestures gestures; private boolean hasGameController; - private final boolean multiControllerEnabled; + private final PreferenceConfiguration prefConfig; private short currentControllers, initialControllers; - public ControllerHandler(Context activityContext, NvConnection conn, GameGestures gestures, boolean multiControllerEnabled, int deadzonePercentage) { + public ControllerHandler(Context activityContext, NvConnection conn, GameGestures gestures, PreferenceConfiguration prefConfig) { this.activityContext = activityContext; this.conn = conn; this.gestures = gestures; - this.multiControllerEnabled = multiControllerEnabled; + this.prefConfig = prefConfig; // HACK: For now we're hardcoding a 10% deadzone. Some deadzone // is required for controller batching support to work. - deadzonePercentage = 10; + int deadzonePercentage = 10; int[] ids = InputDevice.getDeviceIds(); for (int id : ids) { @@ -167,11 +168,15 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD } // Count all USB devices that match our drivers - UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE); - for (UsbDevice dev : usbManager.getDeviceList().values()) { - if (UsbDriverService.shouldClaimDevice(dev)) { - LimeLog.info("Counting UsbDevice: "+dev.getDeviceName()); - mask |= 1 << count++; + if (PreferenceConfiguration.readPreferences(context).usbDriver) { + UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE); + for (UsbDevice dev : usbManager.getDeviceList().values()) { + // We explicitly ask not to claim devices that appear as InputDevices + // otherwise we will double count them. + if (UsbDriverService.shouldClaimDevice(dev, false)) { + LimeLog.info("Counting UsbDevice: "+dev.getDeviceName()); + mask |= 1 << count++; + } } } @@ -215,7 +220,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD LimeLog.info("Built-in buttons hardcoded as controller 0"); context.controllerNumber = 0; } - else if (multiControllerEnabled && devContext.hasJoystickAxes) { + else if (prefConfig.multiController && devContext.hasJoystickAxes) { context.controllerNumber = 0; LimeLog.info("Reserving the next available controller number"); @@ -239,7 +244,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD } } else { - if (multiControllerEnabled) { + if (prefConfig.multiController) { context.controllerNumber = 0; LimeLog.info("Reserving the next available controller number"); @@ -522,7 +527,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD } private short getActiveControllerMask() { - if (multiControllerEnabled) { + if (prefConfig.multiController) { return (short)(currentControllers | initialControllers); } else { @@ -985,7 +990,8 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD // Make sure it's real by checking that the key is actually down before taking // any action. if ((context.inputMap & ControllerPacket.PLAY_FLAG) != 0 && - SystemClock.uptimeMillis() - context.startDownTime > ControllerHandler.START_DOWN_TIME_MOUSE_MODE_MS) { + SystemClock.uptimeMillis() - context.startDownTime > ControllerHandler.START_DOWN_TIME_MOUSE_MODE_MS && + prefConfig.mouseEmulation) { toggleMouseEmulation(context); } context.inputMap &= ~ControllerPacket.PLAY_FLAG; 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 d4f16275..345e62af 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 @@ -18,6 +18,7 @@ import android.widget.Toast; import com.limelight.LimeLog; import com.limelight.R; +import com.limelight.preferences.PreferenceConfiguration; import java.util.ArrayList; @@ -27,6 +28,7 @@ public class UsbDriverService extends Service implements UsbDriverListener { "com.limelight.USB_PERMISSION"; private UsbManager usbManager; + private PreferenceConfiguration prefConfig; private final UsbEventReceiver receiver = new UsbEventReceiver(); private final UsbDriverBinder binder = new UsbDriverBinder(); @@ -119,7 +121,7 @@ public class UsbDriverService extends Service implements UsbDriverListener { private void handleUsbDeviceState(UsbDevice device) { // Are we able to operate it? - if (shouldClaimDevice(device)) { + if (shouldClaimDevice(device, prefConfig.bindAllUsb)) { // Do we have permission yet? if (!usbManager.hasPermission(device)) { // Let's ask for permission @@ -194,16 +196,17 @@ public class UsbDriverService extends Service implements UsbDriverListener { } } - public static boolean shouldClaimDevice(UsbDevice device) { + public static boolean shouldClaimDevice(UsbDevice device, boolean claimAllAvailable) { // We always bind to XB1 controllers but only bind to XB360 controllers // if we know the kernel isn't already driving this device. return XboxOneController.canClaimDevice(device) || - (!isRecognizedInputDevice(device) && Xbox360Controller.canClaimDevice(device)); + ((!isRecognizedInputDevice(device) || claimAllAvailable) && Xbox360Controller.canClaimDevice(device)); } @Override public void onCreate() { this.usbManager = (UsbManager) getSystemService(Context.USB_SERVICE); + this.prefConfig = PreferenceConfiguration.readPreferences(this); // Register for USB attach broadcasts and permission completions IntentFilter filter = new IntentFilter(); @@ -213,7 +216,7 @@ public class UsbDriverService extends Service implements UsbDriverListener { // Enumerate existing devices for (UsbDevice dev : usbManager.getDeviceList().values()) { - if (shouldClaimDevice(dev)) { + if (shouldClaimDevice(dev, prefConfig.bindAllUsb)) { // Start the process of claiming this device handleUsbDeviceState(dev); } diff --git a/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java b/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java index 04c0d3d0..f3750c7a 100644 --- a/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java +++ b/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java @@ -27,6 +27,8 @@ public class PreferenceConfiguration { private static final String DISABLE_FRAME_DROP_PREF_STRING = "checkbox_disable_frame_drop"; private static final String ENABLE_HDR_PREF_STRING = "checkbox_enable_hdr"; private static final String ENABLE_PIP_PREF_STRING = "checkbox_enable_pip"; + private static final String BIND_ALL_USB_STRING = "checkbox_usb_bind_all"; + private static final String MOUSE_EMULATION_STRING = "checkbox_mouse_emulation"; private static final int BITRATE_DEFAULT_720_30 = 5; private static final int BITRATE_DEFAULT_720_60 = 10; @@ -54,6 +56,8 @@ public class PreferenceConfiguration { private static final boolean DEFAULT_DISABLE_FRAME_DROP = false; private static final boolean DEFAULT_ENABLE_HDR = false; private static final boolean DEFAULT_ENABLE_PIP = false; + private static final boolean DEFAULT_BIND_ALL_USB = false; + private static final boolean DEFAULT_MOUSE_EMULATION = true; public static final int FORCE_H265_ON = -1; public static final int AUTOSELECT_H265 = 0; @@ -72,6 +76,8 @@ public class PreferenceConfiguration { public boolean disableFrameDrop; public boolean enableHdr; public boolean enablePip; + public boolean bindAllUsb; + public boolean mouseEmulation; public static int getDefaultBitrate(String resFpsString) { if (resFpsString.equals("720p30")) { @@ -218,6 +224,8 @@ public class PreferenceConfiguration { config.disableFrameDrop = prefs.getBoolean(DISABLE_FRAME_DROP_PREF_STRING, DEFAULT_DISABLE_FRAME_DROP); config.enableHdr = prefs.getBoolean(ENABLE_HDR_PREF_STRING, DEFAULT_ENABLE_HDR); config.enablePip = prefs.getBoolean(ENABLE_PIP_PREF_STRING, DEFAULT_ENABLE_PIP); + config.bindAllUsb = prefs.getBoolean(BIND_ALL_USB_STRING, DEFAULT_BIND_ALL_USB); + config.mouseEmulation = prefs.getBoolean(MOUSE_EMULATION_STRING, DEFAULT_MOUSE_EMULATION); return config; } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 03bf2413..0f87bcf9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -98,7 +98,7 @@ Successfully added computer Unable to resolve PC address. Make sure you didn\'t make a typo in the address. You must enter an IP address - That address doesn\'t look right. You must your router\'s public IP address for streaming over the Internet. + That address doesn\'t look right. You must use your router\'s public IP address for streaming over the Internet. Basic Settings @@ -125,7 +125,11 @@ Adjust analog stick deadzone % Xbox 360/One controller driver - Enables a built-in USB driver for devices without native Xbox controller support. + Enables a built-in USB driver for devices without native Xbox controller support + Override Android controller support + Forces Moonlight\'s USB driver to take over all supported Xbox gamepads + Mouse emulation via gamepad + Long pressing the Start button will put the gamepad into mouse mode On-screen Controls Settings Show on-screen controls diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 27fa953b..ce9d4f08 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -56,6 +56,16 @@ android:title="@string/title_checkbox_xb1_driver" android:summary="@string/summary_checkbox_xb1_driver" android:defaultValue="true" /> + +