Initial pointer capture work for O

This commit is contained in:
Cameron Gutman 2017-05-31 20:50:47 -07:00
parent d06912e81a
commit e66b1ebec9
4 changed files with 83 additions and 7 deletions

View File

@ -170,6 +170,14 @@ public class Game extends Activity implements SurfaceHolder.Callback,
streamView = (StreamView) findViewById(R.id.surfaceView);
streamView.setOnGenericMotionListener(this);
streamView.setOnTouchListener(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
streamView.setOnCapturedPointerListener(new View.OnCapturedPointerListener() {
@Override
public boolean onCapturedPointer(View view, MotionEvent motionEvent) {
return handleMotionEvent(motionEvent, true);
}
});
}
// Warn the user if they're on a metered connection
checkDataConnection();
@ -277,6 +285,19 @@ public class Game extends Activity implements SurfaceHolder.Callback,
streamView.getHolder().addCallback(this);
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// If the window gains focus while we're grabbing input,
// we'll need to request for pointer capture again
if (grabbedInput) {
inputCaptureProvider.enableCapture();
}
}
}
private void prepareDisplayForRendering() {
Display display = getWindowManager().getDefaultDisplay();
WindowManager.LayoutParams windowLayoutParams = getWindow().getAttributes();
@ -659,8 +680,12 @@ public class Game extends Activity implements SurfaceHolder.Callback,
inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
}
// Returns true if the event was consumed
private boolean handleMotionEvent(MotionEvent event) {
return handleMotionEvent(event, false);
}
// Returns true if the event was consumed
private boolean handleMotionEvent(MotionEvent event, boolean capturedMouseCallback) {
// Pass through keyboard input if we're not grabbing
if (!grabbedInput) {
return false;
@ -714,7 +739,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
}
// Get relative axis values if we can
if (inputCaptureProvider.eventHasRelativeMouseAxes(event)) {
if (inputCaptureProvider.eventHasRelativeMouseAxes(event) || capturedMouseCallback) {
// Send the deltas straight from the motion event
conn.sendMouseMove((short) inputCaptureProvider.getRelativeAxisX(event),
(short) inputCaptureProvider.getRelativeAxisY(event));

View File

@ -0,0 +1,46 @@
package com.limelight.binding.input.capture;
import android.annotation.TargetApi;
import android.os.Build;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;
@TargetApi(Build.VERSION_CODES.O)
public class AndroidNativePointerCaptureProvider extends InputCaptureProvider {
private View targetView;
public AndroidNativePointerCaptureProvider(View targetView) {
this.targetView = targetView;
}
public static boolean isCaptureProviderSupported() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
}
@Override
public void enableCapture() {
targetView.requestPointerCapture();
}
@Override
public void disableCapture() {
targetView.releasePointerCapture();
}
@Override
public boolean eventHasRelativeMouseAxes(MotionEvent event) {
return (event.getSource() & InputDevice.SOURCE_MOUSE_RELATIVE) != 0;
}
@Override
public float getRelativeAxisX(MotionEvent event) {
return event.getX();
}
@Override
public float getRelativeAxisY(MotionEvent event) {
return event.getY();
}
}

View File

@ -10,11 +10,11 @@ import android.view.View;
import android.view.ViewGroup;
@TargetApi(Build.VERSION_CODES.N)
public class AndroidCaptureProvider extends InputCaptureProvider {
public class AndroidPointerIconCaptureProvider extends InputCaptureProvider {
private ViewGroup rootViewGroup;
private Context context;
public AndroidCaptureProvider(Activity activity) {
public AndroidPointerIconCaptureProvider(Activity activity) {
this.context = activity;
this.rootViewGroup = (ViewGroup) activity.getWindow().getDecorView();
}

View File

@ -3,6 +3,7 @@ package com.limelight.binding.input.capture;
import android.app.Activity;
import com.limelight.LimeLog;
import com.limelight.R;
import com.limelight.binding.input.evdev.EvdevCaptureProvider;
import com.limelight.binding.input.evdev.EvdevListener;
@ -15,13 +16,17 @@ public class InputCaptureManager {
LimeLog.info("Using NVIDIA mouse capture extension");
return new ShieldCaptureProvider(activity);
}
else if (AndroidNativePointerCaptureProvider.isCaptureProviderSupported()) {
LimeLog.info("Using Android O+ native mouse capture");
return new AndroidNativePointerCaptureProvider(activity.findViewById(R.id.surfaceView));
}
else if (EvdevCaptureProvider.isCaptureProviderSupported()) {
LimeLog.info("Using Evdev mouse capture");
return new EvdevCaptureProvider(activity, rootListener);
}
else if (AndroidCaptureProvider.isCaptureProviderSupported()) {
LimeLog.info("Using Android N+ native mouse capture");
return new AndroidCaptureProvider(activity);
else if (AndroidPointerIconCaptureProvider.isCaptureProviderSupported()) {
LimeLog.info("Using Android N+ pointer hiding");
return new AndroidPointerIconCaptureProvider(activity);
}
else {
LimeLog.info("Mouse capture not available");