| OLD | NEW |
| (Empty) |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 """Finds android browsers that can be controlled by telemetry.""" | |
| 5 | |
| 6 import os | |
| 7 import logging as real_logging | |
| 8 import re | |
| 9 import subprocess | |
| 10 import sys | |
| 11 | |
| 12 from telemetry.core import browser | |
| 13 from telemetry.core import possible_browser | |
| 14 from telemetry.core.chrome import adb_commands | |
| 15 from telemetry.core.chrome import android_browser_backend | |
| 16 from telemetry.core.chrome import android_platform | |
| 17 | |
| 18 CHROME_PACKAGE_NAMES = { | |
| 19 'android-chrome': 'com.google.android.apps.chrome', | |
| 20 'android-chrome-beta': 'com.chrome.beta', | |
| 21 'android-chrome-dev': 'com.google.android.apps.chrome_dev', | |
| 22 'android-jb-system-chrome': 'com.android.chrome' | |
| 23 } | |
| 24 | |
| 25 ALL_BROWSER_TYPES = ','.join(['android-content-shell'] + | |
| 26 CHROME_PACKAGE_NAMES.keys()) | |
| 27 | |
| 28 CHROME_ACTIVITY = 'com.google.android.apps.chrome.Main' | |
| 29 CHROME_COMMAND_LINE = '/data/local/chrome-command-line' | |
| 30 CHROME_DEVTOOLS_REMOTE_PORT = 'localabstract:chrome_devtools_remote' | |
| 31 | |
| 32 CONTENT_SHELL_PACKAGE = 'org.chromium.content_shell_apk' | |
| 33 CONTENT_SHELL_ACTIVITY = 'org.chromium.content_shell_apk.ContentShellActivity' | |
| 34 CONTENT_SHELL_COMMAND_LINE = '/data/local/tmp/content-shell-command-line' | |
| 35 CONTENT_SHELL_DEVTOOLS_REMOTE_PORT = ( | |
| 36 'localabstract:content_shell_devtools_remote') | |
| 37 | |
| 38 # adb shell pm list packages | |
| 39 # adb | |
| 40 # intents to run (pass -D url for the rest) | |
| 41 # com.android.chrome/.Main | |
| 42 # com.google.android.apps.chrome/.Main | |
| 43 | |
| 44 class PossibleAndroidBrowser(possible_browser.PossibleBrowser): | |
| 45 """A launchable android browser instance.""" | |
| 46 def __init__(self, browser_type, options, *args): | |
| 47 super(PossibleAndroidBrowser, self).__init__(browser_type, options) | |
| 48 self._args = args | |
| 49 | |
| 50 def __repr__(self): | |
| 51 return 'PossibleAndroidBrowser(browser_type=%s)' % self.browser_type | |
| 52 | |
| 53 def Create(self): | |
| 54 backend = android_browser_backend.AndroidBrowserBackend( | |
| 55 self._options, *self._args) | |
| 56 platform = android_platform.AndroidPlatform( | |
| 57 self._args[0].Adb(), self._args[1], | |
| 58 self._args[4]) | |
| 59 b = browser.Browser(backend, platform) | |
| 60 backend.SetBrowser(b) | |
| 61 return b | |
| 62 | |
| 63 def SupportsOptions(self, options): | |
| 64 if len(options.extensions_to_load) != 0: | |
| 65 return False | |
| 66 return True | |
| 67 | |
| 68 def FindAllAvailableBrowsers(options, logging=real_logging): | |
| 69 """Finds all the desktop browsers available on this machine.""" | |
| 70 if not adb_commands.IsAndroidSupported(): | |
| 71 return [] | |
| 72 | |
| 73 # See if adb even works. | |
| 74 try: | |
| 75 with open(os.devnull, 'w') as devnull: | |
| 76 proc = subprocess.Popen(['adb', 'devices'], | |
| 77 stdout=subprocess.PIPE, | |
| 78 stderr=subprocess.PIPE, | |
| 79 stdin=devnull) | |
| 80 stdout, _ = proc.communicate() | |
| 81 if re.search(re.escape('????????????\tno permissions'), stdout) != None: | |
| 82 logging.warn( | |
| 83 ('adb devices reported a permissions error. Consider ' | |
| 84 'restarting adb as root:')) | |
| 85 logging.warn(' adb kill-server') | |
| 86 logging.warn(' sudo `which adb` devices\n\n') | |
| 87 except OSError: | |
| 88 platform_tools_path = os.path.join( | |
| 89 os.path.dirname(__file__), '..', '..', '..', '..', '..' | |
| 90 'third_party', 'android_tools', 'sdk', 'platform-tools') | |
| 91 if (sys.platform.startswith('linux') and | |
| 92 os.path.exists(os.path.join(platform_tools_path, 'adb'))): | |
| 93 os.environ['PATH'] = os.pathsep.join([platform_tools_path, | |
| 94 os.environ['PATH']]) | |
| 95 else: | |
| 96 logging.info('No adb command found. ' + | |
| 97 'Will not try searching for Android browsers.') | |
| 98 return [] | |
| 99 | |
| 100 device = None | |
| 101 if options.android_device: | |
| 102 devices = [options.android_device] | |
| 103 else: | |
| 104 devices = adb_commands.GetAttachedDevices() | |
| 105 | |
| 106 if len(devices) == 0: | |
| 107 logging.info('No android devices found.') | |
| 108 return [] | |
| 109 | |
| 110 if len(devices) > 1: | |
| 111 logging.warn('Multiple devices attached. ' + | |
| 112 'Please specify a device explicitly.') | |
| 113 return [] | |
| 114 | |
| 115 device = devices[0] | |
| 116 | |
| 117 adb = adb_commands.AdbCommands(device=device) | |
| 118 | |
| 119 packages = adb.RunShellCommand('pm list packages') | |
| 120 possible_browsers = [] | |
| 121 if 'package:' + CONTENT_SHELL_PACKAGE in packages: | |
| 122 b = PossibleAndroidBrowser('android-content-shell', | |
| 123 options, adb, | |
| 124 CONTENT_SHELL_PACKAGE, True, | |
| 125 CONTENT_SHELL_COMMAND_LINE, | |
| 126 CONTENT_SHELL_ACTIVITY, | |
| 127 CONTENT_SHELL_DEVTOOLS_REMOTE_PORT) | |
| 128 possible_browsers.append(b) | |
| 129 | |
| 130 for name, package in CHROME_PACKAGE_NAMES.iteritems(): | |
| 131 if 'package:' + package in packages: | |
| 132 b = PossibleAndroidBrowser(name, | |
| 133 options, adb, | |
| 134 package, False, | |
| 135 CHROME_COMMAND_LINE, | |
| 136 CHROME_ACTIVITY, | |
| 137 CHROME_DEVTOOLS_REMOTE_PORT) | |
| 138 possible_browsers.append(b) | |
| 139 | |
| 140 # See if the "forwarder" is installed -- we need this to host content locally | |
| 141 # but make it accessible to the device. | |
| 142 if len(possible_browsers) and not adb_commands.HasForwarder(): | |
| 143 logging.warn('telemetry detected an android device. However,') | |
| 144 logging.warn('Chrome\'s port-forwarder app is not available.') | |
| 145 logging.warn('To build:') | |
| 146 logging.warn(' make -j16 host_forwarder device_forwarder') | |
| 147 logging.warn('') | |
| 148 logging.warn('') | |
| 149 return [] | |
| 150 return possible_browsers | |
| OLD | NEW |