blob: 125a0b08a7d88bff01f73a5f1563cebba1787066 [file] [log] [blame]
Alan Viverette7d87cea2017-09-26 13:39:21 -04001#!/usr/bin/python3
2#
3# Copyright (C) 2015 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the 'License');
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an 'AS IS' BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18import os
19import sys
20import tempfile
21import threading
22import time
23import traceback
24
25from android_device import *
26from avd import *
27from queue import Queue, Empty
28
29
30CTS_THEME_dict = {
31 120: "ldpi",
32 160: "mdpi",
33 213: "tvdpi",
34 240: "hdpi",
35 320: "xhdpi",
36 360: "360dpi",
37 420: "420dpi",
38 480: "xxhdpi",
39 560: "560dpi",
40 640: "xxxhdpi",
41}
42
43OUT_FILE = "/sdcard/cts-theme-assets.zip"
44
45
46class ParallelExecutor(threading.Thread):
47 def __init__(self, tasks, q):
48 threading.Thread.__init__(self)
49 self._q = q
50 self._tasks = tasks
51 self._setup = setup
52 self._result = 0
53
54 def run(self):
55 try:
56 while True:
57 config = q.get(block=True, timeout=2)
58 for t in self._tasks:
59 try:
60 if t(self._setup, config):
61 self._result += 1
62 except KeyboardInterrupt:
63 raise
64 except:
65 print("Failed to execute thread:", sys.exc_info()[0])
66 traceback.print_exc()
67 q.task_done()
68 except KeyboardInterrupt:
69 raise
70 except Empty:
71 pass
72
73 def get_result(self):
74 return self._result
75
76
77# pass a function with number of instances to be executed in parallel
78# each thread continues until config q is empty.
79def execute_parallel(tasks, setup, q, num_threads):
80 result = 0
81 threads = []
82 for i in range(num_threads):
83 t = ParallelExecutor(tasks, q)
84 t.start()
85 threads.append(t)
86 for t in threads:
87 t.join()
88 result += t.get_result()
89 return result
90
91
92def print_adb_result(device, out, err):
93 print("device: " + device)
94 if out is not None:
95 print("out:\n" + out)
96 if err is not None:
97 print("err:\n" + err)
98
99
100def do_capture(setup, device_serial):
101 (themeApkPath, out_path) = setup
102
103 device = AndroidDevice(device_serial)
104
105 version = device.get_version_codename()
106 if version == "REL":
107 version = str(device.get_version_sdk())
108
109 density = device.get_density()
110
111 if CTS_THEME_dict[density]:
112 density_bucket = CTS_THEME_dict[density]
113 else:
114 density_bucket = str(density) + "dpi"
115
116 out_file = os.path.join(out_path, os.path.join(version, "%s.zip" % density_bucket))
117
118 device.uninstall_package('android.theme.app')
119
120 (out, err, success) = device.install_apk(themeApkPath)
121 if not success:
122 print("Failed to install APK on " + device_serial)
123 print_adb_result(device_serial, out, err)
124 return False
125
126 print("Generating images on " + device_serial + "...")
127 try:
128 (out, err) = device.run_instrumentation_test(
129 "android.theme.app/android.support.test.runner.AndroidJUnitRunner")
130 except KeyboardInterrupt:
131 raise
132 except:
133 (out, err) = device.run_instrumentation_test(
134 "android.theme.app/android.test.InstrumentationTestRunner")
135
136 # Detect test failure and abort.
137 if "FAILURES!!!" in out.split():
138 print_adb_result(device_serial, out, err)
139 return False
140
141 # Make sure that the run is complete by checking the process itself
142 print("Waiting for " + device_serial + "...")
143 wait_time = 0
144 while device.is_process_alive("android.theme.app"):
145 time.sleep(1)
146 wait_time = wait_time + 1
147 if wait_time > 180:
148 print("Timed out")
149 break
150
151 time.sleep(10)
152
153 print("Pulling images from " + device_serial + " to " + out_file)
154 device.run_adb_command("pull " + OUT_FILE + " " + out_file)
155 device.run_adb_command("shell rm -rf " + OUT_FILE)
156 return True
157
158
159def get_emulator_path():
160 if 'ANDROID_SDK_ROOT' not in os.environ:
161 print('Environment variable ANDROID_SDK_ROOT must point to your Android SDK root.')
162 sys.exit(1)
163
164 sdk_path = os.environ['ANDROID_SDK_ROOT']
165 if not os.path.isdir(sdk_path):
166 print("Failed to find Android SDK at ANDROID_SDK_ROOT: %s" % sdk_path)
167 sys.exit(1)
168
169 emu_path = os.path.join(os.path.join(sdk_path, 'tools'), 'emulator')
170 if not os.path.isfile(emu_path):
171 print("Failed to find emulator within ANDROID_SDK_ROOT: %s" % sdk_path)
172 sys.exit(1)
173
174 return emu_path
175
176
177def start_emulator(name, density):
178 emu_path = get_emulator_path()
179
180 # Start emulator for 560dpi, normal screen size.
181 test_avd = AVD(name, emu_path)
182 test_avd.configure_screen(density, 360, 640)
183 test_avd.start()
184 try:
185 test_avd_device = test_avd.get_device()
186 test_avd_device.wait_for_device()
187 test_avd_device.wait_for_boot_complete()
188 return test_avd
189 except:
190 test_avd.stop()
191 return None
192
193
194def main(argv):
195 if 'ANDROID_BUILD_TOP' not in os.environ or 'ANDROID_HOST_OUT' not in os.environ:
196 print('Missing environment variables. Did you run build/envsetup.sh and lunch?')
197 sys.exit(1)
198
199 theme_apk = os.path.join(os.environ['ANDROID_HOST_OUT'],
200 'cts/android-cts/testcases/CtsThemeDeviceApp.apk')
201 if not os.path.isfile(theme_apk):
202 print('Couldn\'t find test APK. Did you run make cts?')
203 sys.exit(1)
204
205 out_path = os.path.join(os.environ['ANDROID_BUILD_TOP'],
206 'cts/hostsidetests/theme/assets')
207 os.system("mkdir -p %s" % out_path)
208
209 if len(argv) is 2:
210 for density in CTS_THEME_dict.keys():
211 emulator = start_emulator(argv[1], density)
212 result = do_capture(setup=(theme_apk, out_path), device_serial=emulator.get_serial())
213 emulator.stop()
214 if result:
215 print("Generated reference images for %ddpi" % density)
216 else:
217 print("Failed to generate reference images for %ddpi" % density)
218 break
219 else:
220 tasks = [do_capture]
221 setup = (theme_apk, out_path)
222
223 devices = enumerate_android_devices('emulator')
224
225 device_queue = Queue()
226 for device in devices:
227 device_queue.put(device)
228
229 result = execute_parallel(tasks, setup, device_queue, len(devices))
230
231 if result > 0:
232 print('Generated reference images for %(count)d devices' % {"count": result})
233 else:
234 print('Failed to generate reference images')
235
236
237if __name__ == '__main__':
238 main(sys.argv)