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