1ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda#!/usr/bin/env python 2ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda# Copyright (C) 2015 The Android Open Source Project 3ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda# 4ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda# Licensed under the Apache License, Version 2.0 (the "License"); 5ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda# you may not use this file except in compliance with the License. 6ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda# You may obtain a copy of the License at 7ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda# 8ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda# http://www.apache.org/licenses/LICENSE-2.0 9ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda# 10ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda# Unless required by applicable law or agreed to in writing, software 11ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda# distributed under the License is distributed on an "AS IS" BASIS, 12ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda# See the License for the specific language governing permissions and 14ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda# limitations under the License. 15ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda"""Record the event logs during boot and output them to a file. 16ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 17ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro MatsudaThis script repeats the record of each event log during Android boot specified 18ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudatimes. By default, interval between measurements is adjusted in such a way that 19ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro MatsudaCPUs are cooled down sufficiently to avoid boot time slowdown caused by CPU 20ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudathermal throttling. The result is output in a tab-separated value format. 21ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 22ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro MatsudaExamples: 23ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 24ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro MatsudaRepeat measurements 10 times. Interval between iterations is adjusted based on 25ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro MatsudaCPU temperature of the device. 26ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 27ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda$ ./perfboot.py --iterations=10 28ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 29ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro MatsudaRepeat measurements 20 times. 60 seconds interval is taken between each 30ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaiteration. 31ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 32ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda$ ./perfboot.py --iterations=20 --interval=60 33ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 34ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro MatsudaRepeat measurements 20 times, show verbose output, output the result to 35ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadata.tsv, and read event tags from eventtags.txt. 36ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 37ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda$ ./perfboot.py --iterations=30 -v --output=data.tsv --tags=eventtags.txt 38ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda""" 39ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 40ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaimport argparse 41ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaimport atexit 42ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaimport cStringIO 43c0822e83ad11e42e02f2304e9cf925ea944b8f53Yasuhiro Matsudaimport glob 44ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaimport inspect 45ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaimport logging 46ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaimport math 47ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaimport os 48ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaimport re 49ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaimport subprocess 50ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaimport sys 51ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaimport threading 52ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaimport time 53ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 54ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudasys.path.append(os.path.dirname(os.path.dirname(__file__))) 55ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaimport adb 56ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 57ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda# The default event tags to record. 58ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda_DEFAULT_EVENT_TAGS = [ 59ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'boot_progress_start', 60ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'boot_progress_preload_start', 61ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'boot_progress_preload_end', 62ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'boot_progress_system_run', 63ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'boot_progress_pms_start', 64ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'boot_progress_pms_system_scan_start', 65ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'boot_progress_pms_data_scan_start', 66ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'boot_progress_pms_scan_end', 67ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'boot_progress_pms_ready', 68ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'boot_progress_ams_ready', 69ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'boot_progress_enable_screen', 7043c4d998cf8bb5875479d84cb5e5c253a7a11af6Yusuke Sato 'sf_stop_bootanim', 7143c4d998cf8bb5875479d84cb5e5c253a7a11af6Yusuke Sato 'wm_boot_animation_done', 72ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda] 73ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 74ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 75ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaclass IntervalAdjuster(object): 76ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """A helper class to take suffficient interval between iterations.""" 77ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 78ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # CPU temperature values per product used to decide interval 79ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda _CPU_COOL_DOWN_THRESHOLDS = { 80ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'flo': 40, 81ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'flounder': 40000, 82ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'razor': 40, 83ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'volantis': 40000, 84ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda } 85ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # The interval between CPU temperature checks 86ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda _CPU_COOL_DOWN_WAIT_INTERVAL = 10 87ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # The wait time used when the value of _CPU_COOL_DOWN_THRESHOLDS for 88ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # the product is not defined. 89ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda _CPU_COOL_DOWN_WAIT_TIME_DEFAULT = 120 90ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 91ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda def __init__(self, interval, device): 92ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda self._interval = interval 93ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda self._device = device 94ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda self._temp_paths = device.shell( 956ee194013ae27a9b73d011e9fe246c6d8ecef6d5Yasuhiro Matsuda ['ls', '/sys/class/thermal/thermal_zone*/temp'])[0].splitlines() 96ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda self._product = device.get_prop('ro.build.product') 97ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda self._waited = False 98ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 99ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda def wait(self): 100ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """Waits certain amount of time for CPUs cool-down.""" 101ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if self._interval is None: 102ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda self._wait_cpu_cool_down(self._product, self._temp_paths) 103ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda else: 104ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if self._waited: 105ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda print 'Waiting for %d seconds' % self._interval 106ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda time.sleep(self._interval) 107ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda self._waited = True 108ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 109ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda def _get_cpu_temp(self, threshold): 110ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda max_temp = 0 111ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda for temp_path in self._temp_paths: 1126ee194013ae27a9b73d011e9fe246c6d8ecef6d5Yasuhiro Matsuda temp = int(self._device.shell(['cat', temp_path])[0].rstrip()) 113ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda max_temp = max(max_temp, temp) 114ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if temp >= threshold: 115ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return temp 116ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return max_temp 117ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 118ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda def _wait_cpu_cool_down(self, product, temp_paths): 119ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda threshold = IntervalAdjuster._CPU_COOL_DOWN_THRESHOLDS.get( 120ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda self._product) 121ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if threshold is None: 122ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda print 'No CPU temperature threshold is set for ' + self._product 123ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda print ('Just wait %d seconds' % 124ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda IntervalAdjuster._CPU_COOL_DOWN_WAIT_TIME_DEFAULT) 125ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda time.sleep(IntervalAdjuster._CPU_COOL_DOWN_WAIT_TIME_DEFAULT) 126ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return 127ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda while True: 128ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda temp = self._get_cpu_temp(threshold) 129ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if temp < threshold: 130ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda logging.info('Current CPU temperature %s' % temp) 131ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return 132ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda print 'Waiting until CPU temperature (%d) falls below %d' % ( 133ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda temp, threshold) 134ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda time.sleep(IntervalAdjuster._CPU_COOL_DOWN_WAIT_INTERVAL) 135ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 136ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 137ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaclass WatchdogTimer(object): 138ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """A timer that makes is_timedout() return true in |timeout| seconds.""" 139ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda def __init__(self, timeout): 140ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda self._timedout = False 141ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 142ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda def notify_timeout(): 143ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda self._timedout = True 144ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda self._timer = threading.Timer(timeout, notify_timeout) 14559d32a7515c757d6171605bea0ef631d1837b365Yasuhiro Matsuda self._timer.daemon = True 146ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda self._timer.start() 147ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 148ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda def is_timedout(self): 149ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return self._timedout 150ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 151ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda def cancel(self): 152ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda self._timer.cancel() 153ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 154ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 155ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadef readlines_unbuffered(proc): 156ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """Read lines from |proc|'s standard out without buffering.""" 157ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda while True: 158ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda buf = [] 159ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda c = proc.stdout.read(1) 160ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if c == '' and proc.poll() is not None: 161ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda break 162ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda while c != '\n': 163ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if c == '' and proc.poll() is not None: 164ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda break 165ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda buf.append(c) 166ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda c = proc.stdout.read(1) 167ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda yield ''.join(buf) 168ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 169ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 170ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadef disable_dropbox(device): 171ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """Removes the files created by Dropbox and avoids creating the files.""" 172ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device.root() 173ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device.wait() 174ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device.shell(['rm', '-rf', '/system/data/dropbox']) 175ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda original_dropbox_max_files = device.shell( 1766ee194013ae27a9b73d011e9fe246c6d8ecef6d5Yasuhiro Matsuda ['settings', 'get', 'global', 'dropbox_max_files'])[0].rstrip() 177ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device.shell(['settings', 'put', 'global', 'dropbox_max_files', '0']) 178ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return original_dropbox_max_files 179ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 180ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 181ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadef restore_dropbox(device, original_dropbox_max_files): 182ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """Restores the dropbox_max_files setting.""" 183ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device.root() 184ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device.wait() 185ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if original_dropbox_max_files == 'null': 186ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device.shell(['settings', 'delete', 'global', 'dropbox_max_files']) 187ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda else: 188ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device.shell(['settings', 'put', 'global', 'dropbox_max_files', 189ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda original_dropbox_max_files]) 190ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 191ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 192ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadef init_perf(device, output, record_list, tags): 193ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device.wait() 194246b0fd0d9cccc28150f71d55d817f9cacf2a7e0Yusuke Sato debuggable = device.get_prop('ro.debuggable') 195ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda original_dropbox_max_files = None 196246b0fd0d9cccc28150f71d55d817f9cacf2a7e0Yusuke Sato if debuggable == '1': 197ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # Workaround for Dropbox issue (http://b/20890386). 198ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda original_dropbox_max_files = disable_dropbox(device) 199ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 200ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda def cleanup(): 201ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda try: 202ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if record_list: 203ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda print_summary(record_list, tags[-1]) 204ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda output_results(output, record_list, tags) 205ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if original_dropbox_max_files is not None: 206ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda restore_dropbox(device, original_dropbox_max_files) 207f3d0d42f1a38906e0e80ab96368ad01b8a58f8d0Yasuhiro Matsuda except (subprocess.CalledProcessError, RuntimeError): 208ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda pass 209ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda atexit.register(cleanup) 210ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 211ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 212b6c66dc0a3fbd8f76ad9ca5fb6d9049a784b7396Yusuke Satodef check_dm_verity_settings(device): 213b6c66dc0a3fbd8f76ad9ca5fb6d9049a784b7396Yusuke Sato device.wait() 214b6c66dc0a3fbd8f76ad9ca5fb6d9049a784b7396Yusuke Sato for partition in ['system', 'vendor']: 215b6c66dc0a3fbd8f76ad9ca5fb6d9049a784b7396Yusuke Sato verity_mode = device.get_prop('partition.%s.verified' % partition) 216b6c66dc0a3fbd8f76ad9ca5fb6d9049a784b7396Yusuke Sato if verity_mode is None: 217b6c66dc0a3fbd8f76ad9ca5fb6d9049a784b7396Yusuke Sato logging.warning('dm-verity is not enabled for /%s. Did you run ' 218b6c66dc0a3fbd8f76ad9ca5fb6d9049a784b7396Yusuke Sato 'adb disable-verity? That may skew the result.', 219b6c66dc0a3fbd8f76ad9ca5fb6d9049a784b7396Yusuke Sato partition) 220b6c66dc0a3fbd8f76ad9ca5fb6d9049a784b7396Yusuke Sato 221b6c66dc0a3fbd8f76ad9ca5fb6d9049a784b7396Yusuke Sato 222ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadef read_event_tags(tags_file): 223ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """Reads event tags from |tags_file|.""" 224ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if not tags_file: 225ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return _DEFAULT_EVENT_TAGS 226ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda tags = [] 227ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda with open(tags_file) as f: 228ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda for line in f: 229ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if '#' in line: 230ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda line = line[:line.find('#')] 231ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda line = line.strip() 232ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if line: 233ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda tags.append(line) 234ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return tags 235ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 236ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 237ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadef make_event_tags_re(tags): 238ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """Makes a regular expression object that matches event logs of |tags|.""" 239ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return re.compile(r'(?P<pid>[0-9]+) +[0-9]+ I (?P<tag>%s): (?P<time>\d+)' % 240ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda '|'.join(tags)) 241ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 242ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 243e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Satodef filter_event_tags(tags, device): 244e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Sato """Drop unknown tags not listed in device's event-log-tags file.""" 245e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Sato device.wait() 246e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Sato supported_tags = set() 2476ee194013ae27a9b73d011e9fe246c6d8ecef6d5Yasuhiro Matsuda for l in device.shell( 2486ee194013ae27a9b73d011e9fe246c6d8ecef6d5Yasuhiro Matsuda ['cat', '/system/etc/event-log-tags'])[0].splitlines(): 249e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Sato tokens = l.split(' ') 250e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Sato if len(tokens) >= 2: 251e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Sato supported_tags.add(tokens[1]) 252e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Sato filtered = [] 253e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Sato for tag in tags: 254e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Sato if tag in supported_tags: 255e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Sato filtered.append(tag) 256e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Sato else: 257e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Sato logging.warning('Unknown tag \'%s\'. Ignoring...', tag) 258e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Sato return filtered 259e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Sato 260e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Sato 261ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadef get_values(record, tag): 262ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """Gets values that matches |tag| from |record|.""" 263ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda keys = [key for key in record.keys() if key[0] == tag] 264ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return [record[k] for k in sorted(keys)] 265ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 266ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 267ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadef get_last_value(record, tag): 268ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """Gets the last value that matches |tag| from |record|.""" 269ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda values = get_values(record, tag) 270ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if not values: 271ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return 0 272ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return values[-1] 273ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 274ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 275ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadef output_results(filename, record_list, tags): 276ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """Outputs |record_list| into |filename| in a TSV format.""" 277ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # First, count the number of the values of each tag. 278ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # This is for dealing with events that occur multiple times. 279ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # For instance, boot_progress_preload_start and boot_progress_preload_end 280ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # are recorded twice on 64-bit system. One is for 64-bit zygote process 281ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # and the other is for 32-bit zygote process. 282ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda values_counter = {} 283ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda for record in record_list: 284ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda for tag in tags: 285ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # Some record might lack values for some tags due to unanticipated 286ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # problems (e.g. timeout), so take the maximum count among all the 287ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # record. 288ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda values_counter[tag] = max(values_counter.get(tag, 1), 289ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda len(get_values(record, tag))) 290ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 291ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # Then creates labels for the data. If there are multiple values for one 292ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # tag, labels for these values are numbered except the first one as 293ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # follows: 294ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # 295ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # event_tag event_tag2 event_tag3 296ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # 297ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # The corresponding values are sorted in an ascending order of PID. 298ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda labels = [] 299ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda for tag in tags: 300ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda for i in range(1, values_counter[tag] + 1): 301ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda labels.append('%s%s' % (tag, '' if i == 1 else str(i))) 302ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 303ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # Finally write the data into the file. 304ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda with open(filename, 'w') as f: 305ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda f.write('\t'.join(labels) + '\n') 306ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda for record in record_list: 307ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda line = cStringIO.StringIO() 308ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda invalid_line = False 309ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda for i, tag in enumerate(tags): 310ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if i != 0: 311ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda line.write('\t') 312ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda values = get_values(record, tag) 313ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if len(values) < values_counter[tag]: 314ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda invalid_line = True 315ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # Fill invalid record with 0 316ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda values += [0] * (values_counter[tag] - len(values)) 317ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda line.write('\t'.join(str(t) for t in values)) 318ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if invalid_line: 319ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda logging.error('Invalid record found: ' + line.getvalue()) 320ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda line.write('\n') 321ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda f.write(line.getvalue()) 322ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda print 'Wrote: ' + filename 323ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 324ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 325ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadef median(data): 326ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """Calculates the median value from |data|.""" 327ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda data = sorted(data) 328ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda n = len(data) 329ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if n % 2 == 1: 330ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return data[n / 2] 331ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda else: 332ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda n2 = n / 2 333ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return (data[n2 - 1] + data[n2]) / 2.0 334ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 335ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 336ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadef mean(data): 337ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """Calculates the mean value from |data|.""" 338ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return float(sum(data)) / len(data) 339ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 340ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 341ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadef stddev(data): 342ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """Calculates the standard deviation value from |value|.""" 343ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda m = mean(data) 344ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return math.sqrt(sum((x - m) ** 2 for x in data) / len(data)) 345ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 346ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 347ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadef print_summary(record_list, end_tag): 348ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """Prints the summary of |record_list|.""" 349ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # Filter out invalid data. 350ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda end_times = [get_last_value(record, end_tag) for record in record_list 351ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if get_last_value(record, end_tag) != 0] 352ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda print 'mean: ', mean(end_times) 353ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda print 'median:', median(end_times) 354ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda print 'standard deviation:', stddev(end_times) 355ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 356ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 357ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadef do_iteration(device, interval_adjuster, event_tags_re, end_tag): 358ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """Measures the boot time once.""" 359ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device.wait() 360ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda interval_adjuster.wait() 361ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device.reboot() 362ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda print 'Rebooted the device' 363ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda record = {} 364ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda booted = False 365ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda while not booted: 366ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device.wait() 367ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda # Stop the iteration if it does not finish within 120 seconds. 368ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda timeout = 120 369ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda t = WatchdogTimer(timeout) 370ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda p = subprocess.Popen( 371ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda ['adb', 'logcat', '-b', 'events', '-v', 'threadtime'], 372ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda stdout=subprocess.PIPE) 373ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda for line in readlines_unbuffered(p): 374ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if t.is_timedout(): 375ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda print '*** Timed out ***' 376ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return record 377ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda m = event_tags_re.search(line) 378ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if not m: 379ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda continue 380ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda tag = m.group('tag') 381ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda event_time = int(m.group('time')) 382ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda pid = m.group('pid') 383ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda record[(tag, pid)] = event_time 384ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda print 'Event log recorded: %s (%s) - %d ms' % ( 385ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda tag, pid, event_time) 386ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if tag == end_tag: 387ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda booted = True 388ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda t.cancel() 389ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda break 390ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return record 391ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 392ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 393ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadef parse_args(): 394ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda """Parses the command line arguments.""" 395ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda parser = argparse.ArgumentParser( 396ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda description=inspect.getdoc(sys.modules[__name__]), 397ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda formatter_class=argparse.RawDescriptionHelpFormatter) 398ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda parser.add_argument('--iterations', type=int, default=5, 399ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda help='Number of times to repeat boot measurements.') 400ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda parser.add_argument('--interval', type=int, 401ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda help=('Duration between iterations. If this is not ' 402ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'set explicitly, durations are determined ' 403ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'adaptively based on CPUs temperature.')) 404ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda parser.add_argument('-o', '--output', help='File name of output data.') 405ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda parser.add_argument('-v', '--verbose', action='store_true', 406ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda help='Show verbose output.') 407ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda parser.add_argument('-s', '--serial', default=os.getenv('ANDROID_SERIAL'), 408ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda help='Adb device serial number.') 409ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda parser.add_argument('-t', '--tags', help='Specify the filename from which ' 410ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'event tags are read. Every line contains one event ' 411ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 'tag and the last event tag is used to detect that ' 4123966ebb74d7aec08169b99d3cecf23ea3815435fYusuke Sato 'the device has finished booting unless --end-tag is ' 4133966ebb74d7aec08169b99d3cecf23ea3815435fYusuke Sato 'specified.') 4143966ebb74d7aec08169b99d3cecf23ea3815435fYusuke Sato parser.add_argument('--end-tag', help='An event tag on which the script ' 4153966ebb74d7aec08169b99d3cecf23ea3815435fYusuke Sato 'stops measuring the boot time.') 416c0822e83ad11e42e02f2304e9cf925ea944b8f53Yasuhiro Matsuda parser.add_argument('--apk-dir', help='Specify the directory which contains ' 417c0822e83ad11e42e02f2304e9cf925ea944b8f53Yasuhiro Matsuda 'APK files to be installed before measuring boot time.') 418ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda return parser.parse_args() 419ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 420ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 421c0822e83ad11e42e02f2304e9cf925ea944b8f53Yasuhiro Matsudadef install_apks(device, apk_dir): 422c0822e83ad11e42e02f2304e9cf925ea944b8f53Yasuhiro Matsuda for apk in glob.glob(os.path.join(apk_dir, '*.apk')): 423c0822e83ad11e42e02f2304e9cf925ea944b8f53Yasuhiro Matsuda print 'Installing: ' + apk 424c0822e83ad11e42e02f2304e9cf925ea944b8f53Yasuhiro Matsuda device.install(apk, replace=True) 425c0822e83ad11e42e02f2304e9cf925ea944b8f53Yasuhiro Matsuda 426c0822e83ad11e42e02f2304e9cf925ea944b8f53Yasuhiro Matsuda 427ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudadef main(): 428ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda args = parse_args() 429ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if args.verbose: 430ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda logging.getLogger().setLevel(logging.INFO) 431ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 432ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device = adb.get_device(args.serial) 433ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 434ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda if not args.output: 435ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device.wait() 436ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda args.output = 'perf-%s-%s.tsv' % ( 437ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device.get_prop('ro.build.flavor'), 438ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device.get_prop('ro.build.version.incremental')) 439b6c66dc0a3fbd8f76ad9ca5fb6d9049a784b7396Yusuke Sato check_dm_verity_settings(device) 440ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 441c0822e83ad11e42e02f2304e9cf925ea944b8f53Yasuhiro Matsuda if args.apk_dir: 442c0822e83ad11e42e02f2304e9cf925ea944b8f53Yasuhiro Matsuda install_apks(device, args.apk_dir) 443c0822e83ad11e42e02f2304e9cf925ea944b8f53Yasuhiro Matsuda 444ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda record_list = [] 445e801cc0b4e26d13a4d5dc3ef771172dec96ad4ecYusuke Sato event_tags = filter_event_tags(read_event_tags(args.tags), device) 4463966ebb74d7aec08169b99d3cecf23ea3815435fYusuke Sato end_tag = args.end_tag or event_tags[-1] 4473966ebb74d7aec08169b99d3cecf23ea3815435fYusuke Sato if end_tag not in event_tags: 4483966ebb74d7aec08169b99d3cecf23ea3815435fYusuke Sato sys.exit('%s is not a valid tag.' % end_tag) 4493966ebb74d7aec08169b99d3cecf23ea3815435fYusuke Sato event_tags = event_tags[0 : event_tags.index(end_tag) + 1] 450ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda init_perf(device, args.output, record_list, event_tags) 451ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda interval_adjuster = IntervalAdjuster(args.interval, device) 452ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda event_tags_re = make_event_tags_re(event_tags) 4533966ebb74d7aec08169b99d3cecf23ea3815435fYusuke Sato 454ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda for i in range(args.iterations): 455ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda print 'Run #%d ' % i 456ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda record = do_iteration( 457ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda device, interval_adjuster, event_tags_re, end_tag) 458ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda record_list.append(record) 459ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 460ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda 461ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsudaif __name__ == '__main__': 462ab3798399dfe970a12a25f79c4392602b6d7515bYasuhiro Matsuda main() 463