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