1cb93a386Sopenharmony_ci# Copyright 2016 Google Inc. 2cb93a386Sopenharmony_ci# 3cb93a386Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be 4cb93a386Sopenharmony_ci# found in the LICENSE file. 5cb93a386Sopenharmony_ci 6cb93a386Sopenharmony_cifrom __future__ import print_function 7cb93a386Sopenharmony_cifrom _hardware import Hardware 8cb93a386Sopenharmony_ciimport sys 9cb93a386Sopenharmony_ciimport time 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ciclass HardwareAndroid(Hardware): 12cb93a386Sopenharmony_ci def __init__(self, adb): 13cb93a386Sopenharmony_ci Hardware.__init__(self) 14cb93a386Sopenharmony_ci self.warmup_time = 5 15cb93a386Sopenharmony_ci self._adb = adb 16cb93a386Sopenharmony_ci self.desiredClock = 0.66 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ci if self._adb.root(): 19cb93a386Sopenharmony_ci self._adb.remount() 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_ci def __enter__(self): 22cb93a386Sopenharmony_ci Hardware.__enter__(self) 23cb93a386Sopenharmony_ci if not self._adb.is_root() and self._adb.root(): 24cb93a386Sopenharmony_ci self._adb.remount() 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_ci self._adb.shell('\n'.join([ 27cb93a386Sopenharmony_ci # turn on airplane mode. 28cb93a386Sopenharmony_ci ''' 29cb93a386Sopenharmony_ci settings put global airplane_mode_on 1''', 30cb93a386Sopenharmony_ci 31cb93a386Sopenharmony_ci # disable GPS. 32cb93a386Sopenharmony_ci ''' 33cb93a386Sopenharmony_ci settings put secure location_providers_allowed -gps 34cb93a386Sopenharmony_ci settings put secure location_providers_allowed -wifi 35cb93a386Sopenharmony_ci settings put secure location_providers_allowed -network'''])) 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ci if self._adb.is_root(): 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_ci # For explanation of variance reducing steps, see 40cb93a386Sopenharmony_ci # https://g3doc.corp.google.com/engedu/portal/android/g3doc/learn/develop/performance/content/best/reliable-startup-latency.md?cl=head 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ci self._adb.shell('\n'.join([ 43cb93a386Sopenharmony_ci # disable bluetooth, wifi, and mobile data. 44cb93a386Sopenharmony_ci ''' 45cb93a386Sopenharmony_ci service call bluetooth_manager 8 46cb93a386Sopenharmony_ci svc wifi disable 47cb93a386Sopenharmony_ci svc data disable''', 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci # kill the gui. 50cb93a386Sopenharmony_ci ''' 51cb93a386Sopenharmony_ci setprop ctl.stop media 52cb93a386Sopenharmony_ci setprop ctl.stop zygote 53cb93a386Sopenharmony_ci setprop ctl.stop surfaceflinger 54cb93a386Sopenharmony_ci setprop ctl.stop drm''', 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ci # disable ASLR 57cb93a386Sopenharmony_ci ''' 58cb93a386Sopenharmony_ci echo 0 > /proc/sys/kernel/randomize_va_space''', 59cb93a386Sopenharmony_ci ])) 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_ci self.lock_top_three_cores() 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci self.lock_adreno_gpu() 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci else: 66cb93a386Sopenharmony_ci print("WARNING: no adb root access; results may be unreliable.", 67cb93a386Sopenharmony_ci file=sys.stderr) 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_ci return self 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ci def __exit__(self, exception_type, exception_value, traceback): 72cb93a386Sopenharmony_ci Hardware.__exit__(self, exception_type, exception_value, traceback) 73cb93a386Sopenharmony_ci self._adb.reboot() # some devices struggle waking up; just hard reboot. 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ci def sanity_check(self): 76cb93a386Sopenharmony_ci Hardware.sanity_check(self) 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci def print_debug_diagnostics(self): 79cb93a386Sopenharmony_ci # search for and print thermal trip points that may have been exceeded. 80cb93a386Sopenharmony_ci self._adb.shell('''\ 81cb93a386Sopenharmony_ci THERMALDIR=/sys/class/thermal 82cb93a386Sopenharmony_ci if [ ! -d $THERMALDIR ]; then 83cb93a386Sopenharmony_ci exit 84cb93a386Sopenharmony_ci fi 85cb93a386Sopenharmony_ci for ZONE in $(cd $THERMALDIR; echo thermal_zone*); do 86cb93a386Sopenharmony_ci cd $THERMALDIR/$ZONE 87cb93a386Sopenharmony_ci if [ ! -e mode ] || grep -Fxqv enabled mode || [ ! -e trip_point_0_temp ]; then 88cb93a386Sopenharmony_ci continue 89cb93a386Sopenharmony_ci fi 90cb93a386Sopenharmony_ci TEMP=$(cat temp) 91cb93a386Sopenharmony_ci TRIPPOINT=trip_point_0_temp 92cb93a386Sopenharmony_ci if [ $TEMP -le $(cat $TRIPPOINT) ]; then 93cb93a386Sopenharmony_ci echo "$ZONE ($(cat type)): temp=$TEMP <= $TRIPPOINT=$(cat $TRIPPOINT)" 1>&2 94cb93a386Sopenharmony_ci else 95cb93a386Sopenharmony_ci let i=1 96cb93a386Sopenharmony_ci while [ -e trip_point_${i}_temp ] && 97cb93a386Sopenharmony_ci [ $TEMP -gt $(cat trip_point_${i}_temp) ]; do 98cb93a386Sopenharmony_ci TRIPPOINT=trip_point_${i}_temp 99cb93a386Sopenharmony_ci let i=i+1 100cb93a386Sopenharmony_ci done 101cb93a386Sopenharmony_ci echo "$ZONE ($(cat type)): temp=$TEMP > $TRIPPOINT=$(cat $TRIPPOINT)" 1>&2 102cb93a386Sopenharmony_ci fi 103cb93a386Sopenharmony_ci done''') 104cb93a386Sopenharmony_ci 105cb93a386Sopenharmony_ci Hardware.print_debug_diagnostics(self) 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ci # expects a float between 0 and 100 representing where along the list of freqs to choose a value. 108cb93a386Sopenharmony_ci def setDesiredClock(self, c): 109cb93a386Sopenharmony_ci self.desiredClock = c / 100 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_ci def lock_top_three_cores(self): 112cb93a386Sopenharmony_ci # Lock the clocks of the fastest three cores and disable others. 113cb93a386Sopenharmony_ci # Assumes root privlidges 114cb93a386Sopenharmony_ci core_count = int(self._adb.check('cat /proc/cpuinfo | grep processor | wc -l')) 115cb93a386Sopenharmony_ci max_speeds = [] 116cb93a386Sopenharmony_ci for i in range(core_count): 117cb93a386Sopenharmony_ci khz = int(self._adb.check('cat /sys/devices/system/cpu/cpu%i/cpufreq/cpuinfo_max_freq' % i)) 118cb93a386Sopenharmony_ci max_speeds.append((khz, i)) # the tuple's first position and it will be the sort key 119cb93a386Sopenharmony_ci cores_in_desc_order_of_max_speed = [a[1] for a in sorted(max_speeds, reverse=True)] 120cb93a386Sopenharmony_ci top_cores = cores_in_desc_order_of_max_speed[:3] 121cb93a386Sopenharmony_ci disable_cores = cores_in_desc_order_of_max_speed[3:] 122cb93a386Sopenharmony_ci if disable_cores: 123cb93a386Sopenharmony_ci self._adb.shell('\n'.join([('echo 0 > /sys/devices/system/cpu/cpu%i/online' % i) for i in disable_cores])) 124cb93a386Sopenharmony_ci # since thermal-engine will be disabled, don't pick the max freq to lock these at, 125cb93a386Sopenharmony_ci # pick something lower, so it doesn't get too hot (it'd reboot) 126cb93a386Sopenharmony_ci # get a list of available scaling frequencies and pick one 2/3 of the way up. 127cb93a386Sopenharmony_ci for i in top_cores: 128cb93a386Sopenharmony_ci freqs = self._adb.check('cat /sys/devices/system/cpu/cpu%i/cpufreq/scaling_available_frequencies' % i).split() 129cb93a386Sopenharmony_ci speed = freqs[int((len(freqs)-1) * self.desiredClock)] 130cb93a386Sopenharmony_ci self._adb.shell('''echo 1 > /sys/devices/system/cpu/cpu{id}/online 131cb93a386Sopenharmony_ci echo userspace > /sys/devices/system/cpu/cpu{id}/cpufreq/scaling_governor 132cb93a386Sopenharmony_ci echo {speed} > /sys/devices/system/cpu/cpu{id}/cpufreq/scaling_max_freq 133cb93a386Sopenharmony_ci echo {speed} > /sys/devices/system/cpu/cpu{id}/cpufreq/scaling_min_freq 134cb93a386Sopenharmony_ci echo {speed} > /sys/devices/system/cpu/cpu{id}/cpufreq/scaling_setspeed'''.format(id=i, speed=speed)) 135cb93a386Sopenharmony_ci 136cb93a386Sopenharmony_ci def lock_adreno_gpu(self): 137cb93a386Sopenharmony_ci # Use presence of /sys/class/kgsl to indicate Adreno GPU 138cb93a386Sopenharmony_ci exists = self._adb.check('test -d /sys/class/kgsl && echo y') 139cb93a386Sopenharmony_ci if (exists.strip() != 'y'): 140cb93a386Sopenharmony_ci print('Not attempting Adreno GPU clock locking steps') 141cb93a386Sopenharmony_ci return 142cb93a386Sopenharmony_ci 143cb93a386Sopenharmony_ci # variance reducing changes 144cb93a386Sopenharmony_ci self._adb.shell(''' 145cb93a386Sopenharmony_ci echo 0 > /sys/class/kgsl/kgsl-3d0/bus_split 146cb93a386Sopenharmony_ci echo 1 > /sys/class/kgsl/kgsl-3d0/force_clk_on 147cb93a386Sopenharmony_ci echo 10000 > /sys/class/kgsl/kgsl-3d0/idle_timer''') 148cb93a386Sopenharmony_ci 149cb93a386Sopenharmony_ci freqs = self._adb.check('cat /sys/class/kgsl/kgsl-3d0/devfreq/available_frequencies').split() 150cb93a386Sopenharmony_ci speed = freqs[int((len(freqs)-1) * self.desiredClock)] 151cb93a386Sopenharmony_ci 152cb93a386Sopenharmony_ci # Set GPU to performance mode and lock clock 153cb93a386Sopenharmony_ci self._adb.shell(''' 154cb93a386Sopenharmony_ci echo performance > /sys/class/kgsl/kgsl-3d0/devfreq/governor 155cb93a386Sopenharmony_ci echo {speed} > /sys/class/kgsl/kgsl-3d0/devfreq/max_freq 156cb93a386Sopenharmony_ci echo {speed} > /sys/class/kgsl/kgsl-3d0/devfreq/min_freq'''.format(speed=speed)) 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_ci # Set GPU power level 159cb93a386Sopenharmony_ci self._adb.shell(''' 160cb93a386Sopenharmony_ci echo 1 > /sys/class/kgsl/kgsl-3d0/max_pwrlevel 161cb93a386Sopenharmony_ci echo 1 > /sys/class/kgsl/kgsl-3d0/min_pwrlevel''') 162