OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview | 6 * @fileoverview |
7 * Provides a HTML5 postMessage channel to the injected JS to talk back | 7 * Provides a HTML5 postMessage channel to the injected JS to talk back |
8 * to Authenticator. | 8 * to Authenticator. |
9 */ | 9 */ |
10 'use strict'; | 10 'use strict'; |
11 | 11 |
12 <include src="../gaia_auth/channel.js"> | 12 // <include src="../gaia_auth/channel.js"> |
13 | 13 |
14 var PostMessageChannel = (function() { | 14 var PostMessageChannel = (function() { |
15 /** | 15 /** |
16 * Allowed origins of the hosting page. | 16 * Allowed origins of the hosting page. |
17 * @type {Array<string>} | 17 * @type {Array<string>} |
18 */ | 18 */ |
19 var ALLOWED_ORIGINS = [ | 19 var ALLOWED_ORIGINS = ['chrome://oobe', 'chrome://chrome-signin']; |
20 'chrome://oobe', | |
21 'chrome://chrome-signin' | |
22 ]; | |
23 | 20 |
24 /** @const */ | 21 /** @const */ |
25 var PORT_MESSAGE = 'post-message-port-message'; | 22 var PORT_MESSAGE = 'post-message-port-message'; |
26 | 23 |
27 /** @const */ | 24 /** @const */ |
28 var CHANNEL_INIT_MESSAGE = 'post-message-channel-init'; | 25 var CHANNEL_INIT_MESSAGE = 'post-message-channel-init'; |
29 | 26 |
30 /** @const */ | 27 /** @const */ |
31 var CHANNEL_CONNECT_MESSAGE = 'post-message-channel-connect'; | 28 var CHANNEL_CONNECT_MESSAGE = 'post-message-channel-connect'; |
32 | 29 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 port.setTarget(opt_targetWindow, opt_targetOrigin); | 139 port.setTarget(opt_targetWindow, opt_targetOrigin); |
143 this.channels_[channelId] = port; | 140 this.channels_[channelId] = port; |
144 return port; | 141 return port; |
145 }, | 142 }, |
146 | 143 |
147 /* | 144 /* |
148 * Returns a message forward handler for the given proxy port. | 145 * Returns a message forward handler for the given proxy port. |
149 * @private | 146 * @private |
150 */ | 147 */ |
151 getProxyPortForwardHandler_: function(proxyPort) { | 148 getProxyPortForwardHandler_: function(proxyPort) { |
152 return function(msg) { proxyPort.postMessage(msg); }; | 149 return function(msg) { |
| 150 proxyPort.postMessage(msg); |
| 151 }; |
153 }, | 152 }, |
154 | 153 |
155 /** | 154 /** |
156 * Creates a forwarding porxy port. | 155 * Creates a forwarding porxy port. |
157 * @param {number} channelId | 156 * @param {number} channelId |
158 * @param {string} channelName | 157 * @param {string} channelName |
159 * @param {!DOMWindow} targetWindow | 158 * @param {!DOMWindow} targetWindow |
160 * @param {!string} targetOrigin | 159 * @param {!string} targetOrigin |
161 */ | 160 */ |
162 createProxyPort: function( | 161 createProxyPort: function( |
163 channelId, channelName, targetWindow, targetOrigin) { | 162 channelId, channelName, targetWindow, targetOrigin) { |
164 var port = this.createPort( | 163 var port = |
165 channelId, channelName, targetWindow, targetOrigin); | 164 this.createPort(channelId, channelName, targetWindow, targetOrigin); |
166 port.onMessage.addListener(this.getProxyPortForwardHandler_(port)); | 165 port.onMessage.addListener(this.getProxyPortForwardHandler_(port)); |
167 return port; | 166 return port; |
168 }, | 167 }, |
169 | 168 |
170 /** | 169 /** |
171 * Creates a connecting port to the daemon and request connection. | 170 * Creates a connecting port to the daemon and request connection. |
172 * @param {string} name | 171 * @param {string} name |
173 * @return {PostMessagePort} | 172 * @return {PostMessagePort} |
174 */ | 173 */ |
175 connectToDaemon: function(name) { | 174 connectToDaemon: function(name) { |
(...skipping 30 matching lines...) Expand all Loading... |
206 return; | 205 return; |
207 } | 206 } |
208 | 207 |
209 port.handleWindowMessage(e); | 208 port.handleWindowMessage(e); |
210 }, | 209 }, |
211 | 210 |
212 /** | 211 /** |
213 * Window 'message' handler. | 212 * Window 'message' handler. |
214 */ | 213 */ |
215 onMessage_: function(e) { | 214 onMessage_: function(e) { |
216 if (typeof e.data != 'object' || | 215 if (typeof e.data != 'object' || !e.data.hasOwnProperty('type')) { |
217 !e.data.hasOwnProperty('type')) { | |
218 return; | 216 return; |
219 } | 217 } |
220 | 218 |
221 if (e.data.type === PORT_MESSAGE) { | 219 if (e.data.type === PORT_MESSAGE) { |
222 // Dispatch port message to ports if this is the daemon page or | 220 // Dispatch port message to ports if this is the daemon page or |
223 // the message is from upperWindow. In case of null upperWindow, | 221 // the message is from upperWindow. In case of null upperWindow, |
224 // the message is assumed to be forwarded to upperWindow and queued. | 222 // the message is assumed to be forwarded to upperWindow and queued. |
225 if (this.isDaemon || | 223 if (this.isDaemon || |
226 (this.upperWindow && e.source === this.upperWindow)) { | 224 (this.upperWindow && e.source === this.upperWindow)) { |
227 this.dispatchMessageToPort_(e); | 225 this.dispatchMessageToPort_(e); |
228 } else { | 226 } else { |
229 this.postToUpperWindow(e.data); | 227 this.postToUpperWindow(e.data); |
230 } | 228 } |
231 } else if (e.data.type === CHANNEL_CONNECT_MESSAGE) { | 229 } else if (e.data.type === CHANNEL_CONNECT_MESSAGE) { |
232 var channelId = e.data.channelId; | 230 var channelId = e.data.channelId; |
233 var channelName = e.data.channelName; | 231 var channelName = e.data.channelName; |
234 | 232 |
235 if (this.isDaemon) { | 233 if (this.isDaemon) { |
236 var port = this.createPort( | 234 var port = |
237 channelId, channelName, e.source, e.origin); | 235 this.createPort(channelId, channelName, e.source, e.origin); |
238 this.onConnect.dispatch(port); | 236 this.onConnect.dispatch(port); |
239 } else { | 237 } else { |
240 this.createProxyPort(channelId, channelName, e.source, e.origin); | 238 this.createProxyPort(channelId, channelName, e.source, e.origin); |
241 this.postToUpperWindow(e.data); | 239 this.postToUpperWindow(e.data); |
242 } | 240 } |
243 } else if (e.data.type === CHANNEL_INIT_MESSAGE) { | 241 } else if (e.data.type === CHANNEL_INIT_MESSAGE) { |
244 if (ALLOWED_ORIGINS.indexOf(e.origin) == -1) | 242 if (ALLOWED_ORIGINS.indexOf(e.origin) == -1) |
245 return; | 243 return; |
246 | 244 |
247 this.upperWindow = e.source; | 245 this.upperWindow = e.source; |
248 this.upperOrigin = e.origin; | 246 this.upperOrigin = e.origin; |
249 | 247 |
250 for (var i = 0; i < this.deferredUpperWindowMessages_.length; ++i) { | 248 for (var i = 0; i < this.deferredUpperWindowMessages_.length; ++i) { |
251 this.upperWindow.postMessage(this.deferredUpperWindowMessages_[i], | 249 this.upperWindow.postMessage( |
252 this.upperOrigin); | 250 this.deferredUpperWindowMessages_[i], this.upperOrigin); |
253 } | 251 } |
254 this.deferredUpperWindowMessages_ = []; | 252 this.deferredUpperWindowMessages_ = []; |
255 | 253 |
256 for (var i = 0; i < this.deferredUpperWindowPorts_.length; ++i) { | 254 for (var i = 0; i < this.deferredUpperWindowPorts_.length; ++i) { |
257 this.deferredUpperWindowPorts_[i].setTarget(this.upperWindow, | 255 this.deferredUpperWindowPorts_[i].setTarget( |
258 this.upperOrigin); | 256 this.upperWindow, this.upperOrigin); |
259 } | 257 } |
260 this.deferredUpperWindowPorts_ = []; | 258 this.deferredUpperWindowPorts_ = []; |
261 } | 259 } |
262 } | 260 } |
263 }; | 261 }; |
264 | 262 |
265 /** | 263 /** |
266 * Singleton instance of ChannelManager. | 264 * Singleton instance of ChannelManager. |
267 * @type {ChannelManager} | 265 * @type {ChannelManager} |
268 */ | 266 */ |
(...skipping 30 matching lines...) Expand all Loading... |
299 } | 297 } |
300 this.deferredMessages_ = []; | 298 this.deferredMessages_ = []; |
301 }, | 299 }, |
302 | 300 |
303 postMessage: function(msg) { | 301 postMessage: function(msg) { |
304 if (!this.targetWindow) { | 302 if (!this.targetWindow) { |
305 this.deferredMessages_.push(msg); | 303 this.deferredMessages_.push(msg); |
306 return; | 304 return; |
307 } | 305 } |
308 | 306 |
309 this.targetWindow.postMessage({ | 307 this.targetWindow.postMessage( |
310 type: PORT_MESSAGE, | 308 {type: PORT_MESSAGE, channelId: this.channelId, payload: msg}, |
311 channelId: this.channelId, | 309 this.targetOrigin); |
312 payload: msg | |
313 }, this.targetOrigin); | |
314 }, | 310 }, |
315 | 311 |
316 handleWindowMessage: function(e) { | 312 handleWindowMessage: function(e) { |
317 this.onMessage.dispatch(e.data.payload); | 313 this.onMessage.dispatch(e.data.payload); |
318 } | 314 } |
319 }; | 315 }; |
320 | 316 |
321 /** | 317 /** |
322 * A message channel based on PostMessagePort. | 318 * A message channel based on PostMessagePort. |
323 * @extends {Channel} | 319 * @extends {Channel} |
(...skipping 11 matching lines...) Expand all Loading... |
335 this.port_ = channelManager.connectToDaemon(name); | 331 this.port_ = channelManager.connectToDaemon(name); |
336 this.port_.onMessage.addListener(this.onMessage_.bind(this)); | 332 this.port_.onMessage.addListener(this.onMessage_.bind(this)); |
337 }, | 333 }, |
338 }; | 334 }; |
339 | 335 |
340 /** | 336 /** |
341 * Initialize webview content window for postMessage channel. | 337 * Initialize webview content window for postMessage channel. |
342 * @param {DOMWindow} webViewContentWindow Content window of the webview. | 338 * @param {DOMWindow} webViewContentWindow Content window of the webview. |
343 */ | 339 */ |
344 PostMessageChannel.init = function(webViewContentWindow) { | 340 PostMessageChannel.init = function(webViewContentWindow) { |
345 webViewContentWindow.postMessage({ | 341 webViewContentWindow.postMessage({type: CHANNEL_INIT_MESSAGE}, '*'); |
346 type: CHANNEL_INIT_MESSAGE | |
347 }, '*'); | |
348 }; | 342 }; |
349 | 343 |
350 /** | 344 /** |
351 * Run in daemon mode and listen for incoming connections. Note that the | 345 * Run in daemon mode and listen for incoming connections. Note that the |
352 * current implementation assumes the daemon runs in the hosting page | 346 * current implementation assumes the daemon runs in the hosting page |
353 * at the upper layer of the DOM tree. That is, all connect requests go | 347 * at the upper layer of the DOM tree. That is, all connect requests go |
354 * up the DOM tree instead of going into sub frames. | 348 * up the DOM tree instead of going into sub frames. |
355 * @param {function(PostMessagePort)} callback Invoked when a connection is | 349 * @param {function(PostMessagePort)} callback Invoked when a connection is |
356 * made. | 350 * made. |
357 */ | 351 */ |
358 PostMessageChannel.runAsDaemon = function(callback) { | 352 PostMessageChannel.runAsDaemon = function(callback) { |
359 channelManager.isDaemon = true; | 353 channelManager.isDaemon = true; |
360 | 354 |
361 var onConnect = function(port) { | 355 var onConnect = function(port) { |
362 callback(port); | 356 callback(port); |
363 }; | 357 }; |
364 channelManager.onConnect.addListener(onConnect); | 358 channelManager.onConnect.addListener(onConnect); |
365 }; | 359 }; |
366 | 360 |
367 return PostMessageChannel; | 361 return PostMessageChannel; |
368 })(); | 362 })(); |
369 | 363 |
370 /** @override */ | 364 /** @override */ |
371 Channel.create = function() { | 365 Channel.create = function() { |
372 return new PostMessageChannel(); | 366 return new PostMessageChannel(); |
373 }; | 367 }; |
OLD | NEW |