mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-04-07 00:16:15 +00:00
Add an unified input capture interface
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.limelight.binding.input.capture;
|
||||
|
||||
|
||||
public class NullCaptureProvider extends InputCaptureProvider {
|
||||
@Override
|
||||
public void enableCapture() {}
|
||||
|
||||
@Override
|
||||
public void disableCapture() {}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user