123 lines
3.3 KiB
Python
Executable File
123 lines
3.3 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# Copyright 2016 The Chromium Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
"""Use your keyboard as your phone's keyboard. Experimental."""
|
|
|
|
import argparse
|
|
import copy
|
|
import os
|
|
import sys
|
|
import termios
|
|
import tty
|
|
|
|
if __name__ == '__main__':
|
|
sys.path.append(
|
|
os.path.abspath(
|
|
os.path.join(os.path.dirname(__file__), '..', '..', '..')))
|
|
from devil import base_error
|
|
from devil.android.sdk import keyevent
|
|
from devil.android.tools import script_common
|
|
from devil.utils import logging_common
|
|
|
|
_KEY_MAPPING = {
|
|
'\x08': keyevent.KEYCODE_DEL,
|
|
'\x0a': keyevent.KEYCODE_ENTER,
|
|
' ': keyevent.KEYCODE_SPACE,
|
|
'.': keyevent.KEYCODE_PERIOD,
|
|
'0': keyevent.KEYCODE_0,
|
|
'1': keyevent.KEYCODE_1,
|
|
'2': keyevent.KEYCODE_2,
|
|
'3': keyevent.KEYCODE_3,
|
|
'4': keyevent.KEYCODE_4,
|
|
'5': keyevent.KEYCODE_5,
|
|
'6': keyevent.KEYCODE_6,
|
|
'7': keyevent.KEYCODE_7,
|
|
'8': keyevent.KEYCODE_8,
|
|
'9': keyevent.KEYCODE_9,
|
|
'a': keyevent.KEYCODE_A,
|
|
'b': keyevent.KEYCODE_B,
|
|
'c': keyevent.KEYCODE_C,
|
|
'd': keyevent.KEYCODE_D,
|
|
'e': keyevent.KEYCODE_E,
|
|
'f': keyevent.KEYCODE_F,
|
|
'g': keyevent.KEYCODE_G,
|
|
'h': keyevent.KEYCODE_H,
|
|
'i': keyevent.KEYCODE_I,
|
|
'j': keyevent.KEYCODE_J,
|
|
'k': keyevent.KEYCODE_K,
|
|
'l': keyevent.KEYCODE_L,
|
|
'm': keyevent.KEYCODE_M,
|
|
'n': keyevent.KEYCODE_N,
|
|
'o': keyevent.KEYCODE_O,
|
|
'p': keyevent.KEYCODE_P,
|
|
'q': keyevent.KEYCODE_Q,
|
|
'r': keyevent.KEYCODE_R,
|
|
's': keyevent.KEYCODE_S,
|
|
't': keyevent.KEYCODE_T,
|
|
'u': keyevent.KEYCODE_U,
|
|
'v': keyevent.KEYCODE_V,
|
|
'w': keyevent.KEYCODE_W,
|
|
'x': keyevent.KEYCODE_X,
|
|
'y': keyevent.KEYCODE_Y,
|
|
'z': keyevent.KEYCODE_Z,
|
|
'\x7f': keyevent.KEYCODE_DEL,
|
|
}
|
|
|
|
|
|
def Keyboard(device, stream_itr):
|
|
try:
|
|
for c in stream_itr:
|
|
k = _KEY_MAPPING.get(c)
|
|
if k:
|
|
device.SendKeyEvent(k)
|
|
else:
|
|
print
|
|
print '(No mapping for character 0x%x)' % ord(c)
|
|
except KeyboardInterrupt:
|
|
pass
|
|
|
|
|
|
class MultipleDevicesError(base_error.BaseError):
|
|
def __init__(self, devices):
|
|
super(MultipleDevicesError, self).__init__(
|
|
'More than one device found: %s' % ', '.join(str(d) for d in devices))
|
|
|
|
|
|
def main(raw_args):
|
|
parser = argparse.ArgumentParser(
|
|
description="Use your keyboard as your phone's keyboard.")
|
|
logging_common.AddLoggingArguments(parser)
|
|
script_common.AddDeviceArguments(parser)
|
|
args = parser.parse_args(raw_args)
|
|
|
|
logging_common.InitializeLogging(args)
|
|
|
|
devices = script_common.GetDevices(args.devices, None)
|
|
if len(devices) > 1:
|
|
raise MultipleDevicesError(devices)
|
|
|
|
def next_char():
|
|
while True:
|
|
yield sys.stdin.read(1)
|
|
|
|
try:
|
|
fd = sys.stdin.fileno()
|
|
|
|
# See man 3 termios for more info on what this is doing.
|
|
old_attrs = termios.tcgetattr(fd)
|
|
new_attrs = copy.deepcopy(old_attrs)
|
|
new_attrs[tty.LFLAG] = new_attrs[tty.LFLAG] & ~(termios.ICANON)
|
|
new_attrs[tty.CC][tty.VMIN] = 1
|
|
new_attrs[tty.CC][tty.VTIME] = 0
|
|
termios.tcsetattr(fd, termios.TCSAFLUSH, new_attrs)
|
|
|
|
Keyboard(devices[0], next_char())
|
|
finally:
|
|
termios.tcsetattr(fd, termios.TCSAFLUSH, old_attrs)
|
|
return 0
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main(sys.argv[1:]))
|