| 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 import urllib2 | |
| 5 import httplib | |
| 6 import socket | |
| 7 import json | |
| 8 | |
| 9 from chrome_remote_control import browser_gone_exception | |
| 10 from chrome_remote_control import inspector_backend | |
| 11 from chrome_remote_control import tab | |
| 12 from chrome_remote_control import util | |
| 13 from chrome_remote_control import wpr_modes | |
| 14 from chrome_remote_control import wpr_server | |
| 15 | |
| 16 class BrowserBackend(object): | |
| 17 """A base class for broser backends. Provides basic functionality | |
| 18 once a remote-debugger port has been established.""" | |
| 19 def __init__(self, is_content_shell, options): | |
| 20 self.is_content_shell = is_content_shell | |
| 21 self.options = options | |
| 22 self._port = None | |
| 23 | |
| 24 def GetBrowserStartupArgs(self): | |
| 25 args = [] | |
| 26 args.extend(self.options.extra_browser_args) | |
| 27 args.append('--disable-background-networking') | |
| 28 args.append('--metrics-recording-only') | |
| 29 args.append('--no-first-run') | |
| 30 if self.options.wpr_mode != wpr_modes.WPR_OFF: | |
| 31 args.extend(wpr_server.CHROME_FLAGS) | |
| 32 return args | |
| 33 | |
| 34 @property | |
| 35 def wpr_mode(self): | |
| 36 return self.options.wpr_mode | |
| 37 | |
| 38 def _WaitForBrowserToComeUp(self): | |
| 39 def IsBrowserUp(): | |
| 40 try: | |
| 41 self._ListTabs() | |
| 42 except socket.error: | |
| 43 if not self.IsBrowserRunning(): | |
| 44 raise browser_gone_exception.BrowserGoneException() | |
| 45 return False | |
| 46 except httplib.BadStatusLine: | |
| 47 if not self.IsBrowserRunning(): | |
| 48 raise browser_gone_exception.BrowserGoneException() | |
| 49 return False | |
| 50 except urllib2.URLError: | |
| 51 if not self.IsBrowserRunning(): | |
| 52 raise browser_gone_exception.BrowserGoneException() | |
| 53 return False | |
| 54 else: | |
| 55 return True | |
| 56 try: | |
| 57 util.WaitFor(IsBrowserUp, timeout=30) | |
| 58 except util.TimeoutException: | |
| 59 raise browser_gone_exception.BrowserGoneException() | |
| 60 | |
| 61 @property | |
| 62 def _debugger_url(self): | |
| 63 return 'http://localhost:%i/json' % self._port | |
| 64 | |
| 65 def _ListTabs(self, timeout=None): | |
| 66 req = urllib2.urlopen(self._debugger_url, timeout=timeout) | |
| 67 data = req.read() | |
| 68 all_contexts = json.loads(data) | |
| 69 tabs = [ctx for ctx in all_contexts | |
| 70 if not ctx['url'].startswith('chrome-extension://')] | |
| 71 # FIXME(dtu): The remote debugger protocol returns in order of most | |
| 72 # recently created tab first. In order to convert it to the UI tab | |
| 73 # order, we just reverse the list, which assumes we can't move tabs. | |
| 74 # We should guarantee that the remote debugger returns in the UI tab order. | |
| 75 tabs.reverse() | |
| 76 return tabs | |
| 77 | |
| 78 def NewTab(self, timeout=None): | |
| 79 req = urllib2.urlopen(self._debugger_url + '/new', timeout=timeout) | |
| 80 data = req.read() | |
| 81 new_tab = json.loads(data) | |
| 82 return new_tab | |
| 83 | |
| 84 def CloseTab(self, index, timeout=None): | |
| 85 assert self.num_tabs > 1, 'Closing the last tab not supported.' | |
| 86 target_tab = self._ListTabs()[index] | |
| 87 tab_id = target_tab['webSocketDebuggerUrl'].split('/')[-1] | |
| 88 target_num_tabs = self.num_tabs - 1 | |
| 89 | |
| 90 urllib2.urlopen('%s/close/%s' % (self._debugger_url, tab_id), | |
| 91 timeout=timeout) | |
| 92 | |
| 93 util.WaitFor(lambda: self.num_tabs == target_num_tabs, timeout=5) | |
| 94 | |
| 95 @property | |
| 96 def num_tabs(self): | |
| 97 return len(self._ListTabs()) | |
| 98 | |
| 99 def GetNthTabUrl(self, index): | |
| 100 return self._ListTabs()[index]['url'] | |
| 101 | |
| 102 def ConnectToNthTab(self, browser, index): | |
| 103 ib = inspector_backend.InspectorBackend(self, self._ListTabs()[index]) | |
| 104 return tab.Tab(browser, ib) | |
| 105 | |
| 106 def DoesDebuggerUrlExist(self, url): | |
| 107 matches = [t for t in self._ListTabs() | |
| 108 if t['webSocketDebuggerUrl'] == url] | |
| 109 return len(matches) >= 1 | |
| 110 | |
| 111 def CreateForwarder(self, host_port): | |
| 112 raise NotImplementedError() | |
| 113 | |
| 114 def IsBrowserRunning(self): | |
| 115 raise NotImplementedError() | |
| OLD | NEW |