blob: fa00b8ad8b6869b6367166b665e9dab0aa46297f [file] [log] [blame]
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import json
import logging
import socket
from chrome_remote_control import websocket
class InspectorException(Exception):
pass
class InspectorBackend(object):
def __init__(self, backend, descriptor):
self._backend = backend
self._descriptor = descriptor
self._socket = websocket.create_connection(
descriptor['webSocketDebuggerUrl'])
self._next_request_id = 0
self._domain_handlers = {}
def Close(self):
for _, handlers in self._domain_handlers.items():
_, will_close_handler = handlers
will_close_handler()
self._domain_handlers = {}
self._socket.close()
self._socket = None
self._backend = None
def DispatchNotifications(self):
try:
data = self._socket.recv()
except socket.error:
return None
res = json.loads(data)
logging.debug('got [%s]', data)
if 'method' not in res:
return
mname = res['method']
dot_pos = mname.find('.')
domain_name = mname[:dot_pos]
if domain_name in self._domain_handlers:
try:
self._domain_handlers[domain_name][0](res)
except Exception:
import traceback
traceback.print_exc()
def SendAndIgnoreResponse(self, req):
req['id'] = self._next_request_id
self._next_request_id += 1
self._socket.send(json.dumps(req))
def SyncRequest(self, req, timeout=60):
# TODO(nduca): Listen to the timeout argument
# pylint: disable=W0613
# self._socket.settimeout(timeout)
req['id'] = self._next_request_id
self._next_request_id += 1
self._socket.send(json.dumps(req))
while True:
data = self._socket.recv()
res = json.loads(data)
logging.debug('got [%s]', data)
if 'method' in res:
mname = res['method']
dot_pos = mname.find('.')
domain_name = mname[:dot_pos]
if domain_name in self._domain_handlers:
try:
self._domain_handlers[domain_name][0](res)
except Exception:
import traceback
traceback.print_exc()
else:
logging.debug('Unhandled inspector mesage: %s', data)
continue
if res['id'] != req['id']:
logging.debug('Dropped reply: %s', json.dumps(res))
continue
return res
def RegisterDomain(self,
domain_name, notification_handler, will_close_handler):
"""Registers a given domain for handling notification methods.
For example, given inspector_backend:
def OnConsoleNotification(msg):
if msg['method'] == 'Console.messageAdded':
print msg['params']['message']
return
def OnConsoleClose(self):
pass
inspector_backend.RegisterDomain('Console',
OnConsoleNotification, OnConsoleClose)
"""
assert domain_name not in self._domain_handlers
self._domain_handlers[domain_name] = (notification_handler,
will_close_handler)