Index: tools/telemetry/telemetry/internal/backends/chrome/chrome_browser_backend.py |
diff --git a/tools/telemetry/telemetry/internal/backends/chrome/chrome_browser_backend.py b/tools/telemetry/telemetry/internal/backends/chrome/chrome_browser_backend.py |
deleted file mode 100644 |
index 845f84939b8d52e19551acf68f7ee1712e2284f0..0000000000000000000000000000000000000000 |
--- a/tools/telemetry/telemetry/internal/backends/chrome/chrome_browser_backend.py |
+++ /dev/null |
@@ -1,350 +0,0 @@ |
-# Copyright 2013 The Chromium Authors. All rights reserved. |
-# Use of this source code is governed by a BSD-style license that can be |
-# found in the LICENSE file. |
- |
-import logging |
-import pprint |
-import shlex |
-import sys |
- |
-from telemetry.core import exceptions |
-from telemetry.core import util |
-from telemetry import decorators |
-from telemetry.internal.backends import browser_backend |
-from telemetry.internal.backends.chrome import extension_backend |
-from telemetry.internal.backends.chrome import system_info_backend |
-from telemetry.internal.backends.chrome import tab_list_backend |
-from telemetry.internal.backends.chrome_inspector import devtools_client_backend |
-from telemetry.internal.browser import user_agent |
-from telemetry.internal.browser import web_contents |
-from telemetry.internal import forwarders |
-from telemetry.testing import options_for_unittests |
-from telemetry.util import wpr_modes |
- |
- |
-class ChromeBrowserBackend(browser_backend.BrowserBackend): |
- """An abstract class for chrome browser backends. Provides basic functionality |
- once a remote-debugger port has been established.""" |
- # It is OK to have abstract methods. pylint: disable=abstract-method |
- |
- def __init__(self, platform_backend, supports_tab_control, |
- supports_extensions, browser_options, output_profile_path, |
- extensions_to_load): |
- super(ChromeBrowserBackend, self).__init__( |
- platform_backend=platform_backend, |
- supports_extensions=supports_extensions, |
- browser_options=browser_options, |
- tab_list_backend=tab_list_backend.TabListBackend) |
- self._port = None |
- |
- self._supports_tab_control = supports_tab_control |
- self._devtools_client = None |
- self._system_info_backend = None |
- |
- self._output_profile_path = output_profile_path |
- self._extensions_to_load = extensions_to_load |
- |
- if browser_options.netsim: |
- self.wpr_port_pairs = forwarders.PortPairs( |
- http=forwarders.PortPair(80, 80), |
- https=forwarders.PortPair(443, 443), |
- dns=forwarders.PortPair(53, 53)) |
- else: |
- self.wpr_port_pairs = forwarders.PortPairs( |
- http=forwarders.PortPair(0, 0), |
- https=forwarders.PortPair(0, 0), |
- dns=None) |
- |
- if (self.browser_options.dont_override_profile and |
- not options_for_unittests.AreSet()): |
- sys.stderr.write('Warning: Not overriding profile. This can cause ' |
- 'unexpected effects due to profile-specific settings, ' |
- 'such as about:flags settings, cookies, and ' |
- 'extensions.\n') |
- |
- @property |
- def devtools_client(self): |
- return self._devtools_client |
- |
- @property |
- @decorators.Cache |
- def extension_backend(self): |
- if not self.supports_extensions: |
- return None |
- return extension_backend.ExtensionBackendDict(self) |
- |
- def _ArgsNeedProxyServer(self, args): |
- """Returns True if args for Chrome indicate the need for proxy server.""" |
- if '--enable-spdy-proxy-auth' in args: |
- return True |
- return [arg for arg in args if arg.startswith('--proxy-server=')] |
- |
- def GetBrowserStartupArgs(self): |
- args = [] |
- args.extend(self.browser_options.extra_browser_args) |
- args.append('--enable-net-benchmarking') |
- args.append('--metrics-recording-only') |
- args.append('--no-default-browser-check') |
- args.append('--no-first-run') |
- |
- # Turn on GPU benchmarking extension for all runs. The only side effect of |
- # the extension being on is that render stats are tracked. This is believed |
- # to be effectively free. And, by doing so here, it avoids us having to |
- # programmatically inspect a pageset's actions in order to determine if it |
- # might eventually scroll. |
- args.append('--enable-gpu-benchmarking') |
- |
- # Set --no-proxy-server to work around some XP issues unless |
- # some other flag indicates a proxy is needed. |
- if not self._ArgsNeedProxyServer(args): |
- self.browser_options.no_proxy_server = True |
- |
- if self.browser_options.disable_background_networking: |
- args.append('--disable-background-networking') |
- args.extend(self.GetReplayBrowserStartupArgs()) |
- args.extend(user_agent.GetChromeUserAgentArgumentFromType( |
- self.browser_options.browser_user_agent_type)) |
- |
- extensions = [extension.local_path |
- for extension in self._extensions_to_load |
- if not extension.is_component] |
- extension_str = ','.join(extensions) |
- if len(extensions) > 0: |
- args.append('--load-extension=%s' % extension_str) |
- |
- component_extensions = [extension.local_path |
- for extension in self._extensions_to_load |
- if extension.is_component] |
- component_extension_str = ','.join(component_extensions) |
- if len(component_extensions) > 0: |
- args.append('--load-component-extension=%s' % component_extension_str) |
- |
- if self.browser_options.no_proxy_server: |
- args.append('--no-proxy-server') |
- |
- if self.browser_options.disable_component_extensions_with_background_pages: |
- args.append('--disable-component-extensions-with-background-pages') |
- |
- # Disables the start page, as well as other external apps that can |
- # steal focus or make measurements inconsistent. |
- if self.browser_options.disable_default_apps: |
- args.append('--disable-default-apps') |
- |
- if self.browser_options.enable_logging: |
- args.append('--enable-logging') |
- args.append('--v=1') |
- return args |
- |
- def _UseHostResolverRules(self): |
- """Returns True to add --host-resolver-rules to send requests to replay.""" |
- if self._platform_backend.forwarder_factory.does_forwarder_override_dns: |
- # Avoid --host-resolver-rules when the forwarder will map DNS requests |
- # from the target platform to replay (on the host platform). |
- # This allows the browser to exercise DNS requests. |
- return False |
- if self.browser_options.netsim and self.platform_backend.is_host_platform: |
- # Avoid --host-resolver-rules when replay will configure the platform to |
- # resolve hosts to replay. |
- # This allows the browser to exercise DNS requests. |
- return False |
- return True |
- |
- def GetReplayBrowserStartupArgs(self): |
- if self.browser_options.wpr_mode == wpr_modes.WPR_OFF: |
- return [] |
- replay_args = [] |
- if self.should_ignore_certificate_errors: |
- # Ignore certificate errors if the platform backend has not created |
- # and installed a root certificate. |
- replay_args.append('--ignore-certificate-errors') |
- if self._UseHostResolverRules(): |
- # Force hostnames to resolve to the replay's host_ip. |
- replay_args.append('--host-resolver-rules=MAP * %s,EXCLUDE localhost' % |
- self._platform_backend.forwarder_factory.host_ip) |
- # Force the browser to send HTTP/HTTPS requests to fixed ports if they |
- # are not the standard HTTP/HTTPS ports. |
- http_port = self.platform_backend.wpr_http_device_port |
- https_port = self.platform_backend.wpr_https_device_port |
- if http_port != 80: |
- replay_args.append('--testing-fixed-http-port=%s' % http_port) |
- if https_port != 443: |
- replay_args.append('--testing-fixed-https-port=%s' % https_port) |
- return replay_args |
- |
- def HasBrowserFinishedLaunching(self): |
- assert self._port, 'No DevTools port info available.' |
- return devtools_client_backend.IsDevToolsAgentAvailable(self._port, self) |
- |
- def _InitDevtoolsClientBackend(self, remote_devtools_port=None): |
- """ Initiate the devtool client backend which allow browser connection |
- through browser' devtool. |
- |
- Args: |
- remote_devtools_port: The remote devtools port, if |
- any. Otherwise assumed to be the same as self._port. |
- """ |
- assert not self._devtools_client, ( |
- 'Devtool client backend cannot be init twice') |
- self._devtools_client = devtools_client_backend.DevToolsClientBackend( |
- self._port, remote_devtools_port or self._port, self) |
- |
- def _WaitForBrowserToComeUp(self): |
- """ Wait for browser to come up. """ |
- try: |
- timeout = self.browser_options.browser_startup_timeout |
- util.WaitFor(self.HasBrowserFinishedLaunching, timeout=timeout) |
- except (exceptions.TimeoutException, exceptions.ProcessGoneException) as e: |
- if not self.IsBrowserRunning(): |
- raise exceptions.BrowserGoneException(self.browser, e) |
- raise exceptions.BrowserConnectionGoneException(self.browser, e) |
- |
- def _WaitForExtensionsToLoad(self): |
- """ Wait for all extensions to load. |
- Be sure to check whether the browser_backend supports_extensions before |
- calling this method. |
- """ |
- assert self._supports_extensions |
- assert self._devtools_client, ( |
- 'Waiting for extensions required devtool client to be initiated first') |
- try: |
- util.WaitFor(self._AllExtensionsLoaded, timeout=60) |
- except exceptions.TimeoutException: |
- logging.error('ExtensionsToLoad: ' + |
- repr([e.extension_id for e in self._extensions_to_load])) |
- logging.error('Extension list: ' + |
- pprint.pformat(self.extension_backend, indent=4)) |
- raise |
- |
- def _AllExtensionsLoaded(self): |
- # Extension pages are loaded from an about:blank page, |
- # so we need to check that the document URL is the extension |
- # page in addition to the ready state. |
- extension_ready_js = """ |
- document.URL.lastIndexOf('chrome-extension://%s/', 0) == 0 && |
- (document.readyState == 'complete' || |
- document.readyState == 'interactive') |
- """ |
- for e in self._extensions_to_load: |
- try: |
- extension_objects = self.extension_backend[e.extension_id] |
- except KeyError: |
- return False |
- for extension_object in extension_objects: |
- try: |
- res = extension_object.EvaluateJavaScript( |
- extension_ready_js % e.extension_id) |
- except exceptions.EvaluateException: |
- # If the inspected page is not ready, we will get an error |
- # when we evaluate a JS expression, but we can just keep polling |
- # until the page is ready (crbug.com/251913). |
- res = None |
- |
- # TODO(tengs): We don't have full support for getting the Chrome |
- # version before launch, so for now we use a generic workaround to |
- # check for an extension binding bug in old versions of Chrome. |
- # See crbug.com/263162 for details. |
- if res and extension_object.EvaluateJavaScript( |
- 'chrome.runtime == null'): |
- extension_object.Reload() |
- if not res: |
- return False |
- return True |
- |
- @property |
- def browser_directory(self): |
- raise NotImplementedError() |
- |
- @property |
- def profile_directory(self): |
- raise NotImplementedError() |
- |
- @property |
- def supports_tab_control(self): |
- return self._supports_tab_control |
- |
- @property |
- def supports_tracing(self): |
- return True |
- |
- def StartTracing(self, trace_options, custom_categories=None, |
- timeout=web_contents.DEFAULT_WEB_CONTENTS_TIMEOUT): |
- """ |
- Args: |
- trace_options: An tracing_options.TracingOptions instance. |
- custom_categories: An optional string containing a list of |
- comma separated categories that will be traced |
- instead of the default category set. Example: use |
- "webkit,cc,disabled-by-default-cc.debug" to trace only |
- those three event categories. |
- """ |
- return self.devtools_client.StartChromeTracing( |
- trace_options, custom_categories, timeout) |
- |
- def StopTracing(self, trace_data_builder): |
- self.devtools_client.StopChromeTracing(trace_data_builder) |
- |
- def GetProcessName(self, cmd_line): |
- """Returns a user-friendly name for the process of the given |cmd_line|.""" |
- if not cmd_line: |
- # TODO(tonyg): Eventually we should make all of these known and add an |
- # assertion. |
- return 'unknown' |
- if 'nacl_helper_bootstrap' in cmd_line: |
- return 'nacl_helper_bootstrap' |
- if ':sandboxed_process' in cmd_line: |
- return 'renderer' |
- if ':privileged_process' in cmd_line: |
- return 'gpu-process' |
- args = shlex.split(cmd_line) |
- types = [arg.split('=')[1] for arg in args if arg.startswith('--type=')] |
- if not types: |
- return 'browser' |
- return types[0] |
- |
- def Close(self): |
- if self._devtools_client: |
- self._devtools_client.Close() |
- self._devtools_client = None |
- |
- @property |
- def supports_system_info(self): |
- return self.GetSystemInfo() != None |
- |
- def GetSystemInfo(self): |
- if self._system_info_backend is None: |
- self._system_info_backend = system_info_backend.SystemInfoBackend( |
- self._port) |
- return self._system_info_backend.GetSystemInfo() |
- |
- @property |
- def supports_memory_dumping(self): |
- return True |
- |
- def DumpMemory(self, timeout=web_contents.DEFAULT_WEB_CONTENTS_TIMEOUT): |
- return self.devtools_client.DumpMemory(timeout) |
- |
- @property |
- def supports_overriding_memory_pressure_notifications(self): |
- return True |
- |
- def SetMemoryPressureNotificationsSuppressed( |
- self, suppressed, timeout=web_contents.DEFAULT_WEB_CONTENTS_TIMEOUT): |
- self.devtools_client.SetMemoryPressureNotificationsSuppressed( |
- suppressed, timeout) |
- |
- def SimulateMemoryPressureNotification( |
- self, pressure_level, timeout=web_contents.DEFAULT_WEB_CONTENTS_TIMEOUT): |
- self.devtools_client.SimulateMemoryPressureNotification( |
- pressure_level, timeout) |
- |
- @property |
- def supports_cpu_metrics(self): |
- return True |
- |
- @property |
- def supports_memory_metrics(self): |
- return True |
- |
- @property |
- def supports_power_metrics(self): |
- return True |