Index: tools/telemetry/telemetry/browser_backend.py |
diff --git a/tools/telemetry/telemetry/browser_backend.py b/tools/telemetry/telemetry/browser_backend.py |
index 57c4f93dd6716119a960447b6c9f23a4c2b1d47d..01257f5497dda8806df877b3120d3993092e222f 100644 |
--- a/tools/telemetry/telemetry/browser_backend.py |
+++ b/tools/telemetry/telemetry/browser_backend.py |
@@ -11,6 +11,7 @@ import sys |
import weakref |
from telemetry import browser_gone_exception |
+from telemetry import extension_page |
from telemetry import tab |
from telemetry import tracing_backend |
from telemetry import user_agent |
@@ -23,26 +24,19 @@ class BrowserConnectionGoneException( |
browser_gone_exception.BrowserGoneException): |
pass |
- |
-class TabController(object): |
+class ContextControler(object): |
def __init__(self, browser, browser_backend): |
self._browser = browser |
self._browser_backend = browser_backend |
- |
# Stores web socket debugger URLs in iteration order. |
- self._tab_list = [] |
+ self._context_list = [] |
# Maps debugger URLs to Tab objects. |
- self._tab_dict = weakref.WeakValueDictionary() |
- |
- self._UpdateTabList() |
- |
- def New(self, timeout=None): |
- self._browser_backend.Request('new', timeout=timeout) |
- return self[-1] |
+ self._context_dict = weakref.WeakValueDictionary() |
+ self._UpdateContextList() |
def DoesDebuggerUrlExist(self, url): |
- self._UpdateTabList() |
- return url in self._tab_list |
+ self._UpdateContextList() |
+ return url in self._context_list |
def CloseTab(self, debugger_url, timeout=None): |
# TODO(dtu): crbug.com/160946, allow closing the last tab on some platforms. |
@@ -81,52 +75,118 @@ class TabController(object): |
return tab_info['url'] |
def __iter__(self): |
- self._UpdateTabList() |
- return self._tab_list.__iter__() |
+ self._UpdateContextList() |
+ return self._context_list.__iter__() |
def __len__(self): |
- self._UpdateTabList() |
- return len(self._tab_list) |
+ self._UpdateContextList() |
+ return len(self._context_list) |
def __getitem__(self, index): |
- self._UpdateTabList() |
+ self._UpdateContextList() |
# This dereference will propagate IndexErrors. |
- debugger_url = self._tab_list[index] |
+ debugger_url = self._context_list[index] |
+ return self._GetContextObjectForDebugger(debugger_url) |
+ |
+ def FindByUrl(self, url): |
+ for tab_info in self._ListContexts(): |
+ if tab_info['url'] == url: |
+ return self._GetContextObjectForDebugger( |
+ tab_info.get('webSocketDebuggerUrl')) |
+ return None |
+ |
+ def GetAllForUrl(self, url): |
+ return [self._GetContextObjectForDebugger( |
+ tab_info.get('webSocketDebuggerUrl')) |
+ for tab_info in self._ListContexts() |
+ if tab_info['url'] == url] |
+ |
+ def _GetContextObjectForDebugger(self, debugger_url): |
# Lazily get/create a Tab object. |
- tab_object = self._tab_dict.get(debugger_url) |
+ tab_object = self._context_dict.get(debugger_url) |
if not tab_object: |
- tab_object = tab.Tab(self._browser, self, debugger_url) |
- self._tab_dict[debugger_url] = tab_object |
+ tab_object = self._CreateContextObject(debugger_url) |
+ self._context_dict[debugger_url] = tab_object |
return tab_object |
- def _ListTabs(self, timeout=None): |
+ def _ListContexts(self, timeout=None): |
try: |
data = self._browser_backend.Request('', timeout=timeout) |
all_contexts = json.loads(data) |
- tabs = [ctx for ctx in all_contexts |
- if not ctx['url'].startswith('chrome-extension://')] |
- return tabs |
+ contexts = self._FilterContexts(all_contexts) |
+ return contexts |
except (socket.error, httplib.BadStatusLine, urllib2.URLError): |
if not self._browser_backend.IsBrowserRunning(): |
raise browser_gone_exception.BrowserGoneException() |
raise BrowserConnectionGoneException() |
- def _UpdateTabList(self): |
+ def _UpdateContextList(self): |
def GetDebuggerUrl(tab_info): |
if 'webSocketDebuggerUrl' not in tab_info: |
return None |
return tab_info['webSocketDebuggerUrl'] |
- new_tab_list = map(GetDebuggerUrl, self._ListTabs()) |
- self._tab_list = [t for t in self._tab_list if t in new_tab_list] |
- self._tab_list += [t for t in new_tab_list if t not in self._tab_list] |
- |
- def _FindTabInfo(self, debugger_url): |
- for tab_info in self._ListTabs(): |
+ new_context_list = map(GetDebuggerUrl, self._ListContexts()) |
+ self._context_list = [t for t in self._context_list |
+ if t in new_context_list] |
+ self._context_list += [t for t in new_context_list |
+ if t not in self._context_list] |
+ |
+ def _FindContextInfo(self, debugger_url): |
+ for tab_info in self._ListContexts(): |
if tab_info.get('webSocketDebuggerUrl') == debugger_url: |
return tab_info |
return None |
+class TabController(ContextControler): |
+ def __init__(self, browser, browser_backend): |
+ super(TabController, self).__init__(browser, browser_backend) |
+ |
+ def _CreateContextObject(self, debugger_url): |
+ return tab.Tab(self._browser, self, debugger_url) |
+ |
+ def _FilterContexts(self, all_contexts): |
+ return [ctx for ctx in all_contexts |
+ if not ctx['url'].startswith('chrome-extension://')] |
+ |
+ def New(self, timeout=None): |
+ self._browser_backend.Request('new', timeout=timeout) |
+ return self[-1] |
+ |
+ def CloseTab(self, debugger_url, timeout=None): |
+ # TODO(dtu): crbug.com/160946, allow closing the last tab on some platforms. |
+ # For now, just create a new tab before closing the last tab. |
+ if len(self) <= 1: |
+ self.New() |
+ |
+ tab_id = debugger_url.split('/')[-1] |
+ try: |
+ response = self._browser_backend.Request('close/%s' % tab_id, |
+ timeout=timeout) |
+ except urllib2.HTTPError: |
+ raise Exception('Unable to close tab, tab id not found: %s' % tab_id) |
+ assert response == 'Target is closing' |
+ |
+ util.WaitFor(lambda: not self._FindContextInfo(debugger_url), timeout=5) |
+ self._UpdateContextList() |
+ |
+ def GetTabUrl(self, debugger_url): |
+ tab_info = self._FindContextInfo(debugger_url) |
+ assert tab_info is not None |
+ return tab_info['url'] |
+ |
+class ExtensionController(ContextControler): |
+ def __init__(self, browser, browser_backend): |
+ super(ExtensionController, self).__init__(browser, browser_backend) |
+ |
+ def _CreateContextObject(self, debugger_url): |
+ return extension_page.ExtensionPage( |
+ tab.Tab(self._browser, self, debugger_url)) |
+ |
+ def _FilterContexts(self, all_contexts): |
+ return [ctx for ctx in all_contexts |
+ if ctx['url'].startswith('chrome-extension://')] |
+ |
class BrowserBackend(object): |
"""A base class for browser backends. Provides basic functionality |
once a remote-debugger port has been established.""" |
@@ -137,6 +197,7 @@ class BrowserBackend(object): |
def __init__(self, is_content_shell, options): |
self.tabs = None |
+ self.extensions = None |
self.browser_type = options.browser_type |
self.is_content_shell = is_content_shell |
self.options = options |
@@ -155,6 +216,8 @@ class BrowserBackend(object): |
def SetBrowser(self, browser): |
self.tabs = TabController(browser, self) |
+ if not self.is_content_shell: |
+ self.extensions = ExtensionController(browser, self) |
def GetBrowserStartupArgs(self): |
args = [] |