android_browser_backend.py revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
1424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import logging 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import os 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import re 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import subprocess 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import sys 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import time 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import exceptions 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from telemetry.core import forwarders 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochfrom telemetry.core import util 15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)from telemetry.core.backends import adb_commands 16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)from telemetry.core.backends import browser_backend 17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)from telemetry.core.backends.chrome import chrome_browser_backend 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from telemetry.core.forwarders import android_forwarder 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 21a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)class AndroidBrowserBackendSettings(object): 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def __init__(self, adb, activity, cmdline_file, package, pseudo_exec_name, 241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) supports_tab_control): 25a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) self.adb = adb 26a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) self.activity = activity 27a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) self.cmdline_file = cmdline_file 28a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) self.package = package 29a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) self.pseudo_exec_name = pseudo_exec_name 301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.supports_tab_control = supports_tab_control 31a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 32a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) def GetDevtoolsRemotePort(self): 33a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) raise NotImplementedError() 34a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 35a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) def RemoveProfile(self): 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) files = self.adb.RunShellCommandWithSU('ls "%s"' % self.profile_dir) 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # Don't delete lib, since it is created by the installer. 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) paths = ['"%s/%s"' % (self.profile_dir, f) for f in files if f != 'lib'] 39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) self.adb.RunShellCommandWithSU('rm -r %s' % ' '.join(paths)) 40a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 41a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) def PushProfile(self, _): 42a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) logging.critical('Profiles cannot be overriden with current configuration') 43a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) sys.exit(1) 44a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 45a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) @property 46a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) def is_content_shell(self): 47a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return False 48a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 49a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) @property 50bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch def profile_dir(self): 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return '/data/data/%s/' % self.package 52a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 53a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 54a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)class ChromeBackendSettings(AndroidBrowserBackendSettings): 55a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) # Stores a default Preferences file, re-used to speed up "--page-repeat". 56a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) _default_preferences_file = None 57a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) @staticmethod 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) def _GetCommandLineFile(adb): 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if adb.IsUserBuild(): 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return '/data/local/tmp/chrome-command-line' 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) else: 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return '/data/local/chrome-command-line' 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 65a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) def __init__(self, adb, package): 66a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) super(ChromeBackendSettings, self).__init__( 67a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) adb=adb, 68a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) activity='com.google.android.apps.chrome.Main', 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cmdline_file=ChromeBackendSettings._GetCommandLineFile(adb), 70a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) package=package, 711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) pseudo_exec_name='chrome', 721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) supports_tab_control=True) 73a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 74a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) def GetDevtoolsRemotePort(self): 75a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return 'localabstract:chrome_devtools_remote' 76a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 77a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) def PushProfile(self, new_profile_dir): 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # Pushing the profile is slow, so we don't want to do it every time. 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # Avoid this by pushing to a safe location using PushIfNeeded, and 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # then copying into the correct location on each test run. 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (profile_parent, profile_base) = os.path.split(new_profile_dir) 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # If the path ends with a '/' python split will return an empty string for 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # the base name; so we now need to get the base name from the directory. 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if not profile_base: 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) profile_base = os.path.basename(profile_parent) 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) saved_profile_location = '/sdcard/profile/%s' % profile_base 895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu self.adb.device().old_interface.PushIfNeeded( 905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new_profile_dir, saved_profile_location) 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu self.adb.device().old_interface.EfficientDeviceDirectoryCopy( 935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu saved_profile_location, self.profile_dir) 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) dumpsys = self.adb.RunShellCommand('dumpsys package %s' % self.package) 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) id_line = next(line for line in dumpsys if 'userId=' in line) 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) uid = re.search('\d+', id_line).group() 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) files = self.adb.RunShellCommandWithSU('ls "%s"' % self.profile_dir) 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) files.remove('lib') 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) paths = ['%s/%s' % (self.profile_dir, f) for f in files] 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for path in paths: 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extended_path = '%s %s/* %s/*/* %s/*/*/*' % (path, path, path, path) 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.adb.RunShellCommand('chown %s.%s %s' % 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (uid, uid, extended_path)) 104a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 105a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)class ContentShellBackendSettings(AndroidBrowserBackendSettings): 106a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) def __init__(self, adb, package): 107a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) super(ContentShellBackendSettings, self).__init__( 108a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) adb=adb, 109a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) activity='org.chromium.content_shell_apk.ContentShellActivity', 110a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) cmdline_file='/data/local/tmp/content-shell-command-line', 111a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) package=package, 1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) pseudo_exec_name='content_shell', 1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) supports_tab_control=False) 114a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 115a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) def GetDevtoolsRemotePort(self): 116a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return 'localabstract:content_shell_devtools_remote' 117a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 118a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) @property 119a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) def is_content_shell(self): 120a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return True 121a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 122a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class ChromeShellBackendSettings(AndroidBrowserBackendSettings): 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) def __init__(self, adb, package): 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) super(ChromeShellBackendSettings, self).__init__( 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) adb=adb, 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) activity='org.chromium.chrome.shell.ChromeShellActivity', 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) cmdline_file='/data/local/tmp/chrome-shell-command-line', 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) package=package, 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pseudo_exec_name='chrome_shell', 1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) supports_tab_control=False) 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) def GetDevtoolsRemotePort(self): 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return 'localabstract:chrome_shell_devtools_remote' 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) @property 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) def is_content_shell(self): 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return True 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 141a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)class WebviewBackendSettings(AndroidBrowserBackendSettings): 142a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) def __init__(self, adb, package): 143a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) super(WebviewBackendSettings, self).__init__( 144a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) adb=adb, 145a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) activity='com.android.webview.chromium.shell.TelemetryActivity', 146a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) cmdline_file='/data/local/tmp/webview-command-line', 147a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) package=package, 1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) pseudo_exec_name='webview', 1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) supports_tab_control=False) 150a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 151a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) def GetDevtoolsRemotePort(self): 152a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) # The DevTools socket name for WebView depends on the activity PID's. 153a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) retries = 0 154a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) timeout = 1 155a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) pid = None 156a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) while True: 157a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) pids = self.adb.ExtractPid(self.package) 158a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (len(pids) > 0): 159a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) pid = pids[-1] 160a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) break 161a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) time.sleep(timeout) 162a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) retries += 1 163a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) timeout *= 2 164a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if retries == 4: 165a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) logging.critical('android_browser_backend: Timeout while waiting for ' 166a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 'activity %s:%s to come up', 167a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) self.package, 168a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) self.activity) 169a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) raise exceptions.BrowserGoneException('Timeout waiting for PID.') 170a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return 'localabstract:webview_devtools_remote_%s' % str(pid) 171a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 172a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class AndroidBrowserBackend(chrome_browser_backend.ChromeBrowserBackend): 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """The backend for controlling a browser instance running on Android.""" 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def __init__(self, browser_options, backend_settings, use_rndis_forwarder, 17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) output_profile_path, extensions_to_load): 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) super(AndroidBrowserBackend, self).__init__( 178a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) is_content_shell=backend_settings.is_content_shell, 17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) supports_extensions=False, browser_options=browser_options, 18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) output_profile_path=output_profile_path, 18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) extensions_to_load=extensions_to_load) 18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if len(extensions_to_load) > 0: 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise browser_backend.ExtensionsNotSupportedException( 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'Android browser does not support extensions.') 18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Initialize fields so that an explosion during init doesn't break in Close. 187a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) self._adb = backend_settings.adb 188a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) self._backend_settings = backend_settings 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._saved_cmdline = '' 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # TODO(tonyg): This is flaky because it doesn't reserve the port that it 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # allocates. Need to fix this. 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._port = adb_commands.AllocateTestServerPort() 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Kill old browser. 196a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) self._adb.CloseApplication(self._backend_settings.package) 1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if self._adb.device().old_interface.CanAccessProtectedFileContents(): 19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if self.browser_options.profile_dir: 20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) self._backend_settings.PushProfile(self.browser_options.profile_dir) 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) elif not self.browser_options.dont_override_profile: 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._backend_settings.RemoveProfile() 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._forwarder_factory = android_forwarder.AndroidForwarderFactory( 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._adb, use_rndis_forwarder) 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.browser_options.netsim: 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert use_rndis_forwarder, 'Netsim requires RNDIS forwarding.' 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.wpr_port_pairs = forwarders.PortPairs( 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) http=forwarders.PortPair(0, 80), 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) https=forwarders.PortPair(0, 443), 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dns=forwarders.PortPair(0, 53)) 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Set the debug app if needed. 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self._adb.IsUserBuild(): 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) logging.debug('User build device, setting debug app') 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._adb.RunShellCommand('am set-debug-app --persistent %s' % 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._backend_settings.package) 21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def _SetUpCommandLine(self): 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def QuoteIfNeeded(arg): 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Escape 'key=valueA valueB' to 'key="valueA valueB"' 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Already quoted values, or values without space are left untouched. 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # This is required so CommandLine.java can parse valueB correctly rather 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # than as a separate switch. 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) params = arg.split('=', 1) 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if len(params) != 2: 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return arg 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key, values = params 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ' ' not in values: 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return arg 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if values[0] in '"\'' and values[-1] == values[0]: 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return arg 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return '%s="%s"' % (key, values) 23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) args = [self._backend_settings.pseudo_exec_name] 23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) args.extend(self.GetBrowserStartupArgs()) 23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) args = ' '.join(map(QuoteIfNeeded, args)) 23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) self._SetCommandLineFile(args) 24058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def _SetCommandLineFile(self, file_contents): 242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) logging.debug('Using command line: ' + file_contents) 24358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def IsProtectedFile(name): 2445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if self._adb.device().old_interface.FileExistsOnDevice(name): 2455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return not self._adb.device().old_interface.IsFileWritableOnDevice(name) 24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) else: 24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) parent_name = os.path.dirname(name) 24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if parent_name != '': 24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return IsProtectedFile(parent_name) 25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) else: 25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return True 25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if IsProtectedFile(self._backend_settings.cmdline_file): 2545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if not self._adb.device().old_interface.CanAccessProtectedFileContents(): 25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) logging.critical('Cannot set Chrome command line. ' 25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 'Fix this by flashing to a userdebug build.') 25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) sys.exit(1) 2585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu self._saved_cmdline = ''.join( 2595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu self._adb.device().old_interface.GetProtectedFileContents( 2605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu self._backend_settings.cmdline_file) 2615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu or []) 2625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu self._adb.device().old_interface.SetProtectedFileContents( 26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) self._backend_settings.cmdline_file, file_contents) 26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) else: 2655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu self._saved_cmdline = ''.join( 2665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu self._adb.device().old_interface.GetFileContents( 2675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu self._backend_settings.cmdline_file) 2685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu or []) 2695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu self._adb.device().old_interface.SetFileContents( 2705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu self._backend_settings.cmdline_file, file_contents) 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) def Start(self): 273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._SetUpCommandLine() 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._adb.RunShellCommand('logcat -c') 2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if self.browser_options.startup_url: 2761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) url = self.browser_options.startup_url 277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) elif self.browser_options.profile_dir: 278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) url = None 2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) else: 280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # If we have no existing tabs start with a blank page since default 281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # startup with the NTP can lead to race conditions with Telemetry 2821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) url = 'about:blank' 2835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu self._adb.device().old_interface.DismissCrashDialogIfNeeded() 284a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) self._adb.StartActivity(self._backend_settings.package, 285a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) self._backend_settings.activity, 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) True, 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) None, 28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) None, 2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) url) 290a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 291a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) self._adb.Forward('tcp:%d' % self._port, 292a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) self._backend_settings.GetDevtoolsRemotePort()) 293a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) try: 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._WaitForBrowserToComeUp() 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._PostBrowserStartupInitialization() 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) except exceptions.BrowserGoneException: 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) logging.critical('Failed to connect to browser.') 2995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if not self._adb.device().old_interface.CanAccessProtectedFileContents(): 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) logging.critical( 3012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 'Resolve this by either: ' 3022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch '(1) Flashing to a userdebug build OR ' 3032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch '(2) Manually enabling web debugging in Chrome at ' 3042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 'Settings > Developer tools > Enable USB Web debugging.') 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sys.exit(1) 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) except: 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) import traceback 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) traceback.print_exc() 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.Close() 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise 3110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) finally: 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Restore the saved command line if it appears to have come from a user. 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # If it appears to be a Telemetry created command line, then don't restore 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # it. This is to prevent a common bug where --host-resolver-rules borks 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # people's browsers if something goes wrong with Telemetry. 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._SetCommandLineFile( 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._saved_cmdline 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if '--host-resolver-rules' not in self._saved_cmdline else '') 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def GetBrowserStartupArgs(self): 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args = super(AndroidBrowserBackend, self).GetBrowserStartupArgs() 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.forwarder_factory.does_forwarder_override_dns: 32358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) args = [arg for arg in args 32458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if not arg.startswith('--host-resolver-rules')] 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.append('--enable-remote-debugging') 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.append('--disable-fre') 327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) args.append('--disable-external-intent-requests') 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return args 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @property 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def forwarder_factory(self): 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self._forwarder_factory 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) @property 33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) def adb(self): 33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return self._adb 33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) @property 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def pid(self): 34068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pids = self._adb.ExtractPid(self._backend_settings.package) 34168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if not pids: 34268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) raise exceptions.BrowserGoneException(self.GetStackTrace()) 34368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return int(pids[0]) 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 345bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch @property 346bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch def browser_directory(self): 347bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return None 348bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 349bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch @property 350bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch def profile_directory(self): 351bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return self._backend_settings.profile_dir 352bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 353424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) @property 354424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) def package(self): 355424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return self._backend_settings.package 356424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) @property 3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) def activity(self): 3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return self._backend_settings.activity 3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) @property 3621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def supports_tab_control(self): 3631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return self._backend_settings.supports_tab_control 3641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __del__(self): 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.Close() 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def Close(self): 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) super(AndroidBrowserBackend, self).Close() 370a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) self._adb.CloseApplication(self._backend_settings.package) 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 37258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if self._output_profile_path: 37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) logging.info("Pulling profile directory from device: '%s'->'%s'.", 37458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) self._backend_settings.profile_dir, 37558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) self._output_profile_path) 376424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) # To minimize bandwidth it might be good to look at whether all the data 377424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) # pulled down is really needed e.g. .pak files. 378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if not os.path.exists(self._output_profile_path): 379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) os.makedirs(self._output_profile_pathame) 380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) files = self.adb.RunShellCommandWithSU( 381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 'ls "%s"' % self._backend_settings.profile_dir) 382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for f in files: 383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # Don't pull lib, since it is created by the installer. 384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if f != 'lib': 385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) source = '%s%s' % (self._backend_settings.profile_dir, f) 386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) dest = os.path.join(self._output_profile_path, f) 387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # self._adb.Pull(source, dest) doesn't work because its timeout 388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # is fixed in android's adb_interface at 60 seconds, which may 389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # be too short to pull the cache. 390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) cmd = 'pull %s %s' % (source, dest) 3915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu self._adb.device().old_interface.Adb().SendCommand( 3925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu cmd, timeout_time=240) 393424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def IsBrowserRunning(self): 395a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) pids = self._adb.ExtractPid(self._backend_settings.package) 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return len(pids) != 0 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def GetRemotePort(self, local_port): 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return local_port 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def GetStandardOutput(self): 4027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return '\n'.join(self._adb.RunShellCommand('logcat -d -t 500')) 4037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def GetStackTrace(self): 4057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def Decorate(title, content): 4067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return title + '\n' + content + '\n' + '*' * 80 + '\n' 4077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # Get the last lines of logcat (large enough to contain stacktrace) 4087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch logcat = self.GetStandardOutput() 4097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ret = Decorate('Logcat', logcat) 4107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch stack = os.path.join(util.GetChromiumSrcDir(), 'third_party', 4117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'android_platform', 'development', 'scripts', 'stack') 4127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # Try to symbolize logcat. 4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if os.path.exists(stack): 4147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch p = subprocess.Popen([stack], stdin=subprocess.PIPE, 4157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch stdout=subprocess.PIPE) 4167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ret += Decorate('Stack from Logcat', p.communicate(input=logcat)[0]) 4177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # Try to get tombstones. 4197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch tombstones = os.path.join(util.GetChromiumSrcDir(), 'build', 'android', 4207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'tombstones.py') 4217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if os.path.exists(tombstones): 4227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ret += Decorate('Tombstones', 4237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch subprocess.Popen([tombstones, '-w', '--device', 4245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu self._adb.device_serial()], 4257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch stdout=subprocess.PIPE).communicate()[0]) 4267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return ret 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def AddReplayServerOptions(self, extra_wpr_args): 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self.forwarder_factory.does_forwarder_override_dns: 43058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) extra_wpr_args.append('--no-dns_forwarding') 431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if self.browser_options.netsim: 432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extra_wpr_args.append('--net=%s' % self.browser_options.netsim) 433