1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (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. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import contextlib 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import httplib 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import json 88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)import logging 98bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)import pprint 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import re 11a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)import socket 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import sys 13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)import urllib2 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)from telemetry import decorators 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import exceptions 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from telemetry.core import forwarders 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import user_agent 19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)from telemetry.core import util 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochfrom telemetry.core import web_contents 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import wpr_modes 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import wpr_server 23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)from telemetry.core.backends import browser_backend 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)from telemetry.core.backends.chrome import extension_backend 25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)from telemetry.core.backends.chrome import system_info_backend 26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)from telemetry.core.backends.chrome import tab_list_backend 27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)from telemetry.core.backends.chrome import tracing_backend 28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)from telemetry.timeline import tracing_timeline_data 29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)from telemetry.unittest import options_for_unittests 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class ChromeBrowserBackend(browser_backend.BrowserBackend): 33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) """An abstract class for chrome browser backends. Provides basic functionality 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) once a remote-debugger port has been established.""" 35a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) # It is OK to have abstract methods. pylint: disable=W0223 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def __init__(self, supports_tab_control, supports_extensions, browser_options, 3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) output_profile_path, extensions_to_load): 39a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) super(ChromeBrowserBackend, self).__init__( 40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) supports_extensions=supports_extensions, 4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) browser_options=browser_options, 42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tab_list_backend=tab_list_backend.TabListBackend) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._port = None 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self._supports_tab_control = supports_tab_control 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._tracing_backend = None 473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._system_info_backend = None 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) self._output_profile_path = output_profile_path 5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) self._extensions_to_load = extensions_to_load 5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if browser_options.netsim: 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.wpr_port_pairs = forwarders.PortPairs( 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) http=forwarders.PortPair(80, 80), 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) https=forwarders.PortPair(443, 443), 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dns=forwarders.PortPair(53, 53)) 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else: 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.wpr_port_pairs = forwarders.PortPairs( 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) http=forwarders.PortPair(0, 0), 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) https=forwarders.PortPair(0, 0), 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dns=None) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (self.browser_options.dont_override_profile and 6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) not options_for_unittests.AreSet()): 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sys.stderr.write('Warning: Not overriding profile. This can cause ' 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'unexpected effects due to profile-specific settings, ' 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'such as about:flags settings, cookies, and ' 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'extensions.\n') 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def AddReplayServerOptions(self, extra_wpr_args): 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if self.browser_options.netsim: 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extra_wpr_args.append('--net=%s' % self.browser_options.netsim) 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else: 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extra_wpr_args.append('--no-dns_forwarding') 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @property 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) @decorators.Cache 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def extension_backend(self): 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if not self.supports_extensions: 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return None 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return extension_backend.ExtensionBackendDict(self) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def GetBrowserStartupArgs(self): 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args = [] 8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) args.extend(self.browser_options.extra_browser_args) 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.append('--enable-net-benchmarking') 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.append('--metrics-recording-only') 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) args.append('--no-default-browser-check') 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.append('--no-first-run') 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) # Turn on GPU benchmarking extension for all runs. The only side effect of 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) # the extension being on is that render stats are tracked. This is believed 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) # to be effectively free. And, by doing so here, it avoids us having to 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) # programmatically inspect a pageset's actions in order to determine if it 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) # might eventually scroll. 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) args.append('--enable-gpu-benchmarking') 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) # Set --no-proxy-server to work around some XP issues unless 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) # some other flag indicates a proxy is needed. 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if not '--enable-spdy-proxy-auth' in args: 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) args.append('--no-proxy-server') 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if self.browser_options.disable_background_networking: 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci args.append('--disable-background-networking') 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if self.browser_options.netsim: 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) args.append('--ignore-certificate-errors') 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) elif self.browser_options.wpr_mode != wpr_modes.WPR_OFF: 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.extend(wpr_server.GetChromeFlags(self.forwarder_factory.host_ip, 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.wpr_port_pairs)) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.extend(user_agent.GetChromeUserAgentArgumentFromType( 11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) self.browser_options.browser_user_agent_type)) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) extensions = [extension.local_path 11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for extension in self._extensions_to_load 11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if not extension.is_component] 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) extension_str = ','.join(extensions) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if len(extensions) > 0: 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.append('--load-extension=%s' % extension_str) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) component_extensions = [extension.local_path 12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for extension in self._extensions_to_load 12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if extension.is_component] 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) component_extension_str = ','.join(component_extensions) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if len(component_extensions) > 0: 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.append('--load-component-extension=%s' % component_extension_str) 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if self.browser_options.no_proxy_server: 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch args.append('--no-proxy-server') 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if self.browser_options.disable_component_extensions_with_background_pages: 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) args.append('--disable-component-extensions-with-background-pages') 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return args 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def HasBrowserFinishedLaunching(self): 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 13803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) self.Request('', timeout=.1) 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except (exceptions.BrowserGoneException, 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) exceptions.BrowserConnectionGoneException): 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return False 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return True 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def _WaitForBrowserToComeUp(self, wait_for_extensions=True): 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) try: 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) util.WaitFor(self.HasBrowserFinishedLaunching, timeout=30) 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except (util.TimeoutException, exceptions.ProcessGoneException) as e: 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if not self.IsBrowserRunning(): 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) raise exceptions.BrowserGoneException(self.browser, e) 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) raise exceptions.BrowserConnectionGoneException(self.browser, e) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def AllExtensionsLoaded(): 15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) # Extension pages are loaded from an about:blank page, 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) # so we need to check that the document URL is the extension 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) # page in addition to the ready state. 15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) extension_ready_js = """ 15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) document.URL.lastIndexOf('chrome-extension://%s/', 0) == 0 && 15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (document.readyState == 'complete' || 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) document.readyState == 'interactive') 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) """ 16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for e in self._extensions_to_load: 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci try: 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_objects = self.extension_backend[e.extension_id] 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci except KeyError: 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return False 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for extension_object in extension_objects: 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) try: 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) res = extension_object.EvaluateJavaScript( 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension_ready_js % e.extension_id) 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) except exceptions.EvaluateException: 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) # If the inspected page is not ready, we will get an error 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) # when we evaluate a JS expression, but we can just keep polling 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) # until the page is ready (crbug.com/251913). 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) res = None 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) # TODO(tengs): We don't have full support for getting the Chrome 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) # version before launch, so for now we use a generic workaround to 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) # check for an extension binding bug in old versions of Chrome. 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) # See crbug.com/263162 for details. 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if res and extension_object.EvaluateJavaScript( 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'chrome.runtime == null'): 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension_object.Reload() 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if not res: 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return False 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return True 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if wait_for_extensions and self._supports_extensions: 1898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) try: 1908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) util.WaitFor(AllExtensionsLoaded, timeout=60) 1918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) except util.TimeoutException: 1928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) logging.error('ExtensionsToLoad: ' + 1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) repr([e.extension_id for e in self._extensions_to_load])) 1948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) logging.error('Extension list: ' + 195a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pprint.pformat(self.extension_backend, indent=4)) 1968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) raise 1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def ListInspectableContexts(self): 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return json.loads(self.Request('')) 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) def Request(self, path, timeout=30, throw_network_exception=False): 2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) url = 'http://127.0.0.1:%i/json' % self._port 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if path: 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url += '/' + path 205558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch try: 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) proxy_handler = urllib2.ProxyHandler({}) # Bypass any system proxy. 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) opener = urllib2.build_opener(proxy_handler) 2086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) with contextlib.closing(opener.open(url, timeout=timeout)) as req: 2096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return req.read() 210558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch except (socket.error, httplib.BadStatusLine, urllib2.URLError) as e: 211558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if throw_network_exception: 212558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch raise e 213558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if not self.IsBrowserRunning(): 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) raise exceptions.BrowserGoneException(self.browser, e) 215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) raise exceptions.BrowserConnectionGoneException(self.browser, e) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @property 218bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch def browser_directory(self): 219bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch raise NotImplementedError() 220bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 221bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch @property 222bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch def profile_directory(self): 223bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch raise NotImplementedError() 224bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 225bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch @property 226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch @decorators.Cache 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def chrome_branch_number(self): 228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch # Detect version information. 229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data = self.Request('version') 230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch resp = json.loads(data) 231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if 'Protocol-Version' in resp: 232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if 'Browser' in resp: 233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch branch_number_match = re.search('Chrome/\d+\.\d+\.(\d+)\.\d+', 234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch resp['Browser']) 235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch else: 236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch branch_number_match = re.search( 237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'Chrome/\d+\.\d+\.(\d+)\.\d+ (Mobile )?Safari', 238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch resp['User-Agent']) 239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if branch_number_match: 241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch branch_number = int(branch_number_match.group(1)) 242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if branch_number: 243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return branch_number 244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch # Branch number can't be determined, so fail any branch number checks. 246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return 0 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @property 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def supports_tab_control(self): 250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return self._supports_tab_control 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @property 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def supports_tracing(self): 254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return True 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) def StartTracing(self, trace_options, custom_categories=None, 257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch timeout=web_contents.DEFAULT_WEB_CONTENTS_TIMEOUT): 25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) """ 2596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Args: 2606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) trace_options: An tracing_options.TracingOptions instance. 2616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) custom_categories: An optional string containing a list of 2626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) comma separated categories that will be traced 2636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) instead of the default category set. Example: use 2646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "webkit,cc,disabled-by-default-cc.debug" to trace only 2656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) those three event categories. 2666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) """ 2676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) assert trace_options and trace_options.enable_chrome_trace 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._tracing_backend is None: 2696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self._tracing_backend = tracing_backend.TracingBackend(self._port, self) 2706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return self._tracing_backend.StartTracing( 2716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) trace_options, custom_categories, timeout) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) @property 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def is_tracing_running(self): 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if not self._tracing_backend: 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return None 277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return self._tracing_backend.is_tracing_running 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def StopTracing(self): 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) """ Stops tracing and returns the result as TimelineData object. """ 281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) tab_ids_list = [] 282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (i, _) in enumerate(self._browser.tabs): 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) tab = self.tab_list_backend.Get(i, None) 284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if tab: 285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) success = tab.EvaluateJavaScript( 286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "console.time('" + tab.id + "');" + 287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "console.timeEnd('" + tab.id + "');" + 288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "console.time.toString().indexOf('[native code]') != -1;") 289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if not success: 290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) raise Exception('Page stomped on console.time') 291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) tab_ids_list.append(tab.id) 292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) trace_events = self._tracing_backend.StopTracing() 293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) # Augment tab_ids data to trace events. 294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) event_data = {'traceEvents' : trace_events, 'tabIds': tab_ids_list} 295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return tracing_timeline_data.TracingTimelineData(event_data) 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 297b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def GetProcessName(self, cmd_line): 298b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """Returns a user-friendly name for the process of the given |cmd_line|.""" 299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if not cmd_line: 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # TODO(tonyg): Eventually we should make all of these known and add an 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # assertion. 302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 'unknown' 303b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if 'nacl_helper_bootstrap' in cmd_line: 304b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return 'nacl_helper_bootstrap' 305a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if ':sandboxed_process' in cmd_line: 306a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return 'renderer' 307b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) m = re.match(r'.* --type=([^\s]*) .*', cmd_line) 308b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if not m: 309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return 'browser' 310b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return m.group(1) 311b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def Close(self): 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._tracing_backend: 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._tracing_backend.Close() 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._tracing_backend = None 3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @property 3183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) def supports_system_info(self): 3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return self.GetSystemInfo() != None 3203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) def GetSystemInfo(self): 3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if self._system_info_backend is None: 3233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._system_info_backend = system_info_backend.SystemInfoBackend( 3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._port) 3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return self._system_info_backend.GetSystemInfo() 326