Turn screen on on right-click

The right-click is almost useless on Android, so use it to turn the
screen on.

Add a new control event type (command) to request the server to turn the
screen on.
This commit is contained in:
Romain Vimont
2018-02-02 14:52:23 +01:00
parent 228545cefd
commit a139509f11
9 changed files with 107 additions and 1 deletions

View File

@@ -9,11 +9,14 @@ public class ControlEvent {
public static final int TYPE_TEXT = 1;
public static final int TYPE_MOUSE = 2;
public static final int TYPE_SCROLL = 3;
public static final int TYPE_COMMAND = 4;
public static final int COMMAND_SCREEN_ON = 0;
private int type;
private String text;
private int metaState; // KeyEvent.META_*
private int action; // KeyEvent.ACTION_* or MotionEvent.ACTION_*
private int action; // KeyEvent.ACTION_* or MotionEvent.ACTION_* or COMMAND_*
private int keycode; // KeyEvent.KEYCODE_*
private int buttons; // MotionEvent.BUTTON_*
private Position position;
@@ -57,6 +60,13 @@ public class ControlEvent {
return event;
}
public static ControlEvent createCommandControlEvent(int action) {
ControlEvent event = new ControlEvent();
event.type = TYPE_COMMAND;
event.action = action;
return event;
}
public int getType() {
return type;
}

View File

@@ -10,6 +10,7 @@ public class ControlEventReader {
private static final int KEYCODE_PAYLOAD_LENGTH = 9;
private static final int MOUSE_PAYLOAD_LENGTH = 13;
private static final int SCROLL_PAYLOAD_LENGTH = 16;
private static final int COMMAND_PAYLOAD_LENGTH = 1;
private final byte[] rawBuffer = new byte[128];
private final ByteBuffer buffer = ByteBuffer.wrap(rawBuffer);
@@ -86,6 +87,13 @@ public class ControlEventReader {
int vScroll = buffer.getInt();
return ControlEvent.createScrollControlEvent(position, hScroll, vScroll);
}
case ControlEvent.TYPE_COMMAND: {
if (buffer.remaining() < COMMAND_PAYLOAD_LENGTH) {
break;
}
int action = toUnsigned(buffer.get());
return ControlEvent.createCommandControlEvent(action);
}
default:
Ln.w("Unknown event type: " + type);
}

View File

@@ -6,6 +6,7 @@ import android.os.RemoteException;
import android.view.IRotationWatcher;
import com.genymobile.scrcpy.wrappers.InputManager;
import com.genymobile.scrcpy.wrappers.PowerManager;
import com.genymobile.scrcpy.wrappers.ServiceManager;
public final class Device {
@@ -93,6 +94,10 @@ public final class Device {
return serviceManager.getInputManager();
}
public PowerManager getPowerManager() {
return serviceManager.getPowerManager();
}
public void registerRotationWatcher(IRotationWatcher rotationWatcher) {
serviceManager.getWindowManager().registerRotationWatcher(rotationWatcher);
}

View File

@@ -9,6 +9,7 @@ import android.view.KeyEvent;
import android.view.MotionEvent;
import com.genymobile.scrcpy.wrappers.InputManager;
import com.genymobile.scrcpy.wrappers.PowerManager;
import java.io.IOException;
@@ -16,6 +17,7 @@ public class EventController {
private final Device device;
private final InputManager inputManager;
private final PowerManager powerManager;
private final DesktopConnection connection;
private final KeyCharacterMap charMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
@@ -28,6 +30,7 @@ public class EventController {
this.device = device;
this.connection = connection;
inputManager = device.getInputManager();
powerManager = device.getPowerManager();
initPointer();
}
@@ -79,6 +82,10 @@ public class EventController {
break;
case ControlEvent.TYPE_SCROLL:
injectScroll(controlEvent.getPosition(), controlEvent.getHScroll(), controlEvent.getVScroll());
break;
case ControlEvent.TYPE_COMMAND:
executeCommand(controlEvent.getAction());
break;
}
return true;
}
@@ -137,7 +144,24 @@ public class EventController {
return injectEvent(event);
}
private boolean injectKeycode(int keyCode) {
return injectKeyEvent(KeyEvent.ACTION_DOWN, keyCode, 0, 0)
&& injectKeyEvent(KeyEvent.ACTION_UP, keyCode, 0, 0);
}
private boolean injectEvent(InputEvent event) {
return inputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
}
private boolean turnScreenOn() {
return powerManager.isScreenOn() || injectKeycode(KeyEvent.KEYCODE_POWER);
}
private boolean executeCommand(int action) {
switch (action) {
case ControlEvent.COMMAND_SCREEN_ON:
return turnScreenOn();
}
return false;
}
}

View File

@@ -0,0 +1,30 @@
package com.genymobile.scrcpy.wrappers;
import android.os.Build;
import android.os.IInterface;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class PowerManager {
private final IInterface manager;
private final Method isScreenOnMethod;
public PowerManager(IInterface manager) {
this.manager = manager;
try {
String methodName = Build.VERSION.SDK_INT >= 20 ? "isInteractive" : "isScreenOn";
isScreenOnMethod = manager.getClass().getMethod(methodName);
} catch (NoSuchMethodException e) {
throw new AssertionError(e);
}
}
public boolean isScreenOn() {
try {
return (Boolean) isScreenOnMethod.invoke(manager);
} catch (InvocationTargetException | IllegalAccessException e) {
throw new AssertionError(e);
}
}
}

View File

@@ -37,4 +37,8 @@ public class ServiceManager {
public InputManager getInputManager() {
return new InputManager(getService("input", "android.hardware.input.IInputManager"));
}
public PowerManager getPowerManager() {
return new PowerManager(getService("power", "android.os.IPowerManager"));
}
}