1e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# SPDX-License-Identifier: Apache-2.0 2e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# 3e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# Copyright (C) 2017, Arm Limited and contributors. 4e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# 5e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# Licensed under the Apache License, Version 2.0 (the "License"); you may 6e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# not use this file except in compliance with the License. 7e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# You may obtain a copy of the License at 8e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# 9e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# http://www.apache.org/licenses/LICENSE-2.0 10e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# 11e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# Unless required by applicable law or agreed to in writing, software 12e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# See the License for the specific language governing permissions and 15e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# limitations under the License. 16e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# 17e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 18e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneiderimport re 19e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneiderimport os 20e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneiderimport logging 21e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 22e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneiderfrom subprocess import Popen, PIPE 23e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 24e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneiderfrom time import sleep 25e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 26e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneiderfrom android import Screen, System, Workload 27e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneiderfrom devlib.utils.android import grant_app_permissions 28e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 29e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# Regexps for benchmark synchronization 30e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 31e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin SchneiderREGEXPS = { 32e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 'start' : '.*Displayed com.google.android.exoplayer2.demo/.PlayerActivity', 33e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 'duration' : '.*period \[(?P<duration>[0-9]+.*)\]', 34e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 'end' : '.*state \[.+, .+, E\]' 35e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider} 36e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 37e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneiderclass ExoPlayer(Workload): 38e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider """ 39e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider Android ExoPlayer workload 40e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 41e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider Exoplayer sources: https://github.com/google/ExoPlayer 42e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 43e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider The 'demo' application is used by this workload. 44e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider It can easily be built by loading the ExoPlayer sources 45e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider into Android Studio 46e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 47e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider Expected apk is 'demo-noExtensions-debug.apk' 48e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 49e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider Version r2.4.0 (d979469) is known to work 50e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider """ 51e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 52e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Package required by this workload 53e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider package = 'com.google.android.exoplayer2.demo' 54e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider action = 'com.google.android.exoplayer.demo.action.VIEW' 55e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 56e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider def __init__(self, test_env): 57e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider super(ExoPlayer, self).__init__(test_env) 58e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self._log = logging.getLogger('ExoPlayer') 59e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 60e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider def _play(self): 61e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 62e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Grant app all permissions 63e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider grant_app_permissions(self._target, self.package) 64e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 65e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Handle media file location 66e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider if not self.from_device: 67e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider remote_file = self._target.path.join( 68e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self._target.working_directory, 69e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider os.path.basename(self.media_file) 70e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider ) 71e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 72e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self._log.info('Pushing media file to device...') 73e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self._target.push( 74e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self.media_file, 75e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider remote_file, 76e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider timeout = 60 77e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider ) 78e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self._log.info('Media file transfer complete') 79e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider else: 80e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider remote_file = self.media_file 81e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 82e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Prepare logcat monitor 83e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider monitor = self._target.get_logcat_monitor(REGEXPS.values()) 84e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider monitor.start() 85e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 86e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Play media file 87e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider play_cmd = 'am start -a "{}" -d "file://{}"'\ 88e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider .format(self.action, remote_file) 89e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self._log.info(play_cmd) 90e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self._target.execute(play_cmd) 91e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 92e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider monitor.wait_for(REGEXPS['start']) 93e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self.tracingStart() 94e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self._log.info('Playing media file') 95e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 96e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider line = monitor.wait_for(REGEXPS['duration'])[0] 97e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider media_duration_s = int(round(float(re.search(REGEXPS['duration'], line) 98e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider .group('duration')))) 99e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 100e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self._log.info('Media duration is {}'.format(media_duration_s)) 101e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 102e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider if self.play_duration_s and self.play_duration_s < media_duration_s: 103e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self._log.info('Waiting {} seconds before ending playback' 104e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider .format(self.play_duration_s)) 105e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider sleep(self.play_duration_s) 106e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider else: 107e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self._log.info('Waiting for playback completion ({} seconds)' 108e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider .format(media_duration_s)) 109e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider monitor.wait_for(REGEXPS['end'], timeout = media_duration_s + 30) 110e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 111e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self.tracingStop() 112e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider monitor.stop() 113e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self._log.info('Media file playback completed') 114e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 115e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Remove file if it was pushed 116e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider if not self.from_device: 117e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self._target.remove(remote_file) 118e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 119e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider def run(self, out_dir, collect, media_file, from_device=False, play_duration_s=None): 120e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider """ 121e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider Run Exoplayer workload 122e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 123e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider :param out_dir: Path to experiment directory on the host 124e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider where to store results. 125e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider :type out_dir: str 126e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 127e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider :param collect: Specifies what to collect. Possible values: 128e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider - 'energy' 129e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider - 'systrace' 130e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider - 'ftrace' 131e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider - any combination of the above as a single space-separated string. 132e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider :type collect: list(str) 133e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 134e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider :param media_file: Filepath of the media to play 135e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider Path on device if 'from_device' is True 136e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider Path on host if 'from_device' is False (default) 137e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider :type media_file: str 138e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 139e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider :param from_device: Whether file to play is already on the device 140e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider :type from_device: bool 141e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 142e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider :param play_duration_s: If set, maximum duration (seconds) of the media playback 143e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider If not set, media will play to completion 144e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider :type play_duration_s: int 145e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider """ 146e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 147e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Keep track of mandatory parameters 148e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self.out_dir = out_dir 149e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self.collect = collect 150e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self.media_file = media_file 151e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self.from_device = from_device 152e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self.play_duration_s = play_duration_s 153e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 154e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Check media file exists 155e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider if from_device and not self._target.file_exists(self.media_file): 156e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider raise RuntimeError('Cannot find "{}" on target'.format(self.media_file)) 157e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider elif not from_device and not os.path.isfile(self.media_file): 158e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider raise RuntimeError('Cannot find "{}" on host'.format(self.media_file)) 159e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 160e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Unlock device screen (assume no password required) 161e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider Screen.unlock(self._target) 162e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 163e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Close and clear application 164e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider System.force_stop(self._target, self.package, clear=True) 165e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 166e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Enable airplane mode 167e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider System.set_airplane_mode(self._target, on=True) 168e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 169e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Set min brightness 170e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider Screen.set_brightness(self._target, auto=False, percent=0) 171e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 172e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Force screen in PORTRAIT mode 173e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider Screen.set_orientation(self._target, portrait=True) 174e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 175e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Launch Exoplayer benchmark 176e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider self._play() 177e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 178e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Go back to home screen 179e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider System.home(self._target) 180e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 181e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Set orientation back to auto 182e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider Screen.set_orientation(self._target, auto=True) 183e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 184e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Set brightness back to auto 185e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider Screen.set_brightness(self._target, auto=True) 186e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 187e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Turn off airplane mode 188e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider System.set_airplane_mode(self._target, on=False) 189e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 190e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider # Close and clear application 191e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider System.force_stop(self._target, self.package, clear=True) 192e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider 193e30f1aeedbfa5ba20a438c12b1af7078ac64b776Valentin Schneider# vim :set tabstop=4 shiftwidth=4 expandtab 194