UNPKG

browsertime

Version:

Get performance metrics from your web page using Browsertime.

346 lines (293 loc) 10.9 kB
import { getLogger } from '@sitespeed.io/log'; const log = getLogger('browsertime.android'); // Adopted from // https://dxr.mozilla.org/mozilla-central/source/testing/raptor/raptor/performance_tuning.py const servicesToStop = ['mpdecision', 'thermal-engine', 'thermald']; const animationsToStop = [ 'animator_duration_scale', 'transition_animation_scale', 'window_animation_scale' ]; export class RootedDevice { constructor(androidClient, options) { this.client = androidClient; this.options = options; } async _setCPU(freq, policy, type) { return this.client._runAsRoot( `echo ${freq} > /sys/devices/system/cpu/cpufreq/policy${policy}/scaling_${type}_freq` ); } async stopServices() { for (let service of servicesToStop) { await this.client._runAsRoot(`stop ${service}`); } } async startServices() { for (let service of servicesToStop) { await this.client._runAsRoot(`start ${service}`); } } async stopAnimations() { for (let animation of animationsToStop) { await this.client._runCommand(`settings put global ${animation} 0.0`); } } async startAnimations() { for (let animation of animationsToStop) { await this.client._runCommand(`settings put global ${animation} 1.0`); } } async setScheduler() { // Scheduler return this.client._runAsRoot('echo noop > /sys/block/sda/queue/scheduler'); } async setVirtualMemory() { await this.client._runAsRoot('echo 0 > /proc/sys/vm/swappiness'); await this.client._runAsRoot('echo 85 > /proc/sys/vm/dirty_ratio'); return this.client._runAsRoot( 'echo 70 > /proc/sys/vm/dirty_background_ratio' ); } async settingKernel() { // Setting kernel await this.client._runAsRoot( 'echo 1 > /sys/kernel/debug/msm-bus-dbg/shell-client/update_request' ); await this.client._runAsRoot( 'echo 1 > /sys/kernel/debug/msm-bus-dbg/shell-client/mas' ); await this.client._runAsRoot( 'echo 0 > /sys/kernel/debug/msm-bus-dbg/shell-client/a' ); return this.client._runAsRoot( 'echo 512 > /sys/kernel/debug/msm-bus-dbg/shell-client/slv' ); } async setCPUPerformanceMotoG5() { // # MSM8937(8x 1.4GHz) // values obtained from: // cat /sys/devices/system/cpu/cpu1/cpufreq/scaling_available_frequencies // 960000 1094400 1209600 1248000 1344000 1401000 let cpuSpeed = 1_401_000; if ( this.options.androidPinCPUSpeed === 'min' || (this.options.android && this.options.android.pinCPUSpeed === 'min') ) { log.info('Set min CPU speed'); cpuSpeed = 960_000; } else if ( this.options.androidPinCPUSpeed === 'middle' || (this.options.android && this.options.android.pinCPUSpeed === 'middle') ) { log.info('Set middle CPU speed'); cpuSpeed = 1_209_600; } else { log.info('Set max CPU speed'); } for (let index = 0; index < 8; index++) { await this.client._runAsRoot( `echo performance > /sys/devices/system/cpu/cpu${index}/cpufreq/scaling_governor` ); await this.client._runAsRoot( `echo ${cpuSpeed} > /sys/devices/system/cpu/cpu${index}/cpufreq/scaling_min_freq` ); await this.client._runAsRoot( `echo ${cpuSpeed} > /sys/devices/system/cpu/cpu${index}/cpufreq/scaling_max_freq` ); } } async setCPUPerformanceSamsungA51() { // Octa-core (4x2.3 GHz Cortex-A73 & 4x1.7 GHz Cortex-A53) // See values by: // cat /sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies // cat /sys/devices/system/cpu/cpufreq/policy4/scaling_available_frequencies await this.client._runAsRoot( 'echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor' ); await this.client._runAsRoot( 'echo performance > /sys/devices/system/cpu/cpufreq/policy4/scaling_governor' ); // For the Samsung A51 we can choose min/middle or max CPU speed // Collect the current settings const currentMaxPolicy0 = await this.client._runAsRootAndGet( 'cat /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq' ); const currentMinPolicy0 = await this.client._runAsRootAndGet( 'cat /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq' ); const currentMaxPolicy4 = await this.client._runAsRootAndGet( 'cat /sys/devices/system/cpu/cpufreq/policy4/scaling_max_freq' ); const currentMinPolicy4 = await this.client._runAsRootAndGet( 'cat /sys/devices/system/cpu/cpufreq/policy4/scaling_min_freq' ); if ( this.options.androidPinCPUSpeed === 'min' || (this.options.android && this.options.android.pinCPUSpeed === 'min') ) { log.info('Set min CPU speed'); // The min settings, see the possible slowest setting by // cat /sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies const minPolicy0 = 403_000; const minPolicy4 = 936_000; // You need to set them in the correct order if (Number(currentMinPolicy0) > minPolicy0) { await this._setCPU(minPolicy0, '0', 'min'); await this._setCPU(minPolicy0, '0', 'max'); } else { await this._setCPU(minPolicy0, '0', 'max'); await this._setCPU(minPolicy0, '0', 'min'); } if (Number(currentMinPolicy4) > minPolicy4) { await this._setCPU(minPolicy4, '4', 'min'); return this._setCPU(minPolicy4, '4', 'max'); } else { await this._setCPU(minPolicy4, '4', 'max'); return this._setCPU(minPolicy4, '4', 'min'); } } else if ( this.options.androidPinCPUSpeed === 'middle' || (this.options.android && this.options.android.pinCPUSpeed === 'middle') ) { log.info('Set middle CPU speed'); const middlePolicy0 = 910_000; const middlePolicy4 = 1_508_000; if (Number(currentMaxPolicy0) > middlePolicy0) { await this._setCPU(middlePolicy0, '0', 'min'); await this._setCPU(middlePolicy0, '0', 'max'); } else { await this._setCPU(middlePolicy0, '0', 'max'); await this._setCPU(middlePolicy0, '0', 'min'); } if (Number(currentMaxPolicy4) > middlePolicy4) { await this._setCPU(middlePolicy4, '4', 'min'); return this._setCPU(middlePolicy4, '4', 'max'); } else { await this._setCPU(middlePolicy4, '4', 'max'); return this._setCPU(middlePolicy4, '4', 'min'); } } else { log.info('Set max CPU speed'); const maxPolicy0 = 1_742_000; const maxPolicy4 = 2_314_000; // set it to max speed await this._setCPU(maxPolicy0, '0', 'max'); await this._setCPU(maxPolicy0, '0', 'min'); await this._setCPU(maxPolicy4, '4', 'max'); return this._setCPU(maxPolicy4, '4', 'min'); } } async setCPUPerformancePixel2() { // MSM8998 (4x 2.35GHz, 4x 1.9GHz) // values obtained from: // /sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies // /sys/devices/system/cpu/cpufreq/policy4/scaling_available_frequencies await this.client._runAsRoot( 'echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor' ); await this.client._runAsRoot( 'echo performance > /sys/devices/system/cpu/cpufreq/policy4/scaling_governor' ); await this.client._runAsRoot( 'echo 1900800 > /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq' ); return this.client._runAsRoot( 'echo 2457600 > /sys/devices/system/cpu/cpufreq/policy4/scaling_min_freq' ); } async setGPUPerformance() { await this.client._runAsRoot('echo 0 > /sys/class/kgsl/kgsl-3d0/bus_split'); await this.client._runAsRoot( 'echo 1 > /sys/class/kgsl/kgsl-3d0/force_bus_on' ); await this.client._runAsRoot( 'echo 1 > /sys/class/kgsl/kgsl-3d0/force_rail_on' ); await this.client._runAsRoot( 'echo 1 > /sys/class/kgsl/kgsl-3d0/force_clk_on' ); await this.client._runAsRoot( 'echo 1 > /sys/class/kgsl/kgsl-3d0/force_no_nap' ); return this.client._runAsRoot( 'echo 1000000 > /sys/class/kgsl/kgsl-3d0/idle_timer' ); } async setGPUPerformanceMotoG5() { // Adreno 505 (450MHz) // values obtained from: // sys/devices/soc/1c00000.qcom,kgsl-3d0/kgsl/kgsl-3d0/max_clock_mhz const governor = await this.client._runAsRootAndGet( 'cat /sys/devices/soc/1c00000.qcom,kgsl-3d0/devfreq/1c00000.qcom,kgsl-3d0/governor' ); // Only set it if it isn't set if (governor !== 'performance') { await this.client._runAsRoot( 'echo performance > /sys/devices/soc/1c00000.qcom,kgsl-3d0/devfreq/1c00000.qcom,kgsl-3d0/governor' ); } return this.client._runAsRoot( 'echo 450 > /sys/devices/soc/1c00000.qcom,kgsl-3d0/kgsl/kgsl-3d0/min_clock_mhz' ); } async setGPUPerformancePixel2() { // Adreno 540 (710MHz) // values obtained from: // /sys/devices/soc/5000000.qcom,kgsl-3d0/kgsl/kgsl-3d0/max_clk_mhz await this.client._runAsRoot( 'echo performance > /sys/devices/soc/5000000.qcom,kgsl-3d0/devfreq/5000000.qcom,kgsl-3d0/governor' ); await this.client._runAsRoot( 'echo performance > /sys/devices/soc/soc:qcom,kgsl-busmon/devfreq/soc:qcom,kgsl-busmon/governor' ); return this.client._runAsRoot( 'echo 710 > /sys/devices/soc/5000000.qcom,kgsl-3d0/kgsl/kgsl-3d0/min_clock_mhz' ); } async setGPUPerformanceSamsungA51() { // Mali-G72 MP3 (3 @ 850 MHz) // Missing info on how to set the GPU } async start() { await this.stopServices(); await this.stopAnimations(); await this.setScheduler(); await this.setVirtualMemory(); await this.settingKernel(); await this.setGPUPerformance(); const model = await this.client._runCommandAndGet( `getprop ro.product.model` ); switch (model) { case 'Moto G (5)': { log.info('Set CPU and GPU performance settings for Moto G5'); await this.setCPUPerformanceMotoG5(); await this.setGPUPerformanceMotoG5(); break; } case 'Pixel 2': { log.info('Set CPU and GPU performance settings for Pixel 2'); await this.setCPUPerformancePixel2(); await this.setGPUPerformancePixel2(); break; } case 'SM-A515F': { // Samsung A51 await this.setCPUPerformanceSamsungA51(); await this.setGPUPerformanceSamsungA51(); break; } default: { log.info( 'No specific CPU/GPU settings for %s - you can help out by creating a PR at https://github.com/sitespeedio/browsertime for your phone', model ); } } } async stop() { await this.startServices(); return this.startAnimations(); } }