1<!DOCTYPE html>
2<!--
3Copyright (c) 2013 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7<link rel="import" href="/tracing/base/base.html">
8<script>
9
10'use strict';
11
12/**
13 * Contains connection code that inspector's embedding framework calls on
14 * tracing, and that tracing can use to talk to inspector.
15 */
16tr.exportTo('tr.ui.e.about_tracing', function() {
17  // Interface used by inspector when it hands data to us from the backend.
18  window.DevToolsAPI = {
19    setToolbarColors: function() { },
20    addExtensions: function() { },
21    setInspectedPageId: function() { },
22
23    dispatchMessage: function(payload) {
24      throw new Error('Should have been patched by InspectorConnection');
25    }
26  };
27  // Temporary until inspector backend switches to DevToolsAPI.
28  window.InspectorFrontendAPI = window.DevToolsAPI;
29
30  /**
31   * @constructor
32   */
33  function InspectorConnection() {
34    if (InspectorConnection.instance)
35      throw new Error('Singleton');
36
37    this.nextRequestId_ = 1;
38    this.pendingRequestResolversId_ = {};
39
40    this.notificationListenersByMethodName_ = {};
41    DevToolsAPI.dispatchMessage = this.dispatchMessage_.bind(this);
42  }
43
44  InspectorConnection.prototype = {
45    req: function(method, params) {
46      var id = this.nextRequestId_++;
47      var msg = JSON.stringify({
48        id: id,
49        method: method,
50        params: params
51      });
52      var devtoolsMessageStr = JSON.stringify(
53        {'id': id, 'method': 'dispatchProtocolMessage', 'params': [msg]});
54      DevToolsHost.sendMessageToEmbedder(devtoolsMessageStr);
55
56      return new Promise(function(resolve, reject) {
57        this.pendingRequestResolversId_[id] = {
58          resolve: resolve,
59          reject: reject
60        };
61      }.bind(this));
62    },
63
64    setNotificationListener: function(method, listener) {
65      this.notificationListenersByMethodName_[method] = listener;
66    },
67
68    dispatchMessage_: function(payload) {
69      var isStringPayload = typeof payload === 'string';
70      // Special handling for Tracing.dataCollected because it is high
71      // bandwidth.
72      var isDataCollectedMessage = isStringPayload ?
73          payload.indexOf('"method": "Tracing.dataCollected"') !== -1 :
74          payload.method === 'Tracing.dataCollected';
75      if (isDataCollectedMessage) {
76        var listener = this.notificationListenersByMethodName_[
77            'Tracing.dataCollected'];
78        if (listener) {
79          // FIXME(loislo): trace viewer should be able to process
80          // raw message object because string based version a few times
81          // slower on the browser side.
82          // see https://codereview.chromium.org/784513002.
83          listener(isStringPayload ? payload : JSON.stringify(payload));
84          return;
85        }
86      }
87
88      var message = isStringPayload ? JSON.parse(payload) : payload;
89      if (message.id) {
90        var resolver = this.pendingRequestResolversId_[message.id];
91        if (resolver === undefined) {
92          console.log('Unrecognized ack', message);
93          return;
94        }
95        if (message.error) {
96          resolver.reject(message.error);
97          return;
98        }
99        resolver.resolve(message.result);
100        return;
101      }
102
103      if (message['method']) {
104        var listener = this.notificationListenersByMethodName_[message.method];
105        if (listener === undefined) {
106          console.log('Unhandled ', message.method);
107          return;
108        }
109        listener(message.params);
110        return;
111      }
112      console.log('Unknown dispatchMessage: ', payload);
113    }
114  };
115
116  if (window.DevToolsHost)
117    InspectorConnection.instance = new InspectorConnection();
118  else
119    InspectorConnection.instance = undefined;
120
121  return {
122    InspectorConnection: InspectorConnection
123  };
124});
125</script>
126