• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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