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