| Index: tools/telemetry/telemetry/core/platform/android_platform_backend.py
|
| diff --git a/tools/telemetry/telemetry/core/platform/android_platform_backend.py b/tools/telemetry/telemetry/core/platform/android_platform_backend.py
|
| index f1c2b5a8bdfc349ff694abde310c652cec8742d2..49ee2d1e73b3a52b2ea41eae0049f5ac3f745166 100644
|
| --- a/tools/telemetry/telemetry/core/platform/android_platform_backend.py
|
| +++ b/tools/telemetry/telemetry/core/platform/android_platform_backend.py
|
| @@ -3,12 +3,7 @@
|
| # found in the LICENSE file.
|
|
|
| import logging
|
| -import os
|
| -import re
|
| -import shutil
|
| -import subprocess
|
| import tempfile
|
| -import time
|
|
|
| from telemetry import decorators
|
| from telemetry.core import exceptions
|
| @@ -24,17 +19,10 @@
|
| from telemetry.core.platform.power_monitor import monsoon_power_monitor
|
| from telemetry.core.platform.power_monitor import power_monitor_controller
|
| from telemetry.core.platform.profiler import android_prebuilt_profiler_helper
|
| -from telemetry.util import exception_formatter
|
| -
|
| -util.AddDirToPythonPath(util.GetChromiumSrcDir(),
|
| - 'third_party', 'webpagereplay')
|
| -import adb_install_cert # pylint: disable=F0401
|
| -import certutils # pylint: disable=F0401
|
|
|
| # Get build/android scripts into our path.
|
| util.AddDirToPythonPath(util.GetChromiumSrcDir(), 'build', 'android')
|
| from pylib import screenshot # pylint: disable=F0401
|
| -from pylib.device import device_errors # pylint: disable=F0401
|
| from pylib.perf import cache_control # pylint: disable=F0401
|
| from pylib.perf import perf_control # pylint: disable=F0401
|
| from pylib.perf import thermal_throttle # pylint: disable=F0401
|
| @@ -81,9 +69,6 @@
|
| self._video_recorder = None
|
| self._installed_applications = None
|
|
|
| - self._wpr_ca_cert_path = None
|
| - self._cert_util = None
|
| -
|
| @classmethod
|
| def SupportsDevice(cls, device):
|
| return isinstance(device, android_device.AndroidDevice)
|
| @@ -199,6 +184,10 @@
|
| raise exceptions.ProcessGoneException()
|
| return ps[0][1]
|
|
|
| + @decorators.Cache
|
| + def GetArchName(self):
|
| + return self._device.GetABI()
|
| +
|
| def GetOSName(self):
|
| return 'android'
|
|
|
| @@ -221,24 +210,10 @@
|
|
|
| def StopApplication(self, application):
|
| """Stop the given |application|.
|
| -
|
| - Args:
|
| - application: The full package name string of the application to stop.
|
| + Args:
|
| + application: The full package name string of the application to launch.
|
| """
|
| - self._device.ForceStop(application)
|
| -
|
| - def KillApplication(self, application):
|
| - """Kill the given application.
|
| -
|
| - Args:
|
| - application: The full package name string of the application to kill.
|
| - """
|
| - # We use KillAll rather than ForceStop for efficiency reasons.
|
| - try:
|
| - self._adb.device().KillAll(application, retries=0)
|
| - time.sleep(3)
|
| - except device_errors.CommandFailedError:
|
| - pass
|
| + self._adb.device().ForceStop(application)
|
|
|
| def LaunchApplication(
|
| self, application, parameters=None, elevate_privilege=False):
|
| @@ -361,223 +336,3 @@
|
| cstates['C0'] -= int(times[i])
|
| sample_stats[cpu] = cstates
|
| return sample_stats
|
| -
|
| - def SetRelaxSslCheck(self, value):
|
| - old_flag = self._device.GetProp('socket.relaxsslcheck')
|
| - self._device.SetProp('socket.relaxsslcheck', value)
|
| - return old_flag
|
| -
|
| - def ForwardHostToDevice(self, host_port, device_port):
|
| - self._adb.Forward('tcp:%d' % host_port, device_port)
|
| -
|
| - def DismissCrashDialogIfNeeded(self):
|
| - """Dismiss any error dialogs.
|
| -
|
| - Limit the number in case we have an error loop or we are failing to dismiss.
|
| - """
|
| - for _ in xrange(10):
|
| - if not self._device.old_interface.DismissCrashDialogIfNeeded():
|
| - break
|
| -
|
| - def IsAppRunning(self, process_name):
|
| - """Determine if the given process is running.
|
| -
|
| - Args:
|
| - process_name: The full package name string of the process.
|
| - """
|
| - pids = self._adb.ExtractPid(process_name)
|
| - return len(pids) != 0
|
| -
|
| - @property
|
| - def wpr_ca_cert_path(self):
|
| - """Path to root certificate installed on browser (or None).
|
| -
|
| - If this is set, web page replay will use it to sign HTTPS responses.
|
| - """
|
| - if self._wpr_ca_cert_path:
|
| - assert os.path.isfile(self._wpr_ca_cert_path)
|
| - return self._wpr_ca_cert_path
|
| -
|
| - def InstallTestCa(self):
|
| - """Install a randomly generated root CA on the android device.
|
| -
|
| - This allows transparent HTTPS testing with WPR server without need
|
| - to tweak application network stack.
|
| - """
|
| - if certutils.openssl_import_error:
|
| - logging.warn(
|
| - 'The OpenSSL module is unavailable. '
|
| - 'Will fallback to ignoring certificate errors.')
|
| - return
|
| -
|
| - try:
|
| - self._wpr_ca_cert_path = os.path.join(tempfile.mkdtemp(), 'testca.pem')
|
| - certutils.write_dummy_ca_cert(*certutils.generate_dummy_ca_cert(),
|
| - cert_path=self._wpr_ca_cert_path)
|
| - self._cert_util = adb_install_cert.AndroidCertInstaller(
|
| - self._adb.device_serial(), None, self._wpr_ca_cert_path)
|
| - logging.info('Installing test certificate authority on device.')
|
| - self._cert_util.install_cert(True)
|
| - except Exception:
|
| - # Fallback to ignoring certificate errors.
|
| - self._RemoveLocalTestCa()
|
| - exception_formatter.PrintFormattedException(
|
| - msg=('Unable to install test certificate authority on device. '
|
| - 'Will fallback to ignoring certificate errors.'))
|
| -
|
| - def RemoveTestCa(self):
|
| - """Remove root CA installed by previous call to InstallTestCa()."""
|
| - if not self._cert_util:
|
| - return
|
| - self._cert_util.remove_cert()
|
| - self._RemoveLocalTestCa()
|
| -
|
| - def _RemoveLocalTestCa(self):
|
| - """Remove root CA previously generated by InstllTestCa() from host machine.
|
| - """
|
| - temp_dir = os.path.dirname(self._wpr_ca_cert_path)
|
| - if os.path.exists(temp_dir):
|
| - shutil.rmtree(os.path.dirname(self._wpr_ca_cert_path))
|
| - self._wpr_ca_cert_path = None
|
| -
|
| - def PushProfile(self, package, new_profile_dir):
|
| - """Replace application profile with files found on host machine.
|
| -
|
| - Pushing the profile is slow, so we don't want to do it every time.
|
| - Avoid this by pushing to a safe location using PushChangedFiles, and
|
| - then copying into the correct location on each test run.
|
| -
|
| - Args:
|
| - package: The full package name string of the application for which the
|
| - profile is to be updated.
|
| - new_profile_dir: Location where profile to be pushed is stored on the
|
| - host machine.
|
| - """
|
| - (profile_parent, profile_base) = os.path.split(new_profile_dir)
|
| - # If the path ends with a '/' python split will return an empty string for
|
| - # the base name; so we now need to get the base name from the directory.
|
| - if not profile_base:
|
| - profile_base = os.path.basename(profile_parent)
|
| -
|
| - saved_profile_location = '/sdcard/profile/%s' % profile_base
|
| - self._device.PushChangedFiles(new_profile_dir, saved_profile_location)
|
| -
|
| - profile_dir = self._GetProfileDir(package)
|
| - self._device.old_interface.EfficientDeviceDirectoryCopy(
|
| - saved_profile_location, profile_dir)
|
| - dumpsys = self._device.RunShellCommand('dumpsys package %s' % package)
|
| - id_line = next(line for line in dumpsys if 'userId=' in line)
|
| - uid = re.search(r'\d+', id_line).group()
|
| - files = self._device.RunShellCommand(
|
| - 'ls "%s"' % profile_dir, as_root=True)
|
| - files.remove('lib')
|
| - paths = ['%s%s' % (profile_dir, f) for f in files]
|
| - for path in paths:
|
| - extended_path = '%s %s/* %s/*/* %s/*/*/*' % (path, path, path, path)
|
| - self._device.RunShellCommand(
|
| - 'chown %s.%s %s' % (uid, uid, extended_path))
|
| -
|
| - def RemoveProfile(self, package, ignore_list):
|
| - """Delete application profile on device.
|
| -
|
| - Args:
|
| - package: The full package name string of the application for which the
|
| - profile is to be deleted.
|
| - ignore_list: List of files to keep.
|
| - """
|
| - profile_dir = self._GetProfileDir(package)
|
| - files = self._device.RunShellCommand(
|
| - 'ls "%s"' % profile_dir, as_root=True)
|
| - paths = ['"%s%s"' % (profile_dir, f) for f in files
|
| - if f not in ignore_list]
|
| - self._device.RunShellCommand('rm -r %s' % ' '.join(paths), as_root=True)
|
| -
|
| - def PullProfile(self, package, output_profile_path):
|
| - """Copy application profile from device to host machine.
|
| -
|
| - Args:
|
| - package: The full package name string of the application for which the
|
| - profile is to be copied.
|
| - output_profile_dir: Location where profile to be stored on host machine.
|
| - """
|
| - profile_dir = self._GetProfileDir(package)
|
| - logging.info("Pulling profile directory from device: '%s'->'%s'.",
|
| - self._ProfileDir(package), output_profile_path)
|
| - # To minimize bandwidth it might be good to look at whether all the data
|
| - # pulled down is really needed e.g. .pak files.
|
| - if not os.path.exists(output_profile_path):
|
| - os.makedirs(output_profile_path)
|
| - files = self._device.RunShellCommand('ls "%s"' % profile_dir)
|
| - for f in files:
|
| - # Don't pull lib, since it is created by the installer.
|
| - if f != 'lib':
|
| - source = '%s%s' % (profile_dir, f)
|
| - dest = os.path.join(output_profile_path, f)
|
| - # self._adb.Pull(source, dest) doesn't work because its timeout
|
| - # is fixed in android's adb_interface at 60 seconds, which may
|
| - # be too short to pull the cache.
|
| - cmd = 'pull %s %s' % (source, dest)
|
| - self._device.old_interface.Adb().SendCommand(cmd, timeout_time=240)
|
| -
|
| - def _GetProfileDir(self, package):
|
| - """Returns the on-device location where the application profile is stored
|
| - based on Android convention.
|
| -
|
| - Args:
|
| - package: The full package name string of the application.
|
| - """
|
| - return '/data/data/%s/' % package
|
| -
|
| - def SetDebugApp(self, package):
|
| - """Set application to debugging.
|
| -
|
| - Args:
|
| - package: The full package name string of the application.
|
| - """
|
| - if self._adb.IsUserBuild():
|
| - logging.debug('User build device, setting debug app')
|
| - self._device.RunShellCommand('am set-debug-app --persistent %s' % package)
|
| -
|
| - def GetStandardOutput(self, number_of_lines=500):
|
| - """Returns most recent lines of logcat dump.
|
| -
|
| - Args:
|
| - number_of_lines: Number of lines of log to return.
|
| - """
|
| - return '\n'.join(self.adb.device().RunShellCommand(
|
| - 'logcat -d -t %d' % number_of_lines))
|
| -
|
| - def GetStackTrace(self, target_arch):
|
| - """Returns stack trace.
|
| -
|
| - The stack trace consists of raw logcat dump, logcat dump with symbols,
|
| - and stack info from tomstone files.
|
| -
|
| - Args:
|
| - target_arch: String specifying device architecture (eg. arm, arm64, mips,
|
| - x86, x86_64)
|
| - """
|
| - def Decorate(title, content):
|
| - return "%s\n%s\n%s\n" % (title, content, '*' * 80)
|
| - # Get the last lines of logcat (large enough to contain stacktrace)
|
| - logcat = self.GetStandardOutput()
|
| - ret = Decorate('Logcat', logcat)
|
| - stack = os.path.join(util.GetChromiumSrcDir(), 'third_party',
|
| - 'android_platform', 'development', 'scripts', 'stack')
|
| - # Try to symbolize logcat.
|
| - if os.path.exists(stack):
|
| - cmd = [stack]
|
| - if target_arch:
|
| - cmd.append('--arch=%s' % target_arch)
|
| - p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
| - ret += Decorate('Stack from Logcat', p.communicate(input=logcat)[0])
|
| -
|
| - # Try to get tombstones.
|
| - tombstones = os.path.join(util.GetChromiumSrcDir(), 'build', 'android',
|
| - 'tombstones.py')
|
| - if os.path.exists(tombstones):
|
| - ret += Decorate('Tombstones',
|
| - subprocess.Popen([tombstones, '-w', '--device',
|
| - self._adb.device_serial()],
|
| - stdout=subprocess.PIPE).communicate()[0])
|
| - return ret
|
|
|