blob: 33cbbd5febb80ab742909173896167d531ba6744 [file] [log] [blame]
#! /usr/bin/env python
'''
Copyright (C) 2012-2015 Diego Torres Milano
Created on Feb 3, 2012
@author: diego
'''
__version__ = '11.5.9'
import sys
import os
import getopt
try:
sys.path.insert(0, os.path.join(os.environ['ANDROID_VIEW_CLIENT_HOME'], 'src'))
except:
pass
from com.dtmilano.android.viewclient import ViewClient, View, ViewClientOptions
HELP = 'help'
VERBOSE = 'verbose'
VERSION = 'version'
IGNORE_SECURE_DEVICE = 'ignore-secure-device'
IGNORE_VERSION_CHECK = 'ignore-version-check'
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'
ALL = 'all'
UNIQUE_ID = 'uniqueId'
POSITION = 'position'
BOUNDS = 'bounds'
CONTENT_DESCRIPTION = 'content-description'
TAG = 'tag'
CENTER = 'center'
SAVE_SCREENSHOT = 'save-screenshot'
SAVE_VIEW_SCREENSHOTS = 'save-view-screenshots'
DO_NOT_DUMP_VIEWS = 'do-not-dump-views'
DEVICE_ART = 'device-art'
DROP_SHADOW = 'drop-shadow'
SCREEN_GLARE = 'glare'
USE_UIAUTOMATOR_HELPER = 'use-uiautomator-helper'
MAP = {
'a':View.__str__, ALL:View.__str__,
'i':ViewClient.TRAVERSE_CITUI, UNIQUE_ID:ViewClient.TRAVERSE_CITUI,
'x':ViewClient.TRAVERSE_CITPS, POSITION:ViewClient.TRAVERSE_CITPS,
'b':ViewClient.TRAVERSE_CITB, BOUNDS:ViewClient.TRAVERSE_CITB,
'd':ViewClient.TRAVERSE_CITCD, CONTENT_DESCRIPTION:ViewClient.TRAVERSE_CITCD,
'g':ViewClient.TRAVERSE_CITG, TAG:ViewClient.TRAVERSE_CITG,
'c':ViewClient.TRAVERSE_CITC, CENTER:ViewClient.TRAVERSE_CITC,
'W':ViewClient.TRAVERSE_CITCDS, SAVE_VIEW_SCREENSHOTS:ViewClient.TRAVERSE_CITCDS,
'D':ViewClient.TRAVERSE_S, DO_NOT_DUMP_VIEWS:ViewClient.TRAVERSE_S
}
USAGE = 'usage: %s [OPTION]... [serialno]'
SHORT_OPTS = 'HVvIEFSkw:aixbdgcf:W:DA:ZBh'
LONG_OPTS = [HELP, VERBOSE, VERSION, IGNORE_SECURE_DEVICE, IGNORE_VERSION_CHECK, FORCE_VIEW_SERVER_USE,
DO_NOT_START_VIEW_SERVER, DO_NOT_IGNORE_UIAUTOMATOR_KILLED, WINDOW + '=',
ALL, UNIQUE_ID, POSITION, BOUNDS, CONTENT_DESCRIPTION, TAG, CENTER,
SAVE_SCREENSHOT + '=', SAVE_VIEW_SCREENSHOTS + '=',
DO_NOT_DUMP_VIEWS,
DEVICE_ART + '=', DROP_SHADOW, SCREEN_GLARE,
USE_UIAUTOMATOR_HELPER,
]
LONG_OPTS_ARG = {WINDOW: 'WINDOW', SAVE_SCREENSHOT: 'FILE', SAVE_VIEW_SCREENSHOTS: 'DIR', DEVICE_ART: 'MODEL'}
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)',
'a': 'dump all information about Views',
'i': 'dump View unique IDs',
'x': 'dump View positions',
'b': 'dump View bounds',
'd': 'dump View content descriptions',
'g': 'dump View tags',
'c': 'dump View centers',
'f': 'save screenshot to file',
'W': 'save View screenshots to files in directory',
'E': 'ignores ADB version check',
'D': 'don\'t dump views, only useful if you specified -f or -W',
'A': 'device art model to frame screenshot (auto: autodetected)',
'Z': 'drop shadow for device art screenshot',
'B': 'screen glare over screenshot',
'h': 'use UiAutomatorHelper Android app',
}
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)
def version():
print progname, __version__
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, 'ignoreversioncheck': False}
kwargs2 = {ViewClientOptions.FORCE_VIEW_SERVER_USE: False, ViewClientOptions.START_VIEW_SERVER: True,
ViewClientOptions.AUTO_DUMP: False, ViewClientOptions.IGNORE_UIAUTOMATOR_KILLED: True,
ViewClientOptions.COMPRESSED_DUMP: True,
ViewClientOptions.USE_UIAUTOMATOR_HELPER: False,
}
options = {WINDOW: -1, SAVE_SCREENSHOT: None, SAVE_VIEW_SCREENSHOTS: None, DO_NOT_DUMP_VIEWS: False,
DEVICE_ART: None, DROP_SHADOW: False, SCREEN_GLARE: False}
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 ['v', VERSION]:
version()
elif o in ['I', IGNORE_SECURE_DEVICE]:
kwargs1['ignoresecuredevice'] = True
elif o in ['E', IGNORE_VERSION_CHECK]:
kwargs1['ignoreversioncheck'] = True
elif o in ['F', FORCE_VIEW_SERVER_USE]:
kwargs2[ViewClientOptions.FORCE_VIEW_SERVER_USE] = True
elif o in ['S', DO_NOT_START_VIEW_SERVER]:
kwargs2[ViewClientOptions.START_VIEW_SERVER] = False
elif o in ['k', DO_NOT_IGNORE_UIAUTOMATOR_KILLED]:
kwargs2[ViewClientOptions.IGNORE_UIAUTOMATOR_KILLED] = False
elif o in ['w', WINDOW]:
options[WINDOW] = a
elif o in ['f', SAVE_SCREENSHOT]:
options[SAVE_SCREENSHOT] = a
elif o in ['W', SAVE_VIEW_SCREENSHOTS]:
options[SAVE_VIEW_SCREENSHOTS] = a
transform = MAP[o]
elif o in ['A', DEVICE_ART]:
options[DEVICE_ART] = a
elif o in ['Z', DROP_SHADOW]:
options[DROP_SHADOW] = True
elif o in ['B', SCREEN_GLARE]:
options[SCREEN_GLARE] = True
elif o in ['h', USE_UIAUTOMATOR_HELPER]:
kwargs2[ViewClientOptions.USE_UIAUTOMATOR_HELPER] = True
elif o in ['D', DO_NOT_DUMP_VIEWS]:
options[DO_NOT_DUMP_VIEWS] = True
transform = MAP[o]
else:
transform = MAP[o]
if options[DO_NOT_DUMP_VIEWS]:
transform = MAP[DO_NOT_DUMP_VIEWS]
vc = ViewClient(*ViewClient.connectToDeviceOrExit(**kwargs1), **kwargs2)
if options[SAVE_SCREENSHOT]:
vc.device.reconnect = True #(not options[DO_NOT_DUMP_VIEWS])
vc.writeImageToFile(options[SAVE_SCREENSHOT], deviceart=options[DEVICE_ART], dropshadow=options[DROP_SHADOW], screenglare=options[SCREEN_GLARE])
if not options[DO_NOT_DUMP_VIEWS] or options[SAVE_VIEW_SCREENSHOTS]:
vc.dump(window=options[WINDOW])
ViewClient.imageDirectory = options[SAVE_VIEW_SCREENSHOTS]
vc.traverse(transform=transform)
if kwargs2[ViewClientOptions.USE_UIAUTOMATOR_HELPER]:
try:
vc.uiAutomatorHelper.quit()
except:
pass