-
Notifications
You must be signed in to change notification settings - Fork 348
/
dump
executable file
·228 lines (205 loc) · 7.86 KB
/
dump
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#! /usr/bin/env python3
'''
Copyright (C) 2012-2021 Diego Torres Milano
Created on Feb 3, 2012
@author: diego
'''
from __future__ import print_function
__version__ = '24.1.0'
import getopt
import os
import sys
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
from com.dtmilano.android.common import debugArgsToDict
HELP = 'help'
VERBOSE = 'verbose'
VERSION = 'version'
DEBUG = 'debug'
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:ZBhX:'
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,
DEBUG + '='
]
LONG_OPTS_ARG = {WINDOW: 'WINDOW', SAVE_SCREENSHOT: 'FILE', SAVE_VIEW_SCREENSHOTS: 'DIR', DEVICE_ART: 'MODEL',
DEBUG: 'LIST'}
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',
'X': 'debug options',
}
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 = int(len(t) / 2)
sl = []
for i in range(l2):
sl.append((t[i], t[i + l2]))
return sl
def usage(exitVal=1):
print(USAGE % progname, file=sys.stderr)
print("Try '%s --help' for more information." % progname, file=sys.stderr)
sys.exit(exitVal)
def _help():
print(USAGE % progname, file=sys.stderr)
print(file=sys.stderr)
print("Options:", file=sys.stderr)
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(o, file=sys.stderr)
sys.exit(0)
def version():
print('{} version {}'.format(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 as e:
print('ERROR:', str(e), file=sys.stderr)
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,
ViewClientOptions.DEBUG: {},
}
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]
elif o in ['X', DEBUG]:
kwargs2[ViewClientOptions.DEBUG] = debugArgsToDict(a)
else:
transform = MAP[o]
if options[DO_NOT_DUMP_VIEWS]:
transform = MAP[DO_NOT_DUMP_VIEWS]
vc = ViewClient(*ViewClient.connectToDeviceOrExit(**kwargs1), **kwargs2)
if options[WINDOW] == 'list':
vc.list()
sys.exit(0)
if options[SAVE_SCREENSHOT]:
vc.device.reconnect = True # (not options[DO_NOT_DUMP_VIEWS])
ext = os.path.splitext(options[SAVE_SCREENSHOT])[1][1:].upper()
_format = ext
if ext == 'JPG':
_format = 'JPEG'
vc.writeImageToFile(options[SAVE_SCREENSHOT], _format=_format, 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