Add an unified input capture interface

This commit is contained in:
Cameron Gutman
2016-06-13 20:33:43 -05:00
parent 117b555fcd
commit 541ac44be4
6 changed files with 137 additions and 57 deletions

View File

@@ -0,0 +1,28 @@
package com.limelight.binding.input.capture;
import android.app.Activity;
import com.limelight.LimeLog;
import com.limelight.binding.input.evdev.EvdevCaptureProvider;
import com.limelight.binding.input.evdev.EvdevListener;
public class InputCaptureManager {
public static InputCaptureProvider getInputCaptureProvider(Activity activity, EvdevListener rootListener) {
/*if (AndroidCaptureProvider.isCaptureProviderSupported()) {
LimeLog.info("Using Android N+ native mouse capture");
return new AndroidCaptureProvider();
}
else*/ if (ShieldCaptureProvider.isCaptureProviderSupported()) {
LimeLog.info("Using NVIDIA mouse capture extension");
return new ShieldCaptureProvider(activity);
}
else if (EvdevCaptureProvider.isCaptureProviderSupported()) {
LimeLog.info("Using Evdev mouse capture");
return new EvdevCaptureProvider(activity, rootListener);
}
else {
LimeLog.info("Mouse capture not available");
return new NullCaptureProvider();
}
}
}

View File

@@ -0,0 +1,21 @@
package com.limelight.binding.input.capture;
import android.view.MotionEvent;
public abstract class InputCaptureProvider {
public abstract void enableCapture();
public abstract void disableCapture();
public void destroy() {}
public boolean eventHasRelativeMouseAxes(MotionEvent event) {
return false;
}
public float getRelativeAxisX(MotionEvent event) {
return 0;
}
public float getRelativeAxisY(MotionEvent event) {
return 0;
}
}

View File

@@ -0,0 +1,10 @@
package com.limelight.binding.input.capture;
public class NullCaptureProvider extends InputCaptureProvider {
@Override
public void enableCapture() {}
@Override
public void disableCapture() {}
}

View File

@@ -1,4 +1,4 @@
package com.limelight.binding.input;
package com.limelight.binding.input.capture;
import android.content.Context;
@@ -18,12 +18,14 @@ import java.lang.reflect.Method;
//
// http://docs.nvidia.com/gameworks/index.html#technologies/mobile/game_controller_handling_mouse.htm
public class NvMouseHelper {
public class ShieldCaptureProvider extends InputCaptureProvider {
private static boolean nvExtensionSupported;
private static Method methodSetCursorVisibility;
private static int AXIS_RELATIVE_X;
private static int AXIS_RELATIVE_Y;
private Context context;
static {
try {
methodSetCursorVisibility = InputManager.class.getMethod("setCursorVisibility", boolean.class);
@@ -36,16 +38,19 @@ public class NvMouseHelper {
nvExtensionSupported = true;
} catch (Exception e) {
LimeLog.info("NvMouseHelper not supported");
nvExtensionSupported = false;
}
}
public static boolean setCursorVisibility(Context context, boolean visible) {
if (!nvExtensionSupported) {
return false;
}
public ShieldCaptureProvider(Context context) {
this.context = context;
}
public static boolean isCaptureProviderSupported() {
return nvExtensionSupported;
}
private boolean setCursorVisibility(boolean visible) {
try {
methodSetCursorVisibility.invoke(context.getSystemService(Context.INPUT_SERVICE), visible);
return true;
@@ -58,19 +63,29 @@ public class NvMouseHelper {
return false;
}
public static boolean eventHasRelativeMouseAxes(MotionEvent event) {
if (!nvExtensionSupported) {
return false;
}
@Override
public void enableCapture() {
setCursorVisibility(false);
}
@Override
public void disableCapture() {
setCursorVisibility(true);
}
@Override
public boolean eventHasRelativeMouseAxes(MotionEvent event) {
return event.getAxisValue(AXIS_RELATIVE_X) != 0 ||
event.getAxisValue(AXIS_RELATIVE_Y) != 0;
}
public static float getRelativeAxisX(MotionEvent event) {
@Override
public float getRelativeAxisX(MotionEvent event) {
return event.getAxisValue(AXIS_RELATIVE_X);
}
public static float getRelativeAxisY(MotionEvent event) {
@Override
public float getRelativeAxisY(MotionEvent event) {
return event.getAxisValue(AXIS_RELATIVE_Y);
}
}

View File

@@ -4,6 +4,8 @@ import android.app.Activity;
import android.widget.Toast;
import com.limelight.LimeLog;
import com.limelight.LimelightBuildProps;
import com.limelight.binding.input.capture.InputCaptureProvider;
import java.io.DataOutputStream;
import java.io.File;
@@ -13,7 +15,7 @@ import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class EvdevHandler {
public class EvdevCaptureProvider extends InputCaptureProvider {
private final EvdevListener listener;
private final String libraryPath;
@@ -25,6 +27,7 @@ public class EvdevHandler {
private ServerSocket servSock;
private Socket evdevSock;
private Activity activity;
private boolean started = false;
private static final byte UNGRAB_REQUEST = 1;
private static final byte REGRAB_REQUEST = 2;
@@ -163,24 +166,39 @@ public class EvdevHandler {
}
};
public EvdevHandler(Activity activity, EvdevListener listener) {
public EvdevCaptureProvider(Activity activity, EvdevListener listener) {
this.listener = listener;
this.activity = activity;
this.libraryPath = activity.getApplicationInfo().nativeLibraryDir;
}
public void regrabAll() {
if (!shutdown && evdevOut != null) {
try {
evdevOut.write(REGRAB_REQUEST);
} catch (IOException e) {
e.printStackTrace();
public static boolean isCaptureProviderSupported() {
return LimelightBuildProps.ROOT_BUILD;
}
@Override
public void enableCapture() {
if (!started) {
// Start the handler thread if it's our first time
// capturing
handlerThread.start();
started = true;
}
else {
// Send a request to regrab if we're already capturing
if (!shutdown && evdevOut != null) {
try {
evdevOut.write(REGRAB_REQUEST);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void ungrabAll() {
if (!shutdown && evdevOut != null) {
@Override
public void disableCapture() {
if (started && !shutdown && evdevOut != null) {
try {
evdevOut.write(UNGRAB_REQUEST);
} catch (IOException e) {
@@ -189,15 +207,16 @@ public class EvdevHandler {
}
}
public void start() {
handlerThread.start();
}
public void stop() {
@Override
public void destroy() {
// We need to stop the process in this context otherwise
// we could get stuck waiting on output from the process
// in order to terminate it.
if (!started) {
return;
}
shutdown = true;
handlerThread.interrupt();