#! /usr/bin/env python ''' Copyright (C) 2012 Diego Torres Milano Created on Feb 3, 2012 @author: diego ''' __version__ = '4.5.2' import sys import os import getopt try: sys.path.append(os.path.join(os.environ['ANDROID_VIEW_CLIENT_HOME'], 'src')) except: pass from com.dtmilano.android.viewclient import ViewClient HELP = 'help' VERBOSE = 'verbose' IGNORE_SECURE_DEVICE = 'ignore-secure-device' FORCE_VIEW_SERVER_USE = 'force-view-server-use' DO_NOT_START_VIEW_SERVER = 'do-not-start-view-server' DO_NOT_IGNORE_UIAUTOMATOR_KILLED = 'do-not-ignore-uiautomator-killed' WINDOW = 'window' UNIQUE_ID = 'uniqueId' POSITION = 'position' CONTENT_DESCRIPTION = 'content-description' CENTER = 'center' MAP = {'i':ViewClient.TRAVERSE_CITUI, UNIQUE_ID:ViewClient.TRAVERSE_CITUI, 'x':ViewClient.TRAVERSE_CITPS, POSITION:ViewClient.TRAVERSE_CITPS, 'd':ViewClient.TRAVERSE_CITCD, CONTENT_DESCRIPTION:ViewClient.TRAVERSE_CITCD, 'c':ViewClient.TRAVERSE_CITC, CENTER:ViewClient.TRAVERSE_CITC, } USAGE = 'usage: %s [OPTION]... [serialno]' SHORT_OPTS = 'HVIFSkw:ixdc' LONG_OPTS = [HELP, VERBOSE, IGNORE_SECURE_DEVICE, FORCE_VIEW_SERVER_USE, DO_NOT_START_VIEW_SERVER, DO_NOT_IGNORE_UIAUTOMATOR_KILLED, WINDOW + '=', UNIQUE_ID, POSITION, CONTENT_DESCRIPTION, CENTER] LONG_OPTS_ARG = {WINDOW: 'WINDOW'} OPTS_HELP = { 'H': 'prints this help', 'V': 'verbose comments', 'I': 'ignore secure device', 'F': 'force view server use (even if UiAutomator present)', 'S': 'don\'t start ViewServer', 'k': 'don\'t ignore UiAutomator killed', 'w': 'dump WINDOW content (default: -1, all windows)', 'i': 'dump View unique IDs', 'x': 'dump View positions', 'd': 'dump View content descriptions', 'c': 'dump View centers' } def shortAndLongOptions(): ''' @return: the list of corresponding (short-option, long-option) tuples ''' short_opts = SHORT_OPTS.replace(':', '') if len(short_opts) != len(LONG_OPTS): raise Exception('There is a mismatch between short and long options') t = tuple(short_opts) + tuple(LONG_OPTS) l2 = len(t)/2 sl = [] for i in range(l2): sl.append((t[i], t[i+l2])) return sl def usage(exitVal=1): print >> sys.stderr, USAGE % progname print >> sys.stderr, "Try '%s --help' for more information." % progname sys.exit(exitVal) def help(): print >> sys.stderr, USAGE % progname print >> sys.stderr print >> sys.stderr, "Options:" for so, lo in shortAndLongOptions(): o = ' -%c, --%s' % (so, lo) if lo[-1] == '=': o += LONG_OPTS_ARG[lo[:-1]] try: o = '%-34s %-45s' % (o, OPTS_HELP[so]) except: pass print >> sys.stderr, o sys.exit(0) # __main__ progname = os.path.basename(sys.argv[0]) try: opts, args = getopt.getopt(sys.argv[1:], SHORT_OPTS, LONG_OPTS) sys.argv[1:] = args except getopt.GetoptError, e: print >>sys.stderr, 'ERROR:', str(e) usage() kwargs1 = {VERBOSE: False, 'ignoresecuredevice': False} kwargs2 = {'forceviewserveruse': False, 'startviewserver': True, 'autodump': False, 'ignoreuiautomatorkilled': True} options = {WINDOW: -1} transform = ViewClient.TRAVERSE_CIT for o, a in opts: o = o.strip('-') if o in ['H', HELP]: help() elif o in ['V', VERBOSE]: kwargs1[VERBOSE] = True elif o in ['I', IGNORE_SECURE_DEVICE]: kwargs1['ignoresecuredevice'] = True elif o in ['F', FORCE_VIEW_SERVER_USE]: kwargs2['forceviewserveruse'] = True elif o in ['S', DO_NOT_START_VIEW_SERVER]: kwargs2['startviewserver'] = False elif o in ['k', DO_NOT_IGNORE_UIAUTOMATOR_KILLED]: kwargs2['ignoreuiautomatorkilled'] = False elif o in ['w', WINDOW]: options[WINDOW] = a else: transform = MAP[o] vc = ViewClient(*ViewClient.connectToDeviceOrExit(**kwargs1), **kwargs2) vc.dump(window=options[WINDOW]) vc.traverse(transform=transform)