| 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 json | |
| 5 import logging | |
| 6 import socket | |
| 7 | |
| 8 from chrome_remote_control import tab_crash_exception | |
| 9 from chrome_remote_control import util | |
| 10 from chrome_remote_control import websocket | |
| 11 | |
| 12 class InspectorException(Exception): | |
| 13 pass | |
| 14 | |
| 15 class InspectorBackend(object): | |
| 16 def __init__(self, backend, descriptor): | |
| 17 self._backend = backend | |
| 18 self._descriptor = descriptor | |
| 19 self._socket_url = descriptor['webSocketDebuggerUrl'] | |
| 20 self._socket = websocket.create_connection( | |
| 21 descriptor['webSocketDebuggerUrl']) | |
| 22 self._next_request_id = 0 | |
| 23 self._domain_handlers = {} | |
| 24 self._cur_socket_timeout = 0 | |
| 25 | |
| 26 def Close(self): | |
| 27 for _, handlers in self._domain_handlers.items(): | |
| 28 _, will_close_handler = handlers | |
| 29 will_close_handler() | |
| 30 self._domain_handlers = {} | |
| 31 self._socket.close() | |
| 32 self._socket = None | |
| 33 self._backend = None | |
| 34 | |
| 35 def DispatchNotifications(self, timeout=10): | |
| 36 self._SetTimeout(timeout) | |
| 37 try: | |
| 38 data = self._socket.recv() | |
| 39 except socket.error: | |
| 40 if self._backend.DoesDebuggerUrlExist(self._socket_url): | |
| 41 return | |
| 42 raise tab_crash_exception.TabCrashException() | |
| 43 | |
| 44 res = json.loads(data) | |
| 45 logging.debug('got [%s]', data) | |
| 46 if 'method' not in res: | |
| 47 return | |
| 48 | |
| 49 mname = res['method'] | |
| 50 dot_pos = mname.find('.') | |
| 51 domain_name = mname[:dot_pos] | |
| 52 if domain_name in self._domain_handlers: | |
| 53 try: | |
| 54 self._domain_handlers[domain_name][0](res) | |
| 55 except Exception: | |
| 56 import traceback | |
| 57 traceback.print_exc() | |
| 58 | |
| 59 def SendAndIgnoreResponse(self, req): | |
| 60 req['id'] = self._next_request_id | |
| 61 self._next_request_id += 1 | |
| 62 data = json.dumps(req) | |
| 63 self._socket.send(data) | |
| 64 logging.debug('sent [%s]', data) | |
| 65 | |
| 66 def _SetTimeout(self, timeout): | |
| 67 if self._cur_socket_timeout != timeout: | |
| 68 self._socket.settimeout(timeout) | |
| 69 self._cur_socket_timeout = timeout | |
| 70 | |
| 71 def SyncRequest(self, req, timeout=10): | |
| 72 # TODO(nduca): Listen to the timeout argument | |
| 73 # pylint: disable=W0613 | |
| 74 self._SetTimeout(timeout) | |
| 75 self.SendAndIgnoreResponse(req) | |
| 76 | |
| 77 while True: | |
| 78 try: | |
| 79 data = self._socket.recv() | |
| 80 except socket.error: | |
| 81 if self._backend.DoesDebuggerUrlExist(self._socket_url): | |
| 82 raise util.TimeoutException( | |
| 83 "TimedOut waiting for reply. This is unusual.") | |
| 84 raise tab_crash_exception.TabCrashException() | |
| 85 | |
| 86 res = json.loads(data) | |
| 87 logging.debug('got [%s]', data) | |
| 88 if 'method' in res: | |
| 89 mname = res['method'] | |
| 90 dot_pos = mname.find('.') | |
| 91 domain_name = mname[:dot_pos] | |
| 92 if domain_name in self._domain_handlers: | |
| 93 try: | |
| 94 self._domain_handlers[domain_name][0](res) | |
| 95 except Exception: | |
| 96 import traceback | |
| 97 traceback.print_exc() | |
| 98 else: | |
| 99 logging.debug('Unhandled inspector mesage: %s', data) | |
| 100 continue | |
| 101 | |
| 102 if res['id'] != req['id']: | |
| 103 logging.debug('Dropped reply: %s', json.dumps(res)) | |
| 104 continue | |
| 105 return res | |
| 106 | |
| 107 def RegisterDomain(self, | |
| 108 domain_name, notification_handler, will_close_handler): | |
| 109 """Registers a given domain for handling notification methods. | |
| 110 | |
| 111 For example, given inspector_backend: | |
| 112 def OnConsoleNotification(msg): | |
| 113 if msg['method'] == 'Console.messageAdded': | |
| 114 print msg['params']['message'] | |
| 115 return | |
| 116 def OnConsoleClose(self): | |
| 117 pass | |
| 118 inspector_backend.RegisterDomain('Console', | |
| 119 OnConsoleNotification, OnConsoleClose) | |
| 120 """ | |
| 121 assert domain_name not in self._domain_handlers | |
| 122 self._domain_handlers[domain_name] = (notification_handler, | |
| 123 will_close_handler) | |
| 124 | |
| OLD | NEW |