提交 75ce0b5c 编写于 作者: R Romain Vimont

Forward DOWN and UP separately for right-click

The shortcut "back on screen on" is a bit special: the control is
requested by the client, but the actual event injection (POWER or BACK)
is determined on the device.

To properly inject DOWN and UP events for BACK, transmit the action as
a control parameter.

If the screen is off:
 - on DOWN, inject POWER (DOWN and UP) (wake up the device immediately)
 - on UP, do nothing
If the screen is on:
 - on DOWN, inject BACK DOWN
 - on UP, inject BACK UP

A corner case is when the screen turns off between the DOWN and UP
event. In that case, a BACK UP event will be injected, so it's harmless.

With this change, the actual BACK is handled by Android on UP on the
device (instead of DOWN). This is consistent with the keyboard shortcut
(Mod+b) behavior.
上级 5c65f3c1
...@@ -67,6 +67,9 @@ control_msg_serialize(const struct control_msg *msg, unsigned char *buf) { ...@@ -67,6 +67,9 @@ control_msg_serialize(const struct control_msg *msg, unsigned char *buf) {
buffer_write32be(&buf[17], buffer_write32be(&buf[17],
(uint32_t) msg->inject_scroll_event.vscroll); (uint32_t) msg->inject_scroll_event.vscroll);
return 21; return 21;
case CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON:
buf[1] = msg->inject_keycode.action;
return 2;
case CONTROL_MSG_TYPE_SET_CLIPBOARD: { case CONTROL_MSG_TYPE_SET_CLIPBOARD: {
buf[1] = !!msg->set_clipboard.paste; buf[1] = !!msg->set_clipboard.paste;
size_t len = write_string(msg->set_clipboard.text, size_t len = write_string(msg->set_clipboard.text,
...@@ -77,7 +80,6 @@ control_msg_serialize(const struct control_msg *msg, unsigned char *buf) { ...@@ -77,7 +80,6 @@ control_msg_serialize(const struct control_msg *msg, unsigned char *buf) {
case CONTROL_MSG_TYPE_SET_SCREEN_POWER_MODE: case CONTROL_MSG_TYPE_SET_SCREEN_POWER_MODE:
buf[1] = msg->set_screen_power_mode.mode; buf[1] = msg->set_screen_power_mode.mode;
return 2; return 2;
case CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON:
case CONTROL_MSG_TYPE_EXPAND_NOTIFICATION_PANEL: case CONTROL_MSG_TYPE_EXPAND_NOTIFICATION_PANEL:
case CONTROL_MSG_TYPE_COLLAPSE_NOTIFICATION_PANEL: case CONTROL_MSG_TYPE_COLLAPSE_NOTIFICATION_PANEL:
case CONTROL_MSG_TYPE_GET_CLIPBOARD: case CONTROL_MSG_TYPE_GET_CLIPBOARD:
......
...@@ -64,6 +64,10 @@ struct control_msg { ...@@ -64,6 +64,10 @@ struct control_msg {
int32_t hscroll; int32_t hscroll;
int32_t vscroll; int32_t vscroll;
} inject_scroll_event; } inject_scroll_event;
struct {
enum android_keyevent_action action; // action for the BACK key
// screen may only be turned on on ACTION_DOWN
} back_or_screen_on;
struct { struct {
char *text; // owned, to be freed by free() char *text; // owned, to be freed by free()
bool paste; bool paste;
......
...@@ -146,13 +146,25 @@ action_cut(struct controller *controller, int actions) { ...@@ -146,13 +146,25 @@ action_cut(struct controller *controller, int actions) {
} }
// turn the screen on if it was off, press BACK otherwise // turn the screen on if it was off, press BACK otherwise
// If the screen is off, it is turned on only on ACTION_DOWN
static void static void
press_back_or_turn_screen_on(struct controller *controller) { press_back_or_turn_screen_on(struct controller *controller, int actions) {
struct control_msg msg; struct control_msg msg;
msg.type = CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON; msg.type = CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON;
if (!controller_push_msg(controller, &msg)) { if (actions & ACTION_DOWN) {
LOGW("Could not request 'press back or turn screen on'"); msg.back_or_screen_on.action = AKEY_EVENT_ACTION_DOWN;
if (!controller_push_msg(controller, &msg)) {
LOGW("Could not request 'press back or turn screen on'");
return;
}
}
if (actions & ACTION_UP) {
msg.back_or_screen_on.action = AKEY_EVENT_ACTION_UP;
if (!controller_push_msg(controller, &msg)) {
LOGW("Could not request 'press back or turn screen on'");
}
} }
} }
...@@ -650,9 +662,7 @@ input_manager_process_mouse_button(struct input_manager *im, ...@@ -650,9 +662,7 @@ input_manager_process_mouse_button(struct input_manager *im,
int action = down ? ACTION_DOWN : ACTION_UP; int action = down ? ACTION_DOWN : ACTION_UP;
if (control && event->button == SDL_BUTTON_RIGHT) { if (control && event->button == SDL_BUTTON_RIGHT) {
if (down) { press_back_or_turn_screen_on(im->controller, action);
press_back_or_turn_screen_on(im->controller);
}
return; return;
} }
if (control && event->button == SDL_BUTTON_MIDDLE) { if (control && event->button == SDL_BUTTON_MIDDLE) {
......
...@@ -146,14 +146,18 @@ static void test_serialize_inject_scroll_event(void) { ...@@ -146,14 +146,18 @@ static void test_serialize_inject_scroll_event(void) {
static void test_serialize_back_or_screen_on(void) { static void test_serialize_back_or_screen_on(void) {
struct control_msg msg = { struct control_msg msg = {
.type = CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON, .type = CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON,
.back_or_screen_on = {
.action = AKEY_EVENT_ACTION_UP,
},
}; };
unsigned char buf[CONTROL_MSG_MAX_SIZE]; unsigned char buf[CONTROL_MSG_MAX_SIZE];
size_t size = control_msg_serialize(&msg, buf); size_t size = control_msg_serialize(&msg, buf);
assert(size == 1); assert(size == 2);
const unsigned char expected[] = { const unsigned char expected[] = {
CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON, CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON,
0x01, // AKEY_EVENT_ACTION_UP
}; };
assert(!memcmp(buf, expected, sizeof(expected))); assert(!memcmp(buf, expected, sizeof(expected)));
} }
......
...@@ -71,6 +71,13 @@ public final class ControlMessage { ...@@ -71,6 +71,13 @@ public final class ControlMessage {
return msg; return msg;
} }
public static ControlMessage createBackOrScreenOn(int action) {
ControlMessage msg = new ControlMessage();
msg.type = TYPE_BACK_OR_SCREEN_ON;
msg.action = action;
return msg;
}
public static ControlMessage createSetClipboard(String text, boolean paste) { public static ControlMessage createSetClipboard(String text, boolean paste) {
ControlMessage msg = new ControlMessage(); ControlMessage msg = new ControlMessage();
msg.type = TYPE_SET_CLIPBOARD; msg.type = TYPE_SET_CLIPBOARD;
......
...@@ -11,6 +11,7 @@ public class ControlMessageReader { ...@@ -11,6 +11,7 @@ public class ControlMessageReader {
static final int INJECT_KEYCODE_PAYLOAD_LENGTH = 13; static final int INJECT_KEYCODE_PAYLOAD_LENGTH = 13;
static final int INJECT_TOUCH_EVENT_PAYLOAD_LENGTH = 27; static final int INJECT_TOUCH_EVENT_PAYLOAD_LENGTH = 27;
static final int INJECT_SCROLL_EVENT_PAYLOAD_LENGTH = 20; static final int INJECT_SCROLL_EVENT_PAYLOAD_LENGTH = 20;
static final int BACK_OR_SCREEN_ON_LENGTH = 1;
static final int SET_SCREEN_POWER_MODE_PAYLOAD_LENGTH = 1; static final int SET_SCREEN_POWER_MODE_PAYLOAD_LENGTH = 1;
static final int SET_CLIPBOARD_FIXED_PAYLOAD_LENGTH = 1; static final int SET_CLIPBOARD_FIXED_PAYLOAD_LENGTH = 1;
...@@ -66,13 +67,15 @@ public class ControlMessageReader { ...@@ -66,13 +67,15 @@ public class ControlMessageReader {
case ControlMessage.TYPE_INJECT_SCROLL_EVENT: case ControlMessage.TYPE_INJECT_SCROLL_EVENT:
msg = parseInjectScrollEvent(); msg = parseInjectScrollEvent();
break; break;
case ControlMessage.TYPE_BACK_OR_SCREEN_ON:
msg = parseBackOrScreenOnEvent();
break;
case ControlMessage.TYPE_SET_CLIPBOARD: case ControlMessage.TYPE_SET_CLIPBOARD:
msg = parseSetClipboard(); msg = parseSetClipboard();
break; break;
case ControlMessage.TYPE_SET_SCREEN_POWER_MODE: case ControlMessage.TYPE_SET_SCREEN_POWER_MODE:
msg = parseSetScreenPowerMode(); msg = parseSetScreenPowerMode();
break; break;
case ControlMessage.TYPE_BACK_OR_SCREEN_ON:
case ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL: case ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL:
case ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL: case ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL:
case ControlMessage.TYPE_GET_CLIPBOARD: case ControlMessage.TYPE_GET_CLIPBOARD:
...@@ -150,6 +153,14 @@ public class ControlMessageReader { ...@@ -150,6 +153,14 @@ public class ControlMessageReader {
return ControlMessage.createInjectScrollEvent(position, hScroll, vScroll); return ControlMessage.createInjectScrollEvent(position, hScroll, vScroll);
} }
private ControlMessage parseBackOrScreenOnEvent() {
if (buffer.remaining() < BACK_OR_SCREEN_ON_LENGTH) {
return null;
}
int action = toUnsigned(buffer.get());
return ControlMessage.createBackOrScreenOn(action);
}
private ControlMessage parseSetClipboard() { private ControlMessage parseSetClipboard() {
if (buffer.remaining() < SET_CLIPBOARD_FIXED_PAYLOAD_LENGTH) { if (buffer.remaining() < SET_CLIPBOARD_FIXED_PAYLOAD_LENGTH) {
return null; return null;
......
...@@ -101,7 +101,7 @@ public class Controller { ...@@ -101,7 +101,7 @@ public class Controller {
break; break;
case ControlMessage.TYPE_BACK_OR_SCREEN_ON: case ControlMessage.TYPE_BACK_OR_SCREEN_ON:
if (device.supportsInputEvents()) { if (device.supportsInputEvents()) {
pressBackOrTurnScreenOn(); pressBackOrTurnScreenOn(msg.getAction());
} }
break; break;
case ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL: case ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL:
...@@ -255,12 +255,22 @@ public class Controller { ...@@ -255,12 +255,22 @@ public class Controller {
}, 200, TimeUnit.MILLISECONDS); }, 200, TimeUnit.MILLISECONDS);
} }
private boolean pressBackOrTurnScreenOn() { private boolean pressBackOrTurnScreenOn(int action) {
int keycode = Device.isScreenOn() ? KeyEvent.KEYCODE_BACK : KeyEvent.KEYCODE_POWER; if (Device.isScreenOn()) {
if (keepPowerModeOff && keycode == KeyEvent.KEYCODE_POWER) { return device.injectKeyEvent(action, KeyEvent.KEYCODE_BACK, 0, 0);
}
// Screen is off
// Only press POWER on ACTION_DOWN
if (action != KeyEvent.ACTION_DOWN) {
// do nothing,
return true;
}
if (keepPowerModeOff) {
schedulePowerModeOff(); schedulePowerModeOff();
} }
return device.injectKeycode(keycode); return device.injectKeycode(KeyEvent.KEYCODE_POWER);
} }
private boolean setClipboard(String text, boolean paste) { private boolean setClipboard(String text, boolean paste) {
......
...@@ -154,6 +154,7 @@ public class ControlMessageReaderTest { ...@@ -154,6 +154,7 @@ public class ControlMessageReaderTest {
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos); DataOutputStream dos = new DataOutputStream(bos);
dos.writeByte(ControlMessage.TYPE_BACK_OR_SCREEN_ON); dos.writeByte(ControlMessage.TYPE_BACK_OR_SCREEN_ON);
dos.writeByte(KeyEvent.ACTION_UP);
byte[] packet = bos.toByteArray(); byte[] packet = bos.toByteArray();
...@@ -161,6 +162,7 @@ public class ControlMessageReaderTest { ...@@ -161,6 +162,7 @@ public class ControlMessageReaderTest {
ControlMessage event = reader.next(); ControlMessage event = reader.next();
Assert.assertEquals(ControlMessage.TYPE_BACK_OR_SCREEN_ON, event.getType()); Assert.assertEquals(ControlMessage.TYPE_BACK_OR_SCREEN_ON, event.getType());
Assert.assertEquals(KeyEvent.ACTION_DOWN, event.getAction());
} }
@Test @Test
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册