Home PC Games Linux Windows Database Network Programming Server Mobile  
           
  Home \ Programming \ WEB-based Android Remote Tools Python implementation     - CentOS 6.6 installation certification system based on the ftp service (Server)

- RAID configuration and management under linux (Server)

- Construction Spark source and application development environment (Server)

- linux server security (Linux)

- Hadoop namenode do NFS disaster recovery (Server)

- JavaScript, some conclusions about the implicit conversion (Programming)

- Implement Oracle dynamic registration of non-standard port 1521 (Database)

- Django how to generate content in non-HTML formats (Programming)

- How to manage the time and date at systemd Linux systems (Linux)

- Apache Spark1.1.0 deployment and development environment to build (Server)

- Production Environment MongoDB Fragmentation and Cluster Solution (Database)

- Oracle Bug caused by the collection of AWR Snapshot fault (Database)

- How common Linux automation tasks (Server)

- Modify grub solve computer startup error: ERROR 17 (Linux)

- Linux LVM space expansion Demo (Linux)

- Nginx version of helloworld (Server)

- Vi / Vim prompt solutions do not have permission to save time (Linux)

- Spring + MyBatis Multi data source switching (Database)

- Virtual Judge structures under Ubuntu 14.04 (Server)

- NGINX Plus now fully supports HTTP / 2 (Server)

 
         
  WEB-based Android Remote Tools Python implementation
     
  Add Date : 2017-06-05      
         
         
         
  ADB Android Remote Tools Python-based implementation, this tool is original, involving knowledge:

- Python Programming
- Tkinter GUI Programming
- ADB communication mechanism

Code full:

#! / Usr / bin / env python
# - * - Coding: utf-8 - * -
# Function:
# Screen cast via adb daemon, without java env.
# Usage:
# Arobot.py [-option]
# Example:
# Arobot.py
# Arobot.py -lcd
# Arobot.py -keypad

import subprocess, os
import threading
import socket, sys
import time

try:
    import Tkinter as tk
    import ttk
    from PIL import Image, ImageTk, ImageDraw
except:
    print 'Following module is needed:'
    print '- Tkinter: sudo apt-get install python-tk'
    print '- PIL: sudo apt-get install python-imaging-tk'
    sys.exit ()

# Set DEBUG to True if you need know more running message
DEBUG = False

# Set USE_TTK to False if you need classic Tk / Tcl GUI-style
USE_TTK = True

'' '
Key value definition refer from KeyEvent.java
public class KeyEvent extends InputEvent implements Parcelable {
    / ** Key code constant: Unknown key code * /.
    public static final int KEYCODE_UNKNOWN = 0;
    public static final int KEYCODE_SOFT_LEFT = 1;
    public static final int KEYCODE_SOFT_RIGHT = 2;
    public static final int KEYCODE_HOME = 3;
    public static final int KEYCODE_BACK = 4;
    public static final int KEYCODE_CALL = 5;
    public static final int KEYCODE_ENDCALL = 6;
    public static final int KEYCODE_0 = 7;
    public static final int KEYCODE_1 = 8;
    public static final int KEYCODE_2 = 9;
    public static final int KEYCODE_3 = 10;
    public static final int KEYCODE_4 = 11;
    public static final int KEYCODE_5 = 12;
    public static final int KEYCODE_6 = 13;
    public static final int KEYCODE_7 = 14;
    public static final int KEYCODE_8 = 15;
    public static final int KEYCODE_9 = 16;
    public static final int KEYCODE_STAR = 17;
    public static final int KEYCODE_POUND = 18;
    public static final int KEYCODE_DPAD_UP = 19;
    public static final int KEYCODE_DPAD_DOWN = 20;
    public static final int KEYCODE_DPAD_LEFT = 21;
    public static final int KEYCODE_DPAD_RIGHT = 22;
    public static final int KEYCODE_DPAD_CENTER = 23;
    public static final int KEYCODE_VOLUME_UP = 24;
    public static final int KEYCODE_VOLUME_DOWN = 25;
    public static final int KEYCODE_POWER = 26;
    public static final int KEYCODE_CAMERA = 27;
    public static final int KEYCODE_CLEAR = 28;
    public static final int KEYCODE_A = 29;
    public static final int KEYCODE_B = 30;
    public static final int KEYCODE_C = 31;
    public static final int KEYCODE_D = 32;
    public static final int KEYCODE_E = 33;
    public static final int KEYCODE_F = 34;
    public static final int KEYCODE_G = 35;
    public static final int KEYCODE_H = 36;
    public static final int KEYCODE_I = 37;
    public static final int KEYCODE_J = 38;
    public static final int KEYCODE_K = 39;
    public static final int KEYCODE_L = 40;
    public static final int KEYCODE_M = 41;
    public static final int KEYCODE_N = 42;
    public static final int KEYCODE_O = 43;
    public static final int KEYCODE_P = 44;
    public static final int KEYCODE_Q = 45;
    public static final int KEYCODE_R = 46;
    public static final int KEYCODE_S = 47;
    public static final int KEYCODE_T = 48;
    public static final int KEYCODE_U = 49;
    public static final int KEYCODE_V = 50;
    public static final int KEYCODE_W = 51;
    public static final int KEYCODE_X = 52;
    public static final int KEYCODE_Y = 53;
    public static final int KEYCODE_Z = 54;
    public static final int KEYCODE_COMMA = 55;
    public static final int KEYCODE_PERIOD = 56;
    public static final int KEYCODE_ALT_LEFT = 57;
    public static final int KEYCODE_ALT_RIGHT = 58;
    public static final int KEYCODE_SHIFT_LEFT = 59;
    public static final int KEYCODE_SHIFT_RIGHT = 60;
    public static final int KEYCODE_TAB = 61;
    public static final int KEYCODE_SPACE = 62;
    public static final int KEYCODE_SYM = 63;
    public static final int KEYCODE_EXPLORER = 64;
    public static final int KEYCODE_ENVELOPE = 65;
    public static final int KEYCODE_ENTER = 66;
    public static final int KEYCODE_DEL = 67;
    public static final int KEYCODE_GRAVE = 68;
    public static final int KEYCODE_MINUS = 69;
    public static final int KEYCODE_EQUALS = 70;
    public static final int KEYCODE_LEFT_BRACKET = 71;
    public static final int KEYCODE_RIGHT_BRACKET = 72;
    public static final int KEYCODE_BACKSLASH = 73;
    public static final int KEYCODE_SEMICOLON = 74;
    public static final int KEYCODE_APOSTROPHE = 75;
    public static final int KEYCODE_SLASH = 76;
    public static final int KEYCODE_AT = 77;
    public static final int KEYCODE_NUM = 78;
    public static final int KEYCODE_HEADSETHOOK = 79;
    public static final int KEYCODE_FOCUS = 80;
    public static final int KEYCODE_PLUS = 81;
    public static final int KEYCODE_MENU = 82;
    public static final int KEYCODE_NOTIFICATION = 83;
    public static final int KEYCODE_SEARCH = 84;
    public static final int KEYCODE_MEDIA_PLAY_PAUSE = 85;
    public static final int KEYCODE_MEDIA_STOP = 86;
    public static final int KEYCODE_MEDIA_NEXT = 87;
    public static final int KEYCODE_MEDIA_PREVIOUS = 88;
    public static final int KEYCODE_MEDIA_REWIND = 89;
    public static final int KEYCODE_MEDIA_FAST_FORWARD = 90;
    public static final int KEYCODE_MUTE = 91;
    public static final int KEYCODE_PAGE_UP = 92;
    public static final int KEYCODE_PAGE_DOWN = 93;
    public static final int KEYCODE_PICTSYMBOLS = 94;
    public static final int KEYCODE_SWITCH_CHARSET = 95;
    public static final int KEYCODE_BUTTON_A = 96;
    public static final int KEYCODE_BUTTON_B = 97;
    public static final int KEYCODE_BUTTON_C = 98;
    public static final int KEYCODE_BUTTON_X = 99;
    public static final int KEYCODE_BUTTON_Y = 100;
    public static final int KEYCODE_BUTTON_Z = 101;
    public static final int KEYCODE_BUTTON_L1 = 102;
    public static final int KEYCODE_BUTTON_R1 = 103;
    public static final int KEYCODE_BUTTON_L2 = 104;
    public static final int KEYCODE_BUTTON_R2 = 105;
    public static final int KEYCODE_BUTTON_THUMBL = 106;
    public static final int KEYCODE_BUTTON_THUMBR = 107;
    public static final int KEYCODE_BUTTON_START = 108;
    public static final int KEYCODE_BUTTON_SELECT = 109;
    public static final int KEYCODE_BUTTON_MODE = 110;
    public static final int KEYCODE_ESCAPE = 111;
    public static final int KEYCODE_FORWARD_DEL = 112;
    public static final int KEYCODE_CTRL_LEFT = 113;
    public static final int KEYCODE_CTRL_RIGHT = 114;
    public static final int KEYCODE_CAPS_LOCK = 115;
    public static final int KEYCODE_SCROLL_LOCK = 116;
    public static final int KEYCODE_META_LEFT = 117;
    public static final int KEYCODE_META_RIGHT = 118;
    public static final int KEYCODE_FUNCTION = 119;
    public static final int KEYCODE_SYSRQ = 120;
    public static final int KEYCODE_BREAK = 121;
    public static final int KEYCODE_MOVE_HOME = 122;
    public static final int KEYCODE_MOVE_END = 123;
    public static final int KEYCODE_INSERT = 124;
    public static final int KEYCODE_FORWARD = 125;
    public static final int KEYCODE_MEDIA_PLAY = 126;
    public static final int KEYCODE_MEDIA_PAUSE = 127;
    public static final int KEYCODE_MEDIA_CLOSE = 128;
    public static final int KEYCODE_MEDIA_EJECT = 129;
    public static final int KEYCODE_MEDIA_RECORD = 130;
    public static final int KEYCODE_F1 = 131;
    public static final int KEYCODE_F2 = 132;
    public static final int KEYCODE_F3 = 133;
    public static final int KEYCODE_F4 = 134;
    public static final int KEYCODE_F5 = 135;
    public static final int KEYCODE_F6 = 136;
    public static final int KEYCODE_F7 = 137;
    public static final int KEYCODE_F8 = 138;
    public static final int KEYCODE_F9 = 139;
    public static final int KEYCODE_F10 = 140;
    public static final int KEYCODE_F11 = 141;
    public static final int KEYCODE_F12 = 142;
    public static final int KEYCODE_NUM_LOCK = 143;
    public static final int KEYCODE_NUMPAD_0 = 144;
    public static final int KEYCODE_NUMPAD_1 = 145;
    public static final int KEYCODE_NUMPAD_2 = 146;
    public static final int KEYCODE_NUMPAD_3 = 147;
    public static final int KEYCODE_NUMPAD_4 = 148;
    public static final int KEYCODE_NUMPAD_5 = 149;
    public static final int KEYCODE_NUMPAD_6 = 150;
    public static final int KEYCODE_NUMPAD_7 = 151;
    public static final int KEYCODE_NUMPAD_8 = 152;
    public static final int KEYCODE_NUMPAD_9 = 153;
    public static final int KEYCODE_NUMPAD_DIVIDE = 154;
    public static final int KEYCODE_NUMPAD_MULTIPLY = 155;
    public static final int KEYCODE_NUMPAD_SUBTRACT = 156;
    public static final int KEYCODE_NUMPAD_ADD = 157;
    public static final int KEYCODE_NUMPAD_DOT = 158;
    public static final int KEYCODE_NUMPAD_COMMA = 159;
    public static final int KEYCODE_NUMPAD_ENTER = 160;
    public static final int KEYCODE_NUMPAD_EQUALS = 161;
    public static final int KEYCODE_NUMPAD_LEFT_PAREN = 162;
    public static final int KEYCODE_NUMPAD_RIGHT_PAREN = 163;
    public static final int KEYCODE_VOLUME_MUTE = 164;
    public static final int KEYCODE_INFO = 165;
    public static final int KEYCODE_CHANNEL_UP = 166;
    public static final int KEYCODE_CHANNEL_DOWN = 167;
    public static final int KEYCODE_ZOOM_IN = 168;
    public static final int KEYCODE_ZOOM_OUT = 169;
    public static final int KEYCODE_TV = 170;
    public static final int KEYCODE_WINDOW = 171;
    public static final int KEYCODE_GUIDE = 172;
    public static final int KEYCODE_DVR = 173;
    public static final int KEYCODE_BOOKMARK = 174;
    public static final int KEYCODE_CAPTIONS = 175;
    public static final int KEYCODE_SETTINGS = 176;
    public static final int KEYCODE_TV_POWER = 177;
    public static final int KEYCODE_TV_INPUT = 178;
    public static final int KEYCODE_STB_POWER = 179;
    public static final int KEYCODE_STB_INPUT = 180;
    public static final int KEYCODE_AVR_POWER = 181;
    public static final int KEYCODE_AVR_INPUT = 182;
    public static final int KEYCODE_PROG_RED = 183;
    public static final int KEYCODE_PROG_GREEN = 184;
    public static final int KEYCODE_PROG_YELLOW = 185;
    public static final int KEYCODE_PROG_BLUE = 186;
    public static final int KEYCODE_APP_SWITCH = 187;
    public static final int KEYCODE_BUTTON_1 = 188;
    public static final int KEYCODE_BUTTON_2 = 189;
    public static final int KEYCODE_BUTTON_3 = 190;
    public static final int KEYCODE_BUTTON_4 = 191;
    public static final int KEYCODE_BUTTON_5 = 192;
    public static final int KEYCODE_BUTTON_6 = 193;
    public static final int KEYCODE_BUTTON_7 = 194;
    public static final int KEYCODE_BUTTON_8 = 195;
    public static final int KEYCODE_BUTTON_9 = 196;
    public static final int KEYCODE_BUTTON_10 = 197;
    public static final int KEYCODE_BUTTON_11 = 198;
    public static final int KEYCODE_BUTTON_12 = 199;
    public static final int KEYCODE_BUTTON_13 = 200;
    public static final int KEYCODE_BUTTON_14 = 201;
    public static final int KEYCODE_BUTTON_15 = 202;
    public static final int KEYCODE_BUTTON_16 = 203;
    public static final int KEYCODE_LANGUAGE_SWITCH = 204;
    public static final int KEYCODE_MANNER_MODE = 205;
    public static final int KEYCODE_3D_MODE = 206;
    public static final int KEYCODE_CONTACTS = 207;
    public static final int KEYCODE_CALENDAR = 208;
    public static final int KEYCODE_MUSIC = 209;
    public static final int KEYCODE_CALCULATOR = 210;
    public static final int KEYCODE_ZENKAKU_HANKAKU = 211;
    public static final int KEYCODE_EISU = 212;
    public static final int KEYCODE_MUHENKAN = 213;
    public static final int KEYCODE_HENKAN = 214;
    public static final int KEYCODE_KATAKANA_HIRAGANA = 215;
    public static final int KEYCODE_YEN = 216;
    public static final int KEYCODE_RO = 217;
    public static final int KEYCODE_KANA = 218;
    public static final int KEYCODE_ASSIST = 219;
    private static final int LAST_KEYCODE = KEYCODE_ASSIST;

    private static final int KEYCODE_TEST_BASE = 220;
    public static final int KEYCODE_POWER_TEST = KEYCODE_TEST_BASE + 1;
    public static final int KEYCODE_HOME_TEST = KEYCODE_TEST_BASE + 2;
    public static final int KEYCODE_BACK_TEST = KEYCODE_TEST_BASE + 3;
    public static final int KEYCODE_MENU_TEST = KEYCODE_TEST_BASE + 4;
    public static final int KEYCODE_SEARCH_TEST = KEYCODE_TEST_BASE + 5;
    public static final int KEYCODE_CALL_TEST = KEYCODE_TEST_BASE + 6;
    public static final int KEYCODE_ENDCALL_TEST = KEYCODE_TEST_BASE + 7;
    public static final int KEYCODE_VOLUME_UP_TEST = KEYCODE_TEST_BASE + 8;
    public static final int KEYCODE_VOLUME_DOWN_TEST = KEYCODE_TEST_BASE + 9;
    public static final int KEYCODE_CAMERA_TEST = KEYCODE_TEST_BASE + 10;
    public static final int KEYCODE_SPACE_TEST = KEYCODE_TEST_BASE + 11;
    public static final int KEYCODE_FUNCTION_TEST = KEYCODE_TEST_BASE + 12;
'' '
# Keynames is the key name list
# 'None': no keys in this grid
keynames = [ 'home', 'menu', 'back', 'srch',
            'Call', '^', 'end', 'none',
              '< ', 'Ok', '>', 'vol +',
            'None', 'v', 'none', 'vol-',
              '1', '2', '3', 'none',
              '4', '5', '6', 'cam',
              '7', '8', '9', 'enter',
              '*', '0', '#'
            ]

# Keyvalues is the key value list map with the keynames
# 0: no keys here
keyvalues = [3, 82, 4, 84,
              5, 19, 6, 0,
              21,23,22, 24,
              0, 20, 0, 25,
              8, 9, 10, 0,
              11, 12, 27,
              15, 16, 66,
              17, 7, 18
            ]

# Print Hex Buffer
def hexdump (buf = None):
    if buf = None!:
        pstr = ''
        cnt = 0
        for x in buf:
            if (cnt + 1)% 8 == 0:
                pstr = '% s% 02X \ n'% (pstr, x)
            else:
                pstr = '% s% 02X'% (pstr, x)
            cnt = cnt + 1
        print pstr

# Read adb response, if 'OKAY' turn true
def readAdbResponse (s):
    if s = None!:
        resp = s.recv (4)
        if DEBUG:
            print 'resp:% s'% repr (resp)

    ! If len (resp) = 4:
        print 'protocol fault (no status)'
        return False
    
    if resp == 'OKAY':
        return True
    elif resp == 'FAIL':
        resp = s.recv (4)
        if len (resp) < 4:
            print 'protocol fault (status len)'
            return False
        else:
            length = int (resp, 16)
            resp = s.recv (length)
            ! If len (resp) = length:
                print 'protocol fault (status read)'
                return False
            else:
                print resp
                return False
    else:
        print "protocol fault (status% 02x% 02x% 02x% 02x ?!)", (resp [0], resp [1], resp [2], resp [3])
        return False

    return False

# Send adb shell command
def adbshellcommand (cmd):
    reply = None
    s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)

    # Waiting adb server start
    while True:
        try:
            s.connect (( '127.0.0.1', 5037))
        except:
            os.system ( 'adb start-server')
            time.sleep (2)
            continue
        else:
            break

    req_msg = 'host: transport-any'
    s.sendall ( '% 04x'% len (req_msg))
    s.sendall (req_msg)
    if not readAdbResponse (s):
        return None

    req_msg = 'shell:% s'% cmd
    if DEBUG:
        print '% s'% req_msg
    s.sendall ( '% 04x'% len (req_msg))
    s.sendall (req_msg)
    if readAdbResponse (s):
        reply = s.recv (4096)
        if DEBUG:
            hexdump (bytearray (reply))
    s.close ()
    
    return reply

# Convert buffer to Int
def getInt (tbuf = None):
    if (tbuf = None!):
        if DEBUG:
            hexdump (bytearray (tbuf))
        if len (tbuf) < 4:
            print 'buff len < 4'
            return 0
        else:
            if DEBUG:
                print 'parse:% 02x% 02x% 02x% 02x'% (tbuf [0], tbuf [1], tbuf [2], tbuf [3])
            intnum = tbuf [0]
            intnum = intnum + tbuf [1] * 0x100
            intnum = intnum + tbuf [2] * 0x10000
            intnum = intnum + tbuf [3] * 0x1000000
            if DEBUG:
                print 'INT:% 08x'% intnum
            return intnum
    else:
        return 0

# Parse fb header from buffer
def readHeader (tfb, ver, buf):
    if DEBUG:
        print 'readHeader: ver =% d'% ver
    if ver == 16:
        tfb.fb_bpp = 16
        tfb.fb_size = getInt (buf [0: 4])
        tfb.fb_width = getInt (buf [4: 8])
        tfb.fb_height = getInt (buf [8:12])
        tfb.red_offset = 11
        tfb.red_length = 5
        tfb.blue_offset = 5
        tfb.blue_length = 6
        tfb.green_offset = 0
        tfb.green_length = 5
        tfb.alpha_offset = 0
        tfb.alpha_length = 0
    elif ver == 1:
        tfb.fb_bpp = getInt (bytearray (buf [0: 4]))
        tfb.fb_size = getInt (bytearray (buf [4: 8]))
        tfb.fb_width = getInt (bytearray (buf [8:12]))
        tfb.fb_height = getInt (bytearray (buf [12:16]))
        tfb.red_offset = getInt (bytearray (buf [16:20]))
        tfb.red_length = getInt (bytearray (buf [20:24]))
        tfb.blue_offset = getInt (bytearray (buf [24:28]))
        tfb.blue_length = getInt (bytearray (buf [28:32]))
        tfb.green_offset = getInt (bytearray (buf [32:36]))
        tfb.green_length = getInt (bytearray (buf [36:40]))
        tfb.alpha_offset = getInt (bytearray (buf [40:44]))
        tfb.alpha_length = getInt (bytearray (buf [44:48]))
    else:
        return False
    return True

# Find the Touch input device and event
def get_touch_event ():
    tp_names = [ 'ft5x06', 'gt818']
    output = adbshellcommand ( 'getevent -S')
    if output == None:
        return None

    if DEBUG:
        print output
    dev = ''
    name = ''
    for line in output.splitlines ():
        if '/ dev / input / event' in line:
            line = line.split ( ':')
            if len (line) == 2:
                line = line [1]
                line = line.strip ( '')
                line = line.strip ( ' "')
                dev = line
        elif 'name:' in line:
            line = line.split ( ':')
            if len (line) == 2:
                line = line [1]
                line = line.strip ( '')
                line = line.strip ( ' "')
                name = line

        if (dev = ''!) and (name in tp_names):
            break

    if DEBUG:
        print '% s:% s'% (name, dev)

    if name in tp_names:
        return (name, dev)
    else:
        return None

# Do the touch action
def send_touch_event (action, x0, y0, x1 = None, y1 = None):
    # Note: input support tap & swipe after 4.1
    # So we need emulate TP via sendevent if tap or swipe fail
    if action == 'tap':
        resp = adbshellcommand ( 'input tap% d% d'% (x0, y0))
        if 'Error' in resp:
            print 'Not support tap command'

            # Get tp device
            tp = get_touch_event ()

            if tp == None:
                return

            # Down
            cmd_str = ''
            cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 3, 53, x0)
            cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 3, 54, y0)
            cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 3, 57, 0)
            cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 3, 48, 0)
            cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 0, 2, 0)
            cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 1, 330, 1)
            cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 0, 0, 0)

            # Up
            cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 1, 330, 0)
            cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 0, 2, 0)
            cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 0, 0, 0)

            if DEBUG:
                print cmd_str
            adbshellcommand (cmd_str)
    elif action == 'swipe':
        resp = adbshellcommand ( 'input swipe% d% d% d% d'% (x0, y0, x1, y1))
        if 'Error' in resp:
            print 'Not support tap command'
            
            # Get tp device
            tp = get_touch_event ()

            if tp == None:
                return

            step = 3
            stepx = abs (x1 - x0) / step
            stepy = abs (y1 - y0) / step
            x = x0
            y = y0

            for i in range (0, step + 1):
                if x0 < x1:
                    x = x0 + i * stepx
                else:
                    x = x0 - i * stepx

                if y0 < y1:
                    y = y0 + i * stepy
                else:
                    y = y0 - * stepy

                cmd_str = ''
                cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 3, 53, x)
                cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 3, 54, y)
                cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 3, 57, 0)
                cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 3, 48, 0)
                cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 0, 2, 0)
                cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 1, 330, 1)
                cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 0, 0, 0)
                adbshellcommand (cmd_str)

            # Up
            cmd_str = ''
            cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 1, 330, 0)
            cmd_str = cmd_str + 'sendevent% s% d% d% d;'% (tp [1], 0, 2, 0)
            cmd_str = cmd_str + 'sendevent% s% d% d% d'% (tp [1], 0, 0, 0)
            if DEBUG:
                print cmd_str
            adbshellcommand (cmd_str)

# Framebuffer Class
# Only record framebuffer attributs
class fb:
    fb_bpp = 0
    fb_size = 0
    fb_width = 0
    fb_height = 0
    red_offset = 0
    red_length = 0
    blue_offset = 0
    blue_length = 0
    green_offset = 0
    green_length = 0
    alpha_offset = 0
    alpha_length = 0
    fb_data = None

    def __init __ (self):
        fb_bpp = 0
        fb_size = 0
        fb_width = 0
        fb_height = 0
        red_offset = 0
        red_length = 0
        blue_offset = 0
        blue_length = 0
        green_offset = 0
        green_length = 0
        alpha_offset = 0
        alpha_length = 0
        fb_data = None

# Send key thread
class send_key_thread (threading.Thread):
    __tkapp = None
    __root = None
    __key = None
    
    def __init __ (self, key):
        if DEBUG:
            print 'send_key_thread init'
        threading.Thread .__ init __ (self)
        self.thread_stop = False
        self .__ key = key

    def devexist (self):
        p = subprocess.Popen ( "adb devices", shell = True, stdout = subprocess.PIPE)
        p.wait ()
        devList = p.communicate ()
        devList = devList [0] .splitlines ()
        if 'device' in devList [1]:
            if DEBUG:
                print devList [1]
            return True
        else:
            if DEBUG:
                print 'No adb device found'
            return False

    def sendKey (self):
        if DEBUG:
            print 'send_key:% s'% self .__ key
        if self .__ key in keynames:
            if self.devexist ():
                ! If self .__ key = 'none':
                    adbshellcommand ( 'input keyevent% s'% str (keyvalues [keynames.index (self .__ key)]))

    def run (self):
        if DEBUG:
            print 'send_key_thread run'
        self.sendKey ()

    def stop (self):
        if DEBUG:
            print 'stop send_key_thread'
        self.thread_stop = True

# Kaypad Tkinter-Based GUI application
class KeypadApplication (tk.Frame):
    def __init __ (self, master = None):
        if master == None:
            master = tk.Tk ()
        tk.Frame .__ init __ (self, master, class _ = 'KeypadApplication')
        self.createkeypad ()
        self.grid ()

    def createkeypad (self):
        # Creat buttons from keymap with 4 buttons each row
        for btn_name in keynames:
            row_id = keynames.index (btn_name) / 4
            col_id = keynames.index (btn_name)% 4

            ! If btn_name = 'none':
                self.tbutton = tk.Button (self, name = btn_name, text = btn_name)
                self.tbutton [ 'activebackground'] = '#BBBBBB'
                # Self.tbutton [ 'highlightcolor'] = '# BBBB00'
            else:
                self.tbutton = tk.Button (self, name = btn_name, text = '')

            self.tbutton [ 'width'] = 10
            ! If btn_name = 'none':
                self.tbutton.bind ( '< ButtonRelease-1>', self.sendKey)
                self.tbutton.grid (padx = 5, pady = 1, column = col_id, row = row_id)

    def devexist (self):
        p = subprocess.Popen ( "adb devices", shell = True, stdout = subprocess.PIPE)
        p.wait ()
        devList = p.communicate ()
        devList = devList [0] .splitlines ()
        if 'device' in devList [1]:
            if DEBUG:
                print devList [1]
            return True
        else:
            if DEBUG:
                print 'No adb device found'
            return False

    def sendKey (self, event = None):
        if DEBUG:
            print event.widget.winfo_name ()
        keyname = event.widget.winfo_name ()
        if keyname in keynames:
            sender = send_key_thread (keyname)
            sender.start ()

# Kaypad Tkinter-Based GUI application
class ttkKeypadApplication (ttk.Frame):
    def __init __ (self, master = None):
        if master == None:
            master = ttk.Tk ()
        ttk.Frame .__ init __ (self, master, class _ = 'ttkKeypadApplication')
        self.createkeypad ()
        self.grid ()

    def createkeypad (self):
        # Creat buttons from keymap with 4 buttons each row
        for btn_name in keynames:
            row_id = keynames.index (btn_name) / 4
            col_id = keynames.index (btn_name)% 4

            ! If btn_name = 'none':
                self.tbutton = ttk.Button (self, name = btn_name, text = btn_name)
            else:
                self.tbutton = ttk.Button (self, name = btn_name, text = '')

            self.tbutton [ 'width'] = 10
            ! If btn_name = 'none':
                self.tbutton.bind ( '< ButtonRelease-1>', self.sendKey)
                self.tbutton.grid (padx = 5, pady = 1, column = col_id, row = row_id)

    def devexist (self):
        p = subprocess.Popen ( "adb devices", shell = True, stdout = subprocess.PIPE)
        p.wait ()
        devList = p.communicate ()
        devList = devList [0] .splitlines ()
        if 'device' in devList [1]:
            if DEBUG:
                print devList [1]
            return True
        else:
            if DEBUG:
                print 'No adb device found'
            return False

    def sendKey (self, event = None):
        if DEBUG:
            print event.widget.winfo_name ()
        keyname = event.widget.winfo_name ()
        if keyname in keynames:
            sender = send_key_thread (keyname)
            sender.start ()

# LCD Tkinter-Based GUI application
class LcdApplication (tk.Frame):
    __img_factor = 1.00 # image resize rate
    __lcd = None # the label widget
    __keepupdate = True
    __im = None
    __rotate = 0

    # Record mouse start & end point location
    __start = [0, 0]
    __end = [0, 0]

    def __init __ (self, master = None):
        if DEBUG:
            print 'LcdApplication: __init__'
        if master == None:
            master = tk.Tk ()
        tk.Frame .__ init __ (self, master, class _ = 'LcdApplication')
        self .__ rotate = 0
        self.createlcd ()
        self.grid ()

    def createlcd (self):
        # Creat label as lcd
        if DEBUG:
            print 'LcdApplication: createlcd'

        # Make default image display on label
        image = Image.new (mode = 'RGB', size = (240, 320), color = '# 000000')
        draw = ImageDraw.Draw (image)
        draw.text ((80, 100), 'Connecting ...')
        self .__ im = ImageTk.PhotoImage (image)

        # Create label with image option
        self .__ lcd = tk.Label (self, image = self .__ im)
        self .__ lcd.bind ( '< Button-1>', self.click_label)
        self .__ lcd.bind ( '< ButtonRelease-1>', self.click_label)
        self .__ lcd.bind ( '< ButtonRelease-3>', self.rightclick_label)

        # Disply label on frame
        self .__ lcd.grid ()

    # To serve right click on label widget
    def rightclick_label (self, event = None):
        if DEBUG:
            print 'Type:% s'% event.type
        self .__ rotate = (self .__ rotate + 90)% 360
        print "rotate:% d"% self .__ rotate

    # To serve left click on label widget
    def click_label (self, event = None):
        if DEBUG:
            print 'Type:% s'% event.type
        if event.type == '4':
            # Record mouse left button down
            if DEBUG:
                print 'Click at: (% d,% d)'% (event.x, event.y)
            self .__ start [0] = int (float (event.x) / float (self .__ img_factor))
            self .__ start [1] = int (float (event.y) / float (self .__ img_factor))
            self .__ end = None
        elif event.type == '5':
            # Record mouse left button up
            if DEBUG:
                print 'Release at: (% d,% d)'% (event.x, event.y)
            self .__ end = [0, 0]
            self .__ end [0] = int (float (event.x) / float (self .__ img_factor))
            self .__ end [1] = int (float (event.y) / float (self .__ img_factor))

        # Do not report touch event during mouse down
        if self .__ end == None:
            return
        
        if abs (self .__ start [0] - self .__ end [0]) < 2 and \
          abs (self .__ start [1] - self .__ end [1]) < 2:
            # Mouse action: tap
            send_touch_event ( 'tap', self .__ start [0], self .__ start [1])
        else:
            # Mouse action: swipe
            send_touch_event ( 'swipe', self .__ start [0], self .__ start [1], self .__ end [0], self .__ end [1])

    def stop (self):
        if DEBUG:
            print 'LcdApplication: stop'
        self .__ keepupdate = False

    # Screen capture via socket from adb server
    def updatelcd_sock (self):
        if DEBUG:
            print 'LcdApplication: updatelcd_sock'
        # Max display area size on label widget
        #max_lcd_w = 1024
        #max_lcd_h = 600
        max_lcd_w = 1440
        max_lcd_h = 720


        dev_sn = ''
        hdrsize = 0
        myfb = fb ()
        refresh_count = 0 # record refresh count

        while self .__ keepupdate:
            # Get device SerialNumber from ADB server
            s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
            try:
                s.connect (( '127.0.0.1', 5037))
            except:
                os.system ( 'adb start-server')
                time.sleep (2)
                continue

            req_msg = 'host: devices'
            s.sendall ( '% 04x'% len (req_msg))
            s.sendall (req_msg)
            if readAdbResponse (s):
                len_str = s.recv (4)
                if len (len_str) < 4:
                    continue
                length = int (len_str, 16)
                dev_info = s.recv (length)
                if '\ t' in dev_info:
                    dev_sn = dev_info [0: dev_info.index ( '\ t')]
                else:
                    dev_sn = ''
                if DEBUG:
                    print 'dev serial:% s'% dev_sn
            s.recv (1024) # receive all rest data
            s.close ()

            if dev_sn == '':
                continue

            # Get framebuffer from ADB server
            s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
            s.connect (( '127.0.0.1', 5037))
            req_msg = 'host: transport:% s'% dev_sn
            s.sendall ( '% 04x'% len (req_msg))
            s.sendall (req_msg)
            if not readAdbResponse (s):
                s.close ()
            else:
                if DEBUG:
                    print 'ready to transport'
                req_msg = 'framebuffer:'
                s.sendall ( '% 04x'% len (req_msg))
                s.sendall (req_msg)
                if not readAdbResponse (s):
                    s.close ()
                else:
                    reply = s.recv (4)
                    if len (reply) < 4:
                        continue
                    
                    fbver = ord (reply [0]) + \
                            ord (reply [1]) * 0x100 + \
                            ord (reply [2]) * 0x10000 + \
                            ord (reply [3]) * 0x1000000
                    if DEBUG:
                        print 'fbver:% 08x'% fbver

                    # Get fb header size
                    if fbver == 16:
                        hdrsize = 3
                    elif fbver == 1:
                        hdrsize = 12
                    else:
                        hdrsize = 0;
                    if DEBUG:
                        print 'fb header size:% d'% hdrsize

                    # Read the header
                    header = s.recv (hdrsize * 4)
                    if len (header) < (hdrsize * 4):
                        continue

                    if DEBUG:
                        hexdump (bytearray (header))
                    readHeader (myfb, fbver, header)
                    if DEBUG:
                        print 'bpp:% d'% myfb.fb_bpp
                        print 'size:% d'% myfb.fb_size
                        print 'width:% d'% myfb.fb_width
                        print 'height:% d'% myfb.fb_height
                        print 'red_offset:% d'% myfb.red_offset
                        print 'red_length:% d'% myfb.red_length
                        print 'blue_offset:% d'% myfb.blue_offset
                        print 'blue_length:% d'% myfb.blue_length
                        print 'green_offset:% d'% myfb.green_offset
                        print 'green_length:% d'% myfb.green_length
                        print 'alpha_offset:% d'% myfb.alpha_offset
                        print 'alpha_length:% d'% myfb.alpha_length

                    # Read fb buffer
                    rcvcnt = 0
                    readbyte = 0
                    imagebuff = []
                    while True:
                        if (rcvcnt < myfb.fb_size):
                            readbyte = myfb.fb_size - rcvcnt
                        else:
                            break
                        resp = s.recv (readbyte)
                        if DEBUG:
                            print 'read byte:% d'% len (resp)
                        rcvcnt = rcvcnt + len (resp);
                        imagebuff.extend (resp)
                        if len (resp) == 0:
                            break

                    if DEBUG:
                        print 'total rcv byte:% d'% rcvcnt
                    reply = s.recv (10)
                    s.close ()
                    myfb.fb_data = bytearray (imagebuff)

                    if len (imagebuff) < myfb.fb_size:
                        continue

                    # Convert raw-rgb to image
                    image = Image.frombuffer ( 'RGBA',
                                            (Myfb.fb_width, myfb.fb_height),
                                            myfb.fb_data,
                                            'Raw',
                                            'RGBA',
                                            0
                                            1)

                    lcd_w = image.size [0]
                    lcd_h = image.size [1]
                    if DEBUG:
                        print 'LCD size:% d x% d'% (lcd_w, lcd_h)
                    factor_w = 1.00
                    factor_h = 1.00
                    if lcd_w> max_lcd_w:
                        img_w = max_lcd_w
                        factor_w = float (img_w) / float (lcd_w)
                    if lcd_h> max_lcd_h:
                        img_h = max_lcd_h
                        factor_h = float (img_h) / float (lcd_h)
                    factor = min ([factor_w, factor_h])
                    self .__ img_factor = factor

                    # Keep the rate of w: h
                    img_w = int (lcd_w * factor)
                    img_h = int (lcd_h * factor)
                    if DEBUG:
                        print 'Image size:% d x% d'% (img_w, img_h)

                    # Resize image
                    if (factor < 1.00):
                        image = image.resize ((img_w, img_h))

                    # Rotate image
                    if self .__ rotate = 0!:
                        image = image.rotate (self .__ rotate)

                    if self .__ lcd = None!:
                        try:
                            # Save image to local path
                            if DEBUG:
                                refresh_count = refresh_count + 1
                                image_name = 'image_% d.png'% refresh_count
                                image.save (image_name, format = 'PNG')
                            new_image = ImageTk.PhotoImage (image)
                            self .__ im = new_image
                            self .__ lcd [ 'image'] = self .__ im
                        except:
                            continue

# Keypad window thread
class arobot_keys (threading.Thread):
    __tkapp = None
    __root = None
    
    def __init __ (self):
        threading.Thread .__ init __ (self)
        self.thread_stop = False

    def run (self):
        if DEBUG:
            print 'run arobot_keys'
        self .__ root = tk.Tk ()
        if USE_TTK:
            self .__ tkapp = ttkKeypadApplication (master = self .__ root)
        else:
            self .__ tkapp = KeypadApplication (master = self .__ root)
        self .__ tkapp.master.title ( 'ARobot3.0-Keypad')
        self .__ tkapp.grid ()
        self .__ tkapp.mainloop ()
        if DEBUG:
            print 'exit arobot_keys mainloop'

    def stop (self):
        if DEBUG:
            print 'stop arobot_keys'
        if self .__ tkapp = None!:
            self .__ tkapp.quit ()
        self.thread_stop = True

# Screen windows thread
class arobot_lcd (threading.Thread):
    __tkapp = None
    __root = None
    
    def __init __ (self):
        threading.Thread .__ init __ (self)
        self.thread_stop = False

    def run (self):
        if DEBUG:
            print 'run arobot_lcd'
        self .__ root = tk.Tk ()
        self .__ tkapp = LcdApplication (master = self .__ root)
        self .__ tkapp.master.title ( 'ARobot3.0-Lcd')
        t = threading.Timer (1, self .__ tkapp.updatelcd_sock)
        t.start ()
        self .__ tkapp.grid ()
        self .__ tkapp.mainloop ()
        if DEBUG:
            print 'exit arobot_lcd mainloop'
        self .__ tkapp.stop ()

    def stop (self):
        if DEBUG:
            print 'stop arobot_lcd'
        self.thread_stop = True
        if self .__ tkapp = None!:
            self .__ tkapp.stop ()
            self .__ tkapp.quit ()

def arobot_main (prog):
    if prog == None:
        return

    if prog == 'lcd':
        lcd_thread = arobot_lcd ()
        lcd_thread.start ()

    if prog == 'keypad':
        keypad_thread = arobot_keys ()
        keypad_thread.start ()

def usage ():
    print '--------------------------------------------'
    print 'Arobot 3.1'
    print 'This is a tool to control Android device via ADB'
    print 'usage: python% s [option]'% sys.argv [0]
    print 'option:'
    print '-keypad run keypad'
    print '-lcd run lcd'
    print '--------------------------------------------'

if __name__ == '__main__':
    prog_name = sys.argv [0]
    if '--debug' in sys.argv:
        DEBUG = True

    if DEBUG:
        if len (sys.argv) == 2:
            cmd_str = 'python% s -keypad --debug'% prog_name
            p1 = subprocess.Popen (cmd_str, shell = True)
            cmd_str = 'python% s -lcd --debug'% prog_name
            p2 = subprocess.Popen (cmd_str, shell = True)
        elif len (sys.argv) == 3:
            if sys.argv [1] == '-keypad':
                arobot_main ( 'keypad')
            elif sys.argv [1] == '-lcd':
                arobot_main ( 'lcd')
            else:
                usage ()
    else:
        if len (sys.argv) == 1:
            # Do not wast your time on threading, it is disaster working with tk!
            # I have tried many ways to open multi-windows via Tk and Threading
            # But fail! Or linux ok but windows fail, so, just use the subprocess!
            cmd_str = 'python% s -keypad'% prog_name
            p1 = subprocess.Popen (cmd_str, shell = True)
            cmd_str = 'python% s -lcd'% prog_name
            p2 = subprocess.Popen (cmd_str, shell = True)
        elif len (sys.argv) == 2:
            if sys.argv [1] == '-keypad':
                arobot_main ( 'keypad')
            elif sys.argv [1] == '-lcd':
                arobot_main ( 'lcd')
            else:
                usage ()
        else:
            usage ()
     
         
         
         
  More:      
 
- How to manage start-up applications in Ubuntu (Linux)
- PostgreSQL Source Customization: Online global read only (Database)
- Use lsof restore accidentally deleted log files or database (Linux)
- sudo command scenario analysis (Linux)
- Security implementation of disk data protection under Linux (Linux)
- Understand ASP.NET 5 running the command: DNVM, DNX, and DNU (Server)
- Linux regex sed detailing (Linux)
- Role Object of registerNatives () method (Programming)
- Netapp storage routine inspections and information gathering (Linux)
- Oracle Automatic Diagnostic Repository (Automatic Diagnostic Repository, ADR) (Database)
- Linux and SELinux Exploration Program Manager (Linux)
- Monitor traffic Linux Shell Edition (Programming)
- Linux System Getting Started Tutorial: how to find information on Linux-embedded module (Linux)
- GitHub multiplayer co-development configuration (Linux)
- After Ubuntu Password Forgot your way back (Linux)
- Subsequent binary search tree traversal sequence (Programming)
- linux firewall configuration (Linux)
- Build your own Python coding environment (Linux)
- Linux system on a virtual machine to access the Internet (Linux)
- Make command Detailed Tutorial (Programming)
     
           
     
  CopyRight 2002-2022 newfreesoft.com, All Rights Reserved.