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 |