• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2013 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
5import json
6
7from telemetry.core import exceptions
8from telemetry.internal.backends.chrome_inspector import inspector_backend_list
9from telemetry.internal.browser import tab
10
11import py_utils
12
13
14class TabUnexpectedResponseException(exceptions.DevtoolsTargetCrashException):
15  pass
16
17
18class TabListBackend(inspector_backend_list.InspectorBackendList):
19  """A dynamic sequence of tab.Tabs in UI order."""
20
21  def __init__(self, browser_backend):
22    super(TabListBackend, self).__init__(browser_backend)
23
24  def New(self, timeout):
25    """Makes a new tab.
26
27    Returns:
28      A Tab object.
29
30    Raises:
31      devtools_http.DevToolsClientConnectionError
32    """
33    if not self._browser_backend.supports_tab_control:
34      raise NotImplementedError("Browser doesn't support tab control.")
35    response = self._browser_backend.devtools_client.RequestNewTab(timeout)
36    try:
37      response = json.loads(response)
38      context_id = response['id']
39    except (KeyError, ValueError):
40      raise TabUnexpectedResponseException(
41          app=self._browser_backend.browser,
42          msg='Received response: %s' % response)
43    return self.GetBackendFromContextId(context_id)
44
45  def CloseTab(self, tab_id, timeout=300):
46    """Closes the tab with the given debugger_url.
47
48    Raises:
49      devtools_http.DevToolsClientConnectionError
50      devtools_client_backend.TabNotFoundError
51      TabUnexpectedResponseException
52      py_utils.TimeoutException
53    """
54    assert self._browser_backend.supports_tab_control
55    # TODO(dtu): crbug.com/160946, allow closing the last tab on some platforms.
56    # For now, just create a new tab before closing the last tab.
57    if len(self) <= 1:
58      self.New(timeout)
59
60    response = self._browser_backend.devtools_client.CloseTab(tab_id, timeout)
61
62    if response != 'Target is closing':
63      raise TabUnexpectedResponseException(
64          app=self._browser_backend.browser,
65          msg='Received response: %s' % response)
66
67    py_utils.WaitFor(lambda: tab_id not in self.IterContextIds(), timeout=5)
68
69  def ActivateTab(self, tab_id, timeout=30):
70    """Activates the tab with the given debugger_url.
71
72    Raises:
73      devtools_http.DevToolsClientConnectionError
74      devtools_client_backend.TabNotFoundError
75      TabUnexpectedResponseException
76    """
77    assert self._browser_backend.supports_tab_control
78
79    response = self._browser_backend.devtools_client.ActivateTab(tab_id,
80                                                                 timeout)
81
82    if response != 'Target activated':
83      raise TabUnexpectedResponseException(
84          app=self._browser_backend.browser,
85          msg='Received response: %s' % response)
86
87  def Get(self, index, ret):
88    """Returns self[index] if it exists, or ret if index is out of bounds."""
89    if len(self) <= index:
90      return ret
91    return self[index]
92
93  def ShouldIncludeContext(self, context):
94    if 'type' in context:
95      return (context['type'] == 'page' or
96              context['url'] == 'chrome://media-router/')
97    # TODO: For compatibility with Chrome before r177683.
98    # This check is not completely correct, see crbug.com/190592.
99    return not context['url'].startswith('chrome-extension://')
100
101  def CreateWrapper(self, inspector_backend):
102    return tab.Tab(inspector_backend, self, self._browser_backend.browser)
103
104  def _HandleDevToolsConnectionError(self, error):
105    if not self._browser_backend.IsAppRunning():
106      error.AddDebuggingMessage('The browser is not running. It probably '
107                                'crashed.')
108    elif not self._browser_backend.HasBrowserFinishedLaunching():
109      error.AddDebuggingMessage('The browser exists but cannot be reached.')
110    else:
111      error.AddDebuggingMessage('The browser exists and can be reached. '
112                                'The devtools target probably crashed.')
113