blob: 6aea799daec9f24fed6484570f38422059b5650e [file] [log] [blame]
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2017, ARM Limited, Google and contributors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import re
import os
import logging
from subprocess import Popen, PIPE
from time import sleep
from android import Screen, System, Workload
import pandas as pd
class SystemUi(Workload):
"""
Android SystemUi jank test workload
"""
# Packages required by this workload
packages = [
Workload.WorkloadPackage("android.platform.systemui.tests.jank",
"data/app/UbSystemUiJankTests/UbSystemUiJankTests.apk",
"platform_testing/tests/jank/UbSystemUiJankTests")
]
# Instrumentation required to run tests
test_package = packages[0].package_name
test_list = \
["LauncherJankTests#testOpenAllAppsContainer",
"LauncherJankTests#testAllAppsContainerSwipe",
"LauncherJankTests#testHomeScreenSwipe",
"LauncherJankTests#testWidgetsContainerFling",
"SettingsJankTests#testSettingsFling",
"SystemUiJankTests#testRecentAppsFling",
"SystemUiJankTests#testRecentAppsDismiss",
"SystemUiJankTests#testNotificationListPull",
"SystemUiJankTests#testNotificationListPull_manyNotifications",
"SystemUiJankTests#testQuickSettingsPull",
"SystemUiJankTests#testUnlock",
"SystemUiJankTests#testExpandGroup",
"SystemUiJankTests#testClearAll",
"SystemUiJankTests#testChangeBrightness",
"SystemUiJankTests#testNotificationAppear",
"SystemUiJankTests#testCameraFromLockscreen",
"SystemUiJankTests#testAmbientWakeUp",
"SystemUiJankTests#testGoToFullShade",
"SystemUiJankTests#testInlineReply",
"SystemUiJankTests#testPinAppearance",
"SystemUiJankTests#testLaunchSettings"]
def __init__(self, test_env):
super(SystemUi, self).__init__(test_env)
self._log = logging.getLogger('SystemUi')
self._log.debug('Workload created')
# Set of output data reported by SystemUi
self.db_file = None
def get_test_list(self):
return SystemUi.test_list
def run(self, out_dir, test_name, iterations, collect=''):
"""
Run single SystemUi jank test workload.
Performance statistics are stored in self.results, and can be retrieved after
the fact by calling SystemUi.get_results()
:param out_dir: Path to experiment directory where to store results.
:type out_dir: str
:param test_name: Name of the test to run
:type test_name: str
:param iterations: Run benchmark for this required number of iterations
:type iterations: int
:param collect: Specifies what to collect. Possible values:
- 'systrace'
- 'ftrace'
- 'gfxinfo'
- 'surfaceflinger'
- any combination of the above
:type collect: list(str)
"""
if 'energy' in collect:
raise ValueError('SystemUi workload does not support energy data collection')
activity = '.' + test_name
# Keep track of mandatory parameters
self.out_dir = out_dir
self.collect = collect
# Filter out test overhead
filter_prop = System.get_boolean_property(self._target, 'debug.hwui.filter_test_overhead')
if not filter_prop:
System.set_property(self._target, 'debug.hwui.filter_test_overhead', 'true', restart=True)
# Unlock device screen (assume no password required)
Screen.unlock(self._target)
# Set airplane mode
System.set_airplane_mode(self._target, on=True)
# Set min brightness
Screen.set_brightness(self._target, auto=False, percent=0)
# Force screen in PORTRAIT mode
Screen.set_orientation(self._target, portrait=True)
# Delete old test results
self._target.remove('/sdcard/results.log')
# Clear logcat
os.system(self._adb('logcat -c'));
# Regexps for benchmark synchronization
start_logline = r'TestRunner: started'
SYSTEMUI_BENCHMARK_START_RE = re.compile(start_logline)
self._log.debug("START string [%s]", start_logline)
finish_logline = r'TestRunner: finished'
SYSTEMUI_BENCHMARK_FINISH_RE = re.compile(finish_logline)
self._log.debug("FINISH string [%s]", finish_logline)
# Parse logcat output lines
logcat_cmd = self._adb(
'logcat TestRunner:* System.out:I *:S BENCH:*'\
.format(self._target.adb_name))
self._log.info("%s", logcat_cmd)
command = "nohup am instrument -e iterations {} -e class {}{} -w {}".format(
iterations, self.test_package, activity, self.test_package)
print "command: {}".format(command)
self._target.background(command)
logcat = Popen(logcat_cmd, shell=True, stdout=PIPE)
while True:
# read next logcat line (up to max 1024 chars)
message = logcat.stdout.readline(1024)
# Benchmark start trigger
match = SYSTEMUI_BENCHMARK_START_RE.search(message)
if match:
self.tracingStart()
self._log.debug("Benchmark started!")
match = SYSTEMUI_BENCHMARK_FINISH_RE.search(message)
if match:
self.tracingStop()
self._log.debug("Benchmark finished!")
break
sleep(5)
self._target.pull('/sdcard/results.log', os.path.join(out_dir, 'results.log'))
self._target.remove('/sdcard/results.log')
self.results = self.get_results(out_dir)
# Go back to home screen
System.home(self._target)
# Switch back to original settings
Screen.set_orientation(self._target, auto=True)
System.set_airplane_mode(self._target, on=False)
Screen.set_brightness(self._target, auto=True)
@staticmethod
def get_results(out_dir):
"""
Parse SystemUi test output log and return a pandas dataframe of test results.
:param out_dir: Output directory for a run of the SystemUi workload.
:type out_dir: str
"""
path = os.path.join(out_dir, 'results.log')
with open(path, "r") as f:
lines = f.readlines()
data = {}
for line in lines:
key, val = str.split(line)
if key == 'Result':
key = 'test-name'
elif key.startswith('gfx-'):
key = key[4:]
val = float(val)
else:
raise ValueError('Unrecognized line in results file')
data[key] = val
columns, values = zip(*((k,v) for k,v in data.iteritems()))
return pd.DataFrame([values], columns=columns)