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.
8 * The sandbox side of the application/sandbox WCS interface, used by the
9 * sandbox to exchange messages with the application.
14 /** @suppress {duplicate} */
15 var remoting = remoting || {};
18 remoting.WcsSandboxContent = function() {
23 this.parentWindow_ = null;
30 * @type {Object.<number, XMLHttpRequest>}
33 this.pendingXhrs_ = {};
35 window.addEventListener('message', this.onMessage_.bind(this), false);
39 * Event handler to process messages from the application.
41 * @param {Event} event
43 remoting.WcsSandboxContent.prototype.onMessage_ = function(event) {
44 this.parentWindow_ = event.source;
46 switch (event.data['command']) {
49 // Since the WCS driver code constructs XHRs directly, the only
50 // mechanism for proxying them is to replace the XMLHttpRequest
52 XMLHttpRequest = remoting.XMLHttpRequestProxy;
57 var stanza = event.data['stanza'];
58 if (stanza === undefined) {
59 console.error('sendIq: missing IQ stanza.');
63 remoting.wcs.sendIq(stanza);
65 console.error('Dropping IQ stanza:', stanza);
69 case 'setAccessToken':
71 var token = event.data['token'];
72 if (token === undefined) {
73 console.error('setAccessToken: missing access token.');
76 // The WCS driver JS requires that remoting.wcsLoader be a global
77 // variable, so it can't be a member of this class.
78 // TODO(jamiewalch): remoting.wcs doesn't need to be global and should
79 // be made a member (http://crbug.com/172348).
81 remoting.wcs.updateAccessToken(token);
82 } else if (!remoting.wcsLoader) {
83 remoting.wcsLoader = new remoting.WcsLoader();
84 remoting.wcsLoader.start(token,
85 this.onLocalJid_.bind(this),
86 this.onError_.bind(this));
90 case 'xhrStateChange':
92 var id = event.data['id'];
93 if (id === undefined) {
94 console.error('xhrStateChange: missing id.');
97 var pendingXhr = this.pendingXhrs_[id];
99 console.error('xhrStateChange: unrecognized id:', id);
102 /** @type {XMLHttpRequest} */
103 var xhr = event.data['xhr'];
104 if (xhr === undefined) {
105 console.error('xhrStateChange: missing xhr');
108 for (var member in xhr) {
109 pendingXhr[member] = xhr[member];
111 if (xhr.readyState == 4) {
112 delete this.pendingXhrs_[id];
114 if (pendingXhr.onreadystatechange) {
115 pendingXhr.onreadystatechange();
120 console.error('Unexpected message:', event.data['command'], event.data);
125 * Callback method to indicate that the WCS driver has loaded and provide the
126 * full JID of the client.
128 * @param {string} localJid The full JID of the WCS client.
131 remoting.WcsSandboxContent.prototype.onLocalJid_ = function(localJid) {
132 remoting.wcs.setOnIq(this.onIq_.bind(this));
134 'command': 'onLocalJid',
137 this.parentWindow_.postMessage(message, '*');
141 * Callback method to indicate that something went wrong loading the WCS driver.
143 * @param {remoting.Error} error Details of the error.
146 remoting.WcsSandboxContent.prototype.onError_ = function(error) {
148 'command': 'onError',
151 this.parentWindow_.postMessage(message, '*');
155 * Forward an XHR to the container process to send. This is analogous to XHR's
158 * @param {remoting.XMLHttpRequestProxy} xhr The XHR to send.
159 * @return {number} The unique ID allocated to the XHR. Used to abort it.
161 remoting.WcsSandboxContent.prototype.sendXhr = function(xhr) {
162 var id = this.nextXhrId_++;
163 this.pendingXhrs_[id] = xhr;
165 'command': 'sendXhr',
167 'parameters': xhr.sandbox_ipc
169 this.parentWindow_.postMessage(message, '*');
170 delete xhr.sandbox_ipc;
175 * Abort a forwarded XHR. This is analogous to XHR's abort method.
177 * @param {number} id The unique ID of the XHR to abort, as returned by sendXhr.
179 remoting.WcsSandboxContent.prototype.abortXhr = function(id) {
180 if (!this.pendingXhrs_[id]) {
181 // The XHR is removed when it reaches the "ready" state. Calling abort
182 // subsequently is unusual, but legal, so just silently ignore the request
187 'command': 'abortXhr',
190 this.parentWindow_.postMessage(message, '*');
194 * Callback to indicate than an IQ stanza has been received from the WCS
195 * driver, and should be forwarded to the main process.
197 * @param {string} stanza
200 remoting.WcsSandboxContent.prototype.onIq_ = function(stanza) {
201 remoting.wcs.setOnIq(this.onIq_.bind(this));
206 this.parentWindow_.postMessage(message, '*');
210 * Entry point for the WCS sandbox process.
212 function onSandboxInit() {
213 // The WCS code registers for a couple of events that aren't supported in
214 // Apps V2, so ignore those for now.
215 var oldAEL = window.addEventListener;
216 window.addEventListener = function(type, listener, useCapture) {
217 if (type == 'beforeunload' || type == 'unload') {
220 oldAEL(type, listener, useCapture);
223 remoting.settings = new remoting.Settings();
224 remoting.sandboxContent = new remoting.WcsSandboxContent();
227 window.addEventListener('load', onSandboxInit, false);
229 /** @type {remoting.WcsSandboxContent} */
230 remoting.sandboxContent = null;