blob: 31daf59edbf58b746fc93b77c341ef88310627e6 [file] [log] [blame]
#!/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 run_tests_helper
_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
def AddArguments(parser):
parser.add_argument('-d', '--device', action='append', dest='devices',
metavar='DEVICE', help='device serial')
parser.add_argument('-v', '--verbose', action='count', help='print more')
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.")
AddArguments(parser)
args = parser.parse_args(raw_args)
run_tests_helper.SetLogLevel(args.verbose)
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:]))