Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(356)

Unified Diff: tools/telemetry/telemetry/core/platform/android_platform_backend.py

Issue 656383002: [Telemetry] Move some implementations from android_browser_backend_to android_platform_backend (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/telemetry/telemetry/core/backends/chrome/android_browser_backend.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 49ee2d1e73b3a52b2ea41eae0049f5ac3f745166..1acbe1675c301a12cda33ddd59d95f6f2c03ae44 100644
--- a/tools/telemetry/telemetry/core/platform/android_platform_backend.py
+++ b/tools/telemetry/telemetry/core/platform/android_platform_backend.py
@@ -3,7 +3,11 @@
# found in the LICENSE file.
import logging
+import os
+import re
+import subprocess
import tempfile
+import time
from telemetry import decorators
from telemetry.core import exceptions
@@ -23,6 +27,7 @@ from telemetry.core.platform.profiler import android_prebuilt_profiler_helper
# 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
@@ -69,6 +74,8 @@ class AndroidPlatformBackend(
self._video_recorder = None
self._installed_applications = None
+ self._wpr_ca_cert_path = None
+
@classmethod
def SupportsDevice(cls, device):
return isinstance(device, android_device.AndroidDevice)
@@ -184,10 +191,6 @@ class AndroidPlatformBackend(
raise exceptions.ProcessGoneException()
return ps[0][1]
- @decorators.Cache
- def GetArchName(self):
- return self._device.GetABI()
-
def GetOSName(self):
return 'android'
@@ -210,10 +213,24 @@ class AndroidPlatformBackend(
def StopApplication(self, application):
"""Stop the given |application|.
- Args:
- application: The full package name string of the application to launch.
+
+ Args:
+ application: The full package name string of the application to stop.
"""
- self._adb.device().ForceStop(application)
+ 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
def LaunchApplication(
self, application, parameters=None, elevate_privilege=False):
@@ -336,3 +353,181 @@ class AndroidPlatformBackend(
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 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
« no previous file with comments | « tools/telemetry/telemetry/core/backends/chrome/android_browser_backend.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698