Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / resources / gaia_auth / channel.js
blob2f6ce2101e623b7ab8cf19e1d121017ca055535d
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.
5 /**
6  * Channel to the background script.
7  */
8 function Channel() {
9   this.messageCallbacks_ = {};
10   this.internalRequestCallbacks_ = {};
13 /** @const */
14 Channel.INTERNAL_REQUEST_MESSAGE = 'internal-request-message';
16 /** @const */
17 Channel.INTERNAL_REPLY_MESSAGE = 'internal-reply-message';
19 Channel.prototype = {
20   // Message port to use to communicate with background script.
21   port_: null,
23   // Registered message callbacks.
24   messageCallbacks_: null,
26   // Internal request id to track pending requests.
27   nextInternalRequestId_: 0,
29   // Pending internal request callbacks.
30   internalRequestCallbacks_: null,
32   /**
33    * Initialize the channel with given port for the background script.
34    */
35   init: function(port) {
36     this.port_ = port;
37     this.port_.onMessage.addListener(this.onMessage_.bind(this));
38   },
40   /**
41    * Connects to the background script with the given name.
42    */
43   connect: function(name) {
44     this.port_ = chrome.runtime.connect({name: name});
45     this.port_.onMessage.addListener(this.onMessage_.bind(this));
46   },
48   /**
49    * Associates a message name with a callback. When a message with the name
50    * is received, the callback will be invoked with the message as its arg.
51    * Note only the last registered callback will be invoked.
52    */
53   registerMessage: function(name, callback) {
54     this.messageCallbacks_[name] = callback;
55   },
57   /**
58    * Sends a message to the other side of the channel.
59    */
60   send: function(msg) {
61     this.port_.postMessage(msg);
62   },
64   /**
65    * Sends a message to the other side and invokes the callback with
66    * the replied object. Useful for message that expects a returned result.
67    */
68   sendWithCallback: function(msg, callback) {
69     var requestId = this.nextInternalRequestId_++;
70     this.internalRequestCallbacks_[requestId] = callback;
71     this.send({
72       name: Channel.INTERNAL_REQUEST_MESSAGE,
73       requestId: requestId,
74       payload: msg
75     });
76   },
78   /**
79    * Invokes message callback using given message.
80    * @return {*} The return value of the message callback or null.
81    */
82   invokeMessageCallbacks_: function(msg) {
83     var name = msg.name;
84     if (this.messageCallbacks_[name])
85       return this.messageCallbacks_[name](msg);
87     console.error('Error: Unexpected message, name=' + name);
88     return null;
89   },
91   /**
92    * Invoked when a message is received.
93    */
94   onMessage_: function(msg) {
95     var name = msg.name;
96     if (name == Channel.INTERNAL_REQUEST_MESSAGE) {
97       var payload = msg.payload;
98       var result = this.invokeMessageCallbacks_(payload);
99       this.send({
100         name: Channel.INTERNAL_REPLY_MESSAGE,
101         requestId: msg.requestId,
102         result: result
103       });
104     } else if (name == Channel.INTERNAL_REPLY_MESSAGE) {
105       var callback = this.internalRequestCallbacks_[msg.requestId];
106       delete this.internalRequestCallbacks_[msg.requestId];
107       if (callback)
108         callback(msg.result);
109     } else {
110       this.invokeMessageCallbacks_(msg);
111     }
112   }
116  * Class factory.
117  * @return {Channel}
118  */
119 Channel.create = function() {
120   return new Channel();