1# SPDX-License-Identifier: Apache-2.0 2# 3# Copyright (C) 2015, ARM Limited and contributors. 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); you may 6# not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17 18import re 19import os 20import logging 21 22from subprocess import Popen, PIPE 23from time import sleep 24 25from android import Screen, System, Workload 26 27class UiBench(Workload): 28 """ 29 Android UiBench workload 30 """ 31 32 # Package required by this workload 33 package = 'com.android.test.uibench' 34 35 # Instrumentation required to run tests 36 test_package = 'com.android.uibench.janktests' 37 38 # Supported tests list 39 test_ClippedListView = 'UiBenchJankTests#testClippedListView' 40 test_DialogListFling = 'UiBenchJankTests#testDialogListFling' 41 test_FadingEdgeListViewFling = 'UiBenchJankTests#testFadingEdgeListViewFling' 42 test_FullscreenOverdraw = 'UiBenchJankTests#testFullscreenOverdraw' 43 test_GLTextureView = 'UiBenchJankTests#testGLTextureView' 44 test_InflatingListViewFling = 'UiBenchJankTests#testInflatingListViewFling' 45 test_Invalidate = 'UiBenchJankTests#testInvalidate' 46 test_InvalidateTree = 'UiBenchJankTests#testInvalidateTree' 47 test_OpenNavigationDrawer = 'UiBenchJankTests#testOpenNavigationDrawer' 48 test_OpenNotificationShade = 'UiBenchJankTests#testOpenNotificationShade' 49 test_ResizeHWLayer = 'UiBenchJankTests#testResizeHWLayer' 50 test_SaveLayerAnimation = 'UiBenchJankTests#testSaveLayerAnimation' 51 test_SlowBindRecyclerViewFling = 'UiBenchJankTests#testSlowBindRecyclerViewFling' 52 test_SlowNestedRecyclerViewFling = 'UiBenchJankTests#testSlowNestedRecyclerViewFling' 53 test_SlowNestedRecyclerViewInitialFling = 'UiBenchJankTests#testSlowNestedRecyclerViewInitialFling' 54 test_TrivialAnimation = 'UiBenchJankTests#testTrivialAnimation' 55 test_TrivialListViewFling = 'UiBenchJankTests#testTrivialListViewFling' 56 test_TrivialRecyclerListViewFling = 'UiBenchJankTests#testTrivialRecyclerListViewFling' 57 test_BitmapUploadJank = 'UiBenchRenderingJankTests#testBitmapUploadJank' 58 test_ShadowGridListFling = 'UiBenchRenderingJankTests#testShadowGridListFling' 59 test_EditTextTyping = 'UiBenchTextJankTests#testEditTextTyping' 60 test_LayoutCacheHighHitrateFling = 'UiBenchTextJankTests#testLayoutCacheHighHitrateFling' 61 test_LayoutCacheLowHitrateFling = 'UiBenchTextJankTests#testLayoutCacheLowHitrateFling' 62 test_ActivityTransitionsAnimation = 'UiBenchTransitionsJankTests#testActivityTransitionsAnimation' 63 test_WebViewFling = 'UiBenchWebView#testWebViewFling' 64 65 def __init__(self, test_env): 66 super(UiBench, self).__init__(test_env) 67 self._log = logging.getLogger('UiBench') 68 self._log.debug('Workload created') 69 70 # Set of output data reported by UiBench 71 self.db_file = None 72 73 def run(self, out_dir, test_name, duration_s, collect=''): 74 """ 75 Run single UiBench workload. 76 77 :param out_dir: Path to experiment directory where to store results. 78 :type out_dir: str 79 80 :param test_name: Name of the test to run 81 :type test_name: str 82 83 :param duration_s: Run benchmak for this required number of seconds 84 :type duration_s: int 85 86 :param collect: Specifies what to collect. Possible values: 87 - 'energy' 88 - 'systrace' 89 - 'ftrace' 90 - any combination of the above 91 :type collect: list(str) 92 """ 93 94 activity = '.' + test_name 95 96 # Keep track of mandatory parameters 97 self.out_dir = out_dir 98 self.collect = collect 99 100 # Unlock device screen (assume no password required) 101 Screen.unlock(self._target) 102 103 # Close and clear application 104 System.force_stop(self._target, self.package, clear=True) 105 106 # Set airplane mode 107 System.set_airplane_mode(self._target, on=True) 108 109 # Set min brightness 110 Screen.set_brightness(self._target, auto=False, percent=0) 111 112 # Start the main view of the app which must be running 113 # to reset the frame statistics. 114 System.monkey(self._target, self.package) 115 116 # Force screen in PORTRAIT mode 117 Screen.set_orientation(self._target, portrait=True) 118 119 # Reset frame statistics 120 System.gfxinfo_reset(self._target, self.package) 121 sleep(1) 122 123 # Clear logcat 124 os.system(self._adb('logcat -c')); 125 126 # Regexps for benchmark synchronization 127 start_logline = r'TestRunner: started' 128 UIBENCH_BENCHMARK_START_RE = re.compile(start_logline) 129 self._log.debug("START string [%s]", start_logline) 130 131 # Parse logcat output lines 132 logcat_cmd = self._adb( 133 'logcat TestRunner:* System.out:I *:S BENCH:*'\ 134 .format(self._target.adb_name)) 135 self._log.info("%s", logcat_cmd) 136 137 # Run benchmark with a lot of iterations to avoid finishing before duration_s elapses 138 command = "nohup am instrument -e iterations 1000000 -e class {}{} -w {}".format( 139 self.test_package, activity, self.test_package) 140 self._target.background(command) 141 142 logcat = Popen(logcat_cmd, shell=True, stdout=PIPE) 143 while True: 144 145 # read next logcat line (up to max 1024 chars) 146 message = logcat.stdout.readline(1024) 147 148 # Benchmark start trigger 149 match = UIBENCH_BENCHMARK_START_RE.search(message) 150 if match: 151 self.tracingStart() 152 self._log.debug("Benchmark started!") 153 break 154 155 # Run the workload for the required time 156 self._log.info('Benchmark [%s] started, waiting %d [s]', 157 activity, duration_s) 158 sleep(duration_s) 159 160 self._log.debug("Benchmark done!") 161 self.tracingStop() 162 163 # Get frame stats 164 self.db_file = os.path.join(out_dir, "framestats.txt") 165 System.gfxinfo_get(self._target, self.package, self.db_file) 166 167 # Close and clear application 168 System.force_stop(self._target, self.package, clear=True) 169 170 # Go back to home screen 171 System.home(self._target) 172 173 # Switch back to original settings 174 Screen.set_orientation(self._target, auto=True) 175 System.set_airplane_mode(self._target, on=False) 176 Screen.set_brightness(self._target, auto=True) 177 178# vim :set tabstop=4 shiftwidth=4 expandtab 179