| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 * This class provides an interface between the HostController and either the | 7 * This class provides an interface between the HostController and either the |
| 8 * NativeMessaging Host or the Host NPAPI plugin, depending on whether or not | 8 * NativeMessaging Host. |
| 9 * NativeMessaging is supported. Since the test for NativeMessaging support is | |
| 10 * asynchronous, this class stores any requests on a queue, pending the result | |
| 11 * of the test. | |
| 12 * Once the test is complete, the pending requests are performed on either the | |
| 13 * NativeMessaging host, or the NPAPI plugin. | |
| 14 * | |
| 15 * If necessary, the HostController is instructed (via a callback) to | |
| 16 * instantiate the NPAPI plugin, and return a reference to it here. | |
| 17 */ | 9 */ |
| 18 | 10 |
| 19 'use strict'; | 11 'use strict'; |
| 20 | 12 |
| 21 /** @suppress {duplicate} */ | 13 /** @suppress {duplicate} */ |
| 22 var remoting = remoting || {}; | 14 var remoting = remoting || {}; |
| 23 | 15 |
| 24 /** | 16 /** |
| 25 * @constructor | 17 * @constructor |
| 26 * @param {function():remoting.HostPlugin} createPluginCallback Callback to | |
| 27 * instantiate the NPAPI plugin when NativeMessaging is determined to be | |
| 28 * unsupported. | |
| 29 */ | 18 */ |
| 30 remoting.HostDispatcher = function(createPluginCallback) { | 19 remoting.HostDispatcher = function() { |
| 31 /** @type {remoting.HostNativeMessaging} @private */ | 20 /** @type {remoting.HostNativeMessaging} @private */ |
| 32 this.nativeMessagingHost_ = new remoting.HostNativeMessaging(); | 21 this.nativeMessagingHost_ = new remoting.HostNativeMessaging(); |
| 33 | 22 |
| 34 /** @type {remoting.HostPlugin} @private */ | |
| 35 this.npapiHost_ = null; | |
| 36 | |
| 37 /** @type {remoting.HostDispatcher.State} @private */ | 23 /** @type {remoting.HostDispatcher.State} @private */ |
| 38 this.state_ = remoting.HostDispatcher.State.UNKNOWN; | 24 this.state_ = remoting.HostDispatcher.State.UNKNOWN; |
| 39 | 25 |
| 40 /** @type {Array.<function()>} @private */ | 26 /** @type {Array.<function()>} @private */ |
| 41 this.pendingRequests_ = []; | 27 this.pendingRequests_ = []; |
| 42 | 28 |
| 43 /** @type {function():remoting.HostPlugin} @private */ | |
| 44 this.createPluginCallback_ = createPluginCallback; | |
| 45 | |
| 46 this.tryToInitialize_(); | 29 this.tryToInitialize_(); |
| 47 } | 30 } |
| 48 | 31 |
| 49 /** @enum {number} */ | 32 /** @enum {number} */ |
| 50 remoting.HostDispatcher.State = { | 33 remoting.HostDispatcher.State = { |
| 51 UNKNOWN: 0, | 34 UNKNOWN: 0, |
| 52 NATIVE_MESSAGING: 1, | 35 NATIVE_MESSAGING: 1, |
| 53 NPAPI: 2, | 36 NOT_INSTALLED: 2 |
| 54 NOT_INSTALLED: 3 | |
| 55 }; | 37 }; |
| 56 | 38 |
| 57 remoting.HostDispatcher.prototype.tryToInitialize_ = function() { | 39 remoting.HostDispatcher.prototype.tryToInitialize_ = function() { |
| 58 /** @type {remoting.HostDispatcher} */ | 40 /** @type {remoting.HostDispatcher} */ |
| 59 var that = this; | 41 var that = this; |
| 60 | 42 |
| 61 if (this.state_ != remoting.HostDispatcher.State.UNKNOWN) | 43 if (this.state_ != remoting.HostDispatcher.State.UNKNOWN) |
| 62 return; | 44 return; |
| 63 | 45 |
| 64 function sendPendingRequests() { | 46 function sendPendingRequests() { |
| 65 var pendingRequests = that.pendingRequests_; | 47 var pendingRequests = that.pendingRequests_; |
| 66 that.pendingRequests_ = []; | 48 that.pendingRequests_ = []; |
| 67 for (var i = 0; i < pendingRequests.length; i++) { | 49 for (var i = 0; i < pendingRequests.length; i++) { |
| 68 pendingRequests[i](); | 50 pendingRequests[i](); |
| 69 } | 51 } |
| 70 } | 52 } |
| 71 | 53 |
| 72 function onNativeMessagingInit() { | 54 function onNativeMessagingInit() { |
| 73 that.state_ = remoting.HostDispatcher.State.NATIVE_MESSAGING; | 55 that.state_ = remoting.HostDispatcher.State.NATIVE_MESSAGING; |
| 74 sendPendingRequests(); | 56 sendPendingRequests(); |
| 75 } | 57 } |
| 76 | 58 |
| 77 function onNativeMessagingFailed(error) { | 59 function onNativeMessagingFailed(error) { |
| 78 that.npapiHost_ = that.createPluginCallback_(); | 60 that.state_ = remoting.HostDispatcher.State.NOT_INSTALLED; |
| 79 | |
| 80 that.state_ = that.npapiHost_ ? remoting.HostDispatcher.State.NPAPI | |
| 81 : remoting.HostDispatcher.State.NOT_INSTALLED; | |
| 82 sendPendingRequests(); | 61 sendPendingRequests(); |
| 83 } | 62 } |
| 84 | 63 |
| 85 this.nativeMessagingHost_.initialize(onNativeMessagingInit, | 64 this.nativeMessagingHost_.initialize(onNativeMessagingInit, |
| 86 onNativeMessagingFailed); | 65 onNativeMessagingFailed); |
| 87 }; | 66 }; |
| 88 | 67 |
| 89 /** | 68 /** |
| 90 * @return {remoting.HostPlugin} | |
| 91 */ | |
| 92 remoting.HostDispatcher.prototype.getNpapiHost = function() { | |
| 93 return this.npapiHost_; | |
| 94 } | |
| 95 | |
| 96 /** | |
| 97 * @param {remoting.HostController.Feature} feature The feature to test for. | 69 * @param {remoting.HostController.Feature} feature The feature to test for. |
| 98 * @param {function(boolean):void} onDone | 70 * @param {function(boolean):void} onDone |
| 99 * @return {void} | 71 * @return {void} |
| 100 */ | 72 */ |
| 101 remoting.HostDispatcher.prototype.hasFeature = function( | 73 remoting.HostDispatcher.prototype.hasFeature = function( |
| 102 feature, onDone) { | 74 feature, onDone) { |
| 103 switch (this.state_) { | 75 switch (this.state_) { |
| 104 case remoting.HostDispatcher.State.UNKNOWN: | 76 case remoting.HostDispatcher.State.UNKNOWN: |
| 105 this.pendingRequests_.push( | 77 this.pendingRequests_.push( |
| 106 this.hasFeature.bind(this, feature, onDone)); | 78 this.hasFeature.bind(this, feature, onDone)); |
| 107 break; | 79 break; |
| 108 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | 80 case remoting.HostDispatcher.State.NATIVE_MESSAGING: |
| 109 onDone(this.nativeMessagingHost_.hasFeature(feature)); | 81 onDone(this.nativeMessagingHost_.hasFeature(feature)); |
| 110 break; | 82 break; |
| 111 case remoting.HostDispatcher.State.NPAPI: | |
| 112 // If this is an old NPAPI plugin that doesn't list supportedFeatures, | |
| 113 // assume it is an old plugin that doesn't support any new feature. | |
| 114 var supportedFeatures = []; | |
| 115 if (typeof(this.npapiHost_.supportedFeatures) == 'string') { | |
| 116 supportedFeatures = this.npapiHost_.supportedFeatures.split(' '); | |
| 117 } | |
| 118 onDone(supportedFeatures.indexOf(feature) >= 0); | |
| 119 break; | |
| 120 case remoting.HostDispatcher.State.NOT_INSTALLED: | 83 case remoting.HostDispatcher.State.NOT_INSTALLED: |
| 121 onDone(false); | 84 onDone(false); |
| 122 break; | 85 break; |
| 123 } | 86 } |
| 124 }; | 87 }; |
| 125 | 88 |
| 126 /** | 89 /** |
| 127 * @param {function(string):void} onDone | 90 * @param {function(string):void} onDone |
| 128 * @param {function(remoting.Error):void} onError | 91 * @param {function(remoting.Error):void} onError |
| 129 * @return {void} | 92 * @return {void} |
| 130 */ | 93 */ |
| 131 remoting.HostDispatcher.prototype.getHostName = function(onDone, onError) { | 94 remoting.HostDispatcher.prototype.getHostName = function(onDone, onError) { |
| 132 switch (this.state_) { | 95 switch (this.state_) { |
| 133 case remoting.HostDispatcher.State.UNKNOWN: | 96 case remoting.HostDispatcher.State.UNKNOWN: |
| 134 this.pendingRequests_.push( | 97 this.pendingRequests_.push( |
| 135 this.getHostName.bind(this, onDone, onError)); | 98 this.getHostName.bind(this, onDone, onError)); |
| 136 break; | 99 break; |
| 137 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | 100 case remoting.HostDispatcher.State.NATIVE_MESSAGING: |
| 138 this.nativeMessagingHost_.getHostName(onDone, onError); | 101 this.nativeMessagingHost_.getHostName(onDone, onError); |
| 139 break; | 102 break; |
| 140 case remoting.HostDispatcher.State.NPAPI: | |
| 141 try { | |
| 142 this.npapiHost_.getHostName(onDone); | |
| 143 } catch (err) { | |
| 144 onError(remoting.Error.MISSING_PLUGIN); | |
| 145 } | |
| 146 break; | |
| 147 case remoting.HostDispatcher.State.NOT_INSTALLED: | 103 case remoting.HostDispatcher.State.NOT_INSTALLED: |
| 148 onError(remoting.Error.MISSING_PLUGIN); | 104 onError(remoting.Error.MISSING_PLUGIN); |
| 149 break; | 105 break; |
| 150 } | 106 } |
| 151 }; | 107 }; |
| 152 | 108 |
| 153 /** | 109 /** |
| 154 * @param {string} hostId | 110 * @param {string} hostId |
| 155 * @param {string} pin | 111 * @param {string} pin |
| 156 * @param {function(string):void} onDone | 112 * @param {function(string):void} onDone |
| 157 * @param {function(remoting.Error):void} onError | 113 * @param {function(remoting.Error):void} onError |
| 158 * @return {void} | 114 * @return {void} |
| 159 */ | 115 */ |
| 160 remoting.HostDispatcher.prototype.getPinHash = | 116 remoting.HostDispatcher.prototype.getPinHash = |
| 161 function(hostId, pin, onDone, onError) { | 117 function(hostId, pin, onDone, onError) { |
| 162 switch (this.state_) { | 118 switch (this.state_) { |
| 163 case remoting.HostDispatcher.State.UNKNOWN: | 119 case remoting.HostDispatcher.State.UNKNOWN: |
| 164 this.pendingRequests_.push( | 120 this.pendingRequests_.push( |
| 165 this.getPinHash.bind(this, hostId, pin, onDone, onError)); | 121 this.getPinHash.bind(this, hostId, pin, onDone, onError)); |
| 166 break; | 122 break; |
| 167 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | 123 case remoting.HostDispatcher.State.NATIVE_MESSAGING: |
| 168 this.nativeMessagingHost_.getPinHash(hostId, pin, onDone, onError); | 124 this.nativeMessagingHost_.getPinHash(hostId, pin, onDone, onError); |
| 169 break; | 125 break; |
| 170 case remoting.HostDispatcher.State.NPAPI: | |
| 171 try { | |
| 172 this.npapiHost_.getPinHash(hostId, pin, onDone); | |
| 173 } catch (err) { | |
| 174 onError(remoting.Error.MISSING_PLUGIN); | |
| 175 } | |
| 176 break; | |
| 177 case remoting.HostDispatcher.State.NOT_INSTALLED: | 126 case remoting.HostDispatcher.State.NOT_INSTALLED: |
| 178 onError(remoting.Error.MISSING_PLUGIN); | 127 onError(remoting.Error.MISSING_PLUGIN); |
| 179 break; | 128 break; |
| 180 } | 129 } |
| 181 }; | 130 }; |
| 182 | 131 |
| 183 /** | 132 /** |
| 184 * @param {function(string, string):void} onDone | 133 * @param {function(string, string):void} onDone |
| 185 * @param {function(remoting.Error):void} onError | 134 * @param {function(remoting.Error):void} onError |
| 186 * @return {void} | 135 * @return {void} |
| 187 */ | 136 */ |
| 188 remoting.HostDispatcher.prototype.generateKeyPair = function(onDone, onError) { | 137 remoting.HostDispatcher.prototype.generateKeyPair = function(onDone, onError) { |
| 189 switch (this.state_) { | 138 switch (this.state_) { |
| 190 case remoting.HostDispatcher.State.UNKNOWN: | 139 case remoting.HostDispatcher.State.UNKNOWN: |
| 191 this.pendingRequests_.push( | 140 this.pendingRequests_.push( |
| 192 this.generateKeyPair.bind(this, onDone, onError)); | 141 this.generateKeyPair.bind(this, onDone, onError)); |
| 193 break; | 142 break; |
| 194 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | 143 case remoting.HostDispatcher.State.NATIVE_MESSAGING: |
| 195 this.nativeMessagingHost_.generateKeyPair(onDone, onError); | 144 this.nativeMessagingHost_.generateKeyPair(onDone, onError); |
| 196 break; | 145 break; |
| 197 case remoting.HostDispatcher.State.NPAPI: | |
| 198 try { | |
| 199 this.npapiHost_.generateKeyPair(onDone); | |
| 200 } catch (err) { | |
| 201 onError(remoting.Error.MISSING_PLUGIN); | |
| 202 } | |
| 203 break; | |
| 204 case remoting.HostDispatcher.State.NOT_INSTALLED: | 146 case remoting.HostDispatcher.State.NOT_INSTALLED: |
| 205 onError(remoting.Error.MISSING_PLUGIN); | 147 onError(remoting.Error.MISSING_PLUGIN); |
| 206 break; | 148 break; |
| 207 } | 149 } |
| 208 }; | 150 }; |
| 209 | 151 |
| 210 /** | 152 /** |
| 211 * @param {Object} config | 153 * @param {Object} config |
| 212 * @param {function(remoting.HostController.AsyncResult):void} onDone | 154 * @param {function(remoting.HostController.AsyncResult):void} onDone |
| 213 * @param {function(remoting.Error):void} onError | 155 * @param {function(remoting.Error):void} onError |
| 214 * @return {void} | 156 * @return {void} |
| 215 */ | 157 */ |
| 216 remoting.HostDispatcher.prototype.updateDaemonConfig = | 158 remoting.HostDispatcher.prototype.updateDaemonConfig = |
| 217 function(config, onDone, onError) { | 159 function(config, onDone, onError) { |
| 218 switch (this.state_) { | 160 switch (this.state_) { |
| 219 case remoting.HostDispatcher.State.UNKNOWN: | 161 case remoting.HostDispatcher.State.UNKNOWN: |
| 220 this.pendingRequests_.push( | 162 this.pendingRequests_.push( |
| 221 this.updateDaemonConfig.bind(this, config, onDone, onError)); | 163 this.updateDaemonConfig.bind(this, config, onDone, onError)); |
| 222 break; | 164 break; |
| 223 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | 165 case remoting.HostDispatcher.State.NATIVE_MESSAGING: |
| 224 this.nativeMessagingHost_.updateDaemonConfig(config, onDone, onError); | 166 this.nativeMessagingHost_.updateDaemonConfig(config, onDone, onError); |
| 225 break; | 167 break; |
| 226 case remoting.HostDispatcher.State.NPAPI: | |
| 227 try { | |
| 228 this.npapiHost_.updateDaemonConfig(JSON.stringify(config), onDone); | |
| 229 } catch (err) { | |
| 230 onError(remoting.Error.MISSING_PLUGIN); | |
| 231 } | |
| 232 break; | |
| 233 case remoting.HostDispatcher.State.NOT_INSTALLED: | 168 case remoting.HostDispatcher.State.NOT_INSTALLED: |
| 234 onError(remoting.Error.MISSING_PLUGIN); | 169 onError(remoting.Error.MISSING_PLUGIN); |
| 235 break; | 170 break; |
| 236 } | 171 } |
| 237 }; | 172 }; |
| 238 | 173 |
| 239 /** | 174 /** |
| 240 * @param {function(Object):void} onDone | 175 * @param {function(Object):void} onDone |
| 241 * @param {function(remoting.Error):void} onError | 176 * @param {function(remoting.Error):void} onError |
| 242 * @return {void} | 177 * @return {void} |
| 243 */ | 178 */ |
| 244 remoting.HostDispatcher.prototype.getDaemonConfig = function(onDone, onError) { | 179 remoting.HostDispatcher.prototype.getDaemonConfig = function(onDone, onError) { |
| 245 /** | |
| 246 * Converts the config string from the NPAPI plugin to an Object, to pass to | |
| 247 * |onDone|. | |
| 248 * @param {string} configStr | |
| 249 * @return {void} | |
| 250 */ | |
| 251 function callbackForNpapi(configStr) { | |
| 252 var config = jsonParseSafe(configStr); | |
| 253 if (typeof(config) != 'object') { | |
| 254 onError(remoting.Error.UNEXPECTED); | |
| 255 } else { | |
| 256 onDone(/** @type {Object} */ (config)); | |
| 257 } | |
| 258 } | |
| 259 | |
| 260 switch (this.state_) { | 180 switch (this.state_) { |
| 261 case remoting.HostDispatcher.State.UNKNOWN: | 181 case remoting.HostDispatcher.State.UNKNOWN: |
| 262 this.pendingRequests_.push( | 182 this.pendingRequests_.push( |
| 263 this.getDaemonConfig.bind(this, onDone, onError)); | 183 this.getDaemonConfig.bind(this, onDone, onError)); |
| 264 break; | 184 break; |
| 265 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | 185 case remoting.HostDispatcher.State.NATIVE_MESSAGING: |
| 266 this.nativeMessagingHost_.getDaemonConfig(onDone, onError); | 186 this.nativeMessagingHost_.getDaemonConfig(onDone, onError); |
| 267 break; | 187 break; |
| 268 case remoting.HostDispatcher.State.NPAPI: | |
| 269 try { | |
| 270 this.npapiHost_.getDaemonConfig(callbackForNpapi); | |
| 271 } catch (err) { | |
| 272 onError(remoting.Error.MISSING_PLUGIN); | |
| 273 } | |
| 274 break; | |
| 275 case remoting.HostDispatcher.State.NOT_INSTALLED: | 188 case remoting.HostDispatcher.State.NOT_INSTALLED: |
| 276 onDone({}); | 189 onDone({}); |
| 277 break; | 190 break; |
| 278 } | 191 } |
| 279 }; | 192 }; |
| 280 | 193 |
| 281 /** | 194 /** |
| 282 * @param {function(string):void} onDone | 195 * @param {function(string):void} onDone |
| 283 * @param {function(remoting.Error):void} onError | 196 * @param {function(remoting.Error):void} onError |
| 284 * @return {void} | 197 * @return {void} |
| 285 */ | 198 */ |
| 286 remoting.HostDispatcher.prototype.getDaemonVersion = function(onDone, onError) { | 199 remoting.HostDispatcher.prototype.getDaemonVersion = function(onDone, onError) { |
| 287 switch (this.state_) { | 200 switch (this.state_) { |
| 288 case remoting.HostDispatcher.State.UNKNOWN: | 201 case remoting.HostDispatcher.State.UNKNOWN: |
| 289 this.pendingRequests_.push( | 202 this.pendingRequests_.push( |
| 290 this.getDaemonVersion.bind(this, onDone, onError)); | 203 this.getDaemonVersion.bind(this, onDone, onError)); |
| 291 break; | 204 break; |
| 292 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | 205 case remoting.HostDispatcher.State.NATIVE_MESSAGING: |
| 293 onDone(this.nativeMessagingHost_.getDaemonVersion()); | 206 onDone(this.nativeMessagingHost_.getDaemonVersion()); |
| 294 break; | 207 break; |
| 295 case remoting.HostDispatcher.State.NPAPI: | |
| 296 try { | |
| 297 this.npapiHost_.getDaemonVersion(onDone); | |
| 298 } catch (err) { | |
| 299 onError(remoting.Error.MISSING_PLUGIN); | |
| 300 } | |
| 301 break; | |
| 302 case remoting.HostDispatcher.State.NOT_INSTALLED: | 208 case remoting.HostDispatcher.State.NOT_INSTALLED: |
| 303 onError(remoting.Error.MISSING_PLUGIN); | 209 onError(remoting.Error.MISSING_PLUGIN); |
| 304 break; | 210 break; |
| 305 } | 211 } |
| 306 }; | 212 }; |
| 307 | 213 |
| 308 /** | 214 /** |
| 309 * @param {function(boolean, boolean, boolean):void} onDone | 215 * @param {function(boolean, boolean, boolean):void} onDone |
| 310 * @param {function(remoting.Error):void} onError | 216 * @param {function(remoting.Error):void} onError |
| 311 * @return {void} | 217 * @return {void} |
| 312 */ | 218 */ |
| 313 remoting.HostDispatcher.prototype.getUsageStatsConsent = | 219 remoting.HostDispatcher.prototype.getUsageStatsConsent = |
| 314 function(onDone, onError) { | 220 function(onDone, onError) { |
| 315 switch (this.state_) { | 221 switch (this.state_) { |
| 316 case remoting.HostDispatcher.State.UNKNOWN: | 222 case remoting.HostDispatcher.State.UNKNOWN: |
| 317 this.pendingRequests_.push( | 223 this.pendingRequests_.push( |
| 318 this.getUsageStatsConsent.bind(this, onDone, onError)); | 224 this.getUsageStatsConsent.bind(this, onDone, onError)); |
| 319 break; | 225 break; |
| 320 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | 226 case remoting.HostDispatcher.State.NATIVE_MESSAGING: |
| 321 this.nativeMessagingHost_.getUsageStatsConsent(onDone, onError); | 227 this.nativeMessagingHost_.getUsageStatsConsent(onDone, onError); |
| 322 break; | 228 break; |
| 323 case remoting.HostDispatcher.State.NPAPI: | |
| 324 try { | |
| 325 this.npapiHost_.getUsageStatsConsent(onDone); | |
| 326 } catch (err) { | |
| 327 onError(remoting.Error.MISSING_PLUGIN); | |
| 328 } | |
| 329 break; | |
| 330 case remoting.HostDispatcher.State.NOT_INSTALLED: | 229 case remoting.HostDispatcher.State.NOT_INSTALLED: |
| 331 onError(remoting.Error.MISSING_PLUGIN); | 230 onError(remoting.Error.MISSING_PLUGIN); |
| 332 break; | 231 break; |
| 333 } | |
| 334 }; | |
| 335 | |
| 336 /** | |
| 337 * This function installs the host using the NPAPI plugin and should only be | |
| 338 * called on Windows. | |
| 339 * | |
| 340 * @param {function(remoting.HostController.AsyncResult):void} onDone | |
| 341 * @param {function(remoting.Error):void} onError | |
| 342 * @return {void} | |
| 343 */ | |
| 344 remoting.HostDispatcher.prototype.installHost = function(onDone, onError) { | |
| 345 switch (this.state_) { | |
| 346 case remoting.HostDispatcher.State.UNKNOWN: | |
| 347 this.pendingRequests_.push(this.installHost.bind(this, onDone, onError)); | |
| 348 break; | |
| 349 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | |
| 350 // Host already installed, no action needed. | |
| 351 onDone(remoting.HostController.AsyncResult.OK); | |
| 352 break; | |
| 353 case remoting.HostDispatcher.State.NPAPI: | |
| 354 try { | |
| 355 this.npapiHost_.installHost(onDone); | |
| 356 } catch (err) { | |
| 357 onError(remoting.Error.MISSING_PLUGIN); | |
| 358 } | |
| 359 break; | |
| 360 case remoting.HostDispatcher.State.NOT_INSTALLED: | |
| 361 onError(remoting.Error.MISSING_PLUGIN); | |
| 362 break; | |
| 363 } | 232 } |
| 364 }; | 233 }; |
| 365 | 234 |
| 366 /** | 235 /** |
| 367 * @param {Object} config | 236 * @param {Object} config |
| 368 * @param {boolean} consent | 237 * @param {boolean} consent |
| 369 * @param {function(remoting.HostController.AsyncResult):void} onDone | 238 * @param {function(remoting.HostController.AsyncResult):void} onDone |
| 370 * @param {function(remoting.Error):void} onError | 239 * @param {function(remoting.Error):void} onError |
| 371 * @return {void} | 240 * @return {void} |
| 372 */ | 241 */ |
| 373 remoting.HostDispatcher.prototype.startDaemon = | 242 remoting.HostDispatcher.prototype.startDaemon = |
| 374 function(config, consent, onDone, onError) { | 243 function(config, consent, onDone, onError) { |
| 375 switch (this.state_) { | 244 switch (this.state_) { |
| 376 case remoting.HostDispatcher.State.UNKNOWN: | 245 case remoting.HostDispatcher.State.UNKNOWN: |
| 377 this.pendingRequests_.push( | 246 this.pendingRequests_.push( |
| 378 this.startDaemon.bind(this, config, consent, onDone, onError)); | 247 this.startDaemon.bind(this, config, consent, onDone, onError)); |
| 379 break; | 248 break; |
| 380 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | 249 case remoting.HostDispatcher.State.NATIVE_MESSAGING: |
| 381 this.nativeMessagingHost_.startDaemon(config, consent, onDone, onError); | 250 this.nativeMessagingHost_.startDaemon(config, consent, onDone, onError); |
| 382 break; | 251 break; |
| 383 case remoting.HostDispatcher.State.NPAPI: | |
| 384 try { | |
| 385 this.npapiHost_.startDaemon(JSON.stringify(config), consent, onDone); | |
| 386 } catch (err) { | |
| 387 onError(remoting.Error.MISSING_PLUGIN); | |
| 388 } | |
| 389 break; | |
| 390 case remoting.HostDispatcher.State.NOT_INSTALLED: | 252 case remoting.HostDispatcher.State.NOT_INSTALLED: |
| 391 onError(remoting.Error.MISSING_PLUGIN); | 253 onError(remoting.Error.MISSING_PLUGIN); |
| 392 break; | 254 break; |
| 393 } | 255 } |
| 394 }; | 256 }; |
| 395 | 257 |
| 396 /** | 258 /** |
| 397 * @param {function(remoting.HostController.AsyncResult):void} onDone | 259 * @param {function(remoting.HostController.AsyncResult):void} onDone |
| 398 * @param {function(remoting.Error):void} onError | 260 * @param {function(remoting.Error):void} onError |
| 399 * @return {void} | 261 * @return {void} |
| 400 */ | 262 */ |
| 401 remoting.HostDispatcher.prototype.stopDaemon = function(onDone, onError) { | 263 remoting.HostDispatcher.prototype.stopDaemon = function(onDone, onError) { |
| 402 switch (this.state_) { | 264 switch (this.state_) { |
| 403 case remoting.HostDispatcher.State.UNKNOWN: | 265 case remoting.HostDispatcher.State.UNKNOWN: |
| 404 this.pendingRequests_.push(this.stopDaemon.bind(this, onDone, onError)); | 266 this.pendingRequests_.push(this.stopDaemon.bind(this, onDone, onError)); |
| 405 break; | 267 break; |
| 406 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | 268 case remoting.HostDispatcher.State.NATIVE_MESSAGING: |
| 407 this.nativeMessagingHost_.stopDaemon(onDone, onError); | 269 this.nativeMessagingHost_.stopDaemon(onDone, onError); |
| 408 break; | 270 break; |
| 409 case remoting.HostDispatcher.State.NPAPI: | |
| 410 try { | |
| 411 this.npapiHost_.stopDaemon(onDone); | |
| 412 } catch (err) { | |
| 413 onError(remoting.Error.MISSING_PLUGIN); | |
| 414 } | |
| 415 break; | |
| 416 case remoting.HostDispatcher.State.NOT_INSTALLED: | 271 case remoting.HostDispatcher.State.NOT_INSTALLED: |
| 417 onError(remoting.Error.MISSING_PLUGIN); | 272 onError(remoting.Error.MISSING_PLUGIN); |
| 418 break; | 273 break; |
| 419 } | 274 } |
| 420 }; | 275 }; |
| 421 | 276 |
| 422 /** | 277 /** |
| 423 * @param {function(remoting.HostController.State):void} onDone | 278 * @param {function(remoting.HostController.State):void} onDone |
| 424 * @param {function(remoting.Error):void} onError | 279 * @param {function(remoting.Error):void} onError |
| 425 * @return {void} | 280 * @return {void} |
| (...skipping 17 matching lines...) Expand all Loading... |
| 443 remoting.HostDispatcher.prototype.getDaemonStateInternal_ = | 298 remoting.HostDispatcher.prototype.getDaemonStateInternal_ = |
| 444 function(onDone, onError) { | 299 function(onDone, onError) { |
| 445 switch (this.state_) { | 300 switch (this.state_) { |
| 446 case remoting.HostDispatcher.State.UNKNOWN: | 301 case remoting.HostDispatcher.State.UNKNOWN: |
| 447 this.pendingRequests_.push( | 302 this.pendingRequests_.push( |
| 448 this.getDaemonStateInternal_.bind(this, onDone, onError)); | 303 this.getDaemonStateInternal_.bind(this, onDone, onError)); |
| 449 break; | 304 break; |
| 450 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | 305 case remoting.HostDispatcher.State.NATIVE_MESSAGING: |
| 451 this.nativeMessagingHost_.getDaemonState(onDone, onError); | 306 this.nativeMessagingHost_.getDaemonState(onDone, onError); |
| 452 break; | 307 break; |
| 453 case remoting.HostDispatcher.State.NPAPI: | |
| 454 // Call the callback directly, since NPAPI exposes the state directly as | |
| 455 // a field member, rather than an asynchronous method. | |
| 456 var state = this.npapiHost_.daemonState; | |
| 457 if (state === undefined) { | |
| 458 onError(remoting.Error.MISSING_PLUGIN); | |
| 459 } else { | |
| 460 onDone(state); | |
| 461 } | |
| 462 break; | |
| 463 case remoting.HostDispatcher.State.NOT_INSTALLED: | 308 case remoting.HostDispatcher.State.NOT_INSTALLED: |
| 464 onDone(remoting.HostController.State.NOT_INSTALLED); | 309 onDone(remoting.HostController.State.NOT_INSTALLED); |
| 465 break; | 310 break; |
| 466 } | 311 } |
| 467 }; | 312 }; |
| 468 | 313 |
| 469 /** | 314 /** |
| 470 * @param {function(Array.<remoting.PairedClient>):void} onDone | 315 * @param {function(Array.<remoting.PairedClient>):void} onDone |
| 471 * @param {function(remoting.Error):void} onError | 316 * @param {function(remoting.Error):void} onError |
| 472 * @return {void} | 317 * @return {void} |
| 473 */ | 318 */ |
| 474 remoting.HostDispatcher.prototype.getPairedClients = function(onDone, onError) { | 319 remoting.HostDispatcher.prototype.getPairedClients = function(onDone, onError) { |
| 475 /** | |
| 476 * Converts the JSON string from the NPAPI plugin to Array.<PairedClient>, to | |
| 477 * pass to |onDone|. | |
| 478 * @param {string} pairedClientsJson | |
| 479 * @return {void} | |
| 480 */ | |
| 481 function callbackForNpapi(pairedClientsJson) { | |
| 482 var pairedClients = remoting.PairedClient.convertToPairedClientArray( | |
| 483 jsonParseSafe(pairedClientsJson)); | |
| 484 if (pairedClients != null) { | |
| 485 onDone(pairedClients); | |
| 486 } else { | |
| 487 onError(remoting.Error.UNEXPECTED); | |
| 488 } | |
| 489 } | |
| 490 | |
| 491 switch (this.state_) { | 320 switch (this.state_) { |
| 492 case remoting.HostDispatcher.State.UNKNOWN: | 321 case remoting.HostDispatcher.State.UNKNOWN: |
| 493 this.pendingRequests_.push( | 322 this.pendingRequests_.push( |
| 494 this.getPairedClients.bind(this, onDone, onError)); | 323 this.getPairedClients.bind(this, onDone, onError)); |
| 495 break; | 324 break; |
| 496 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | 325 case remoting.HostDispatcher.State.NATIVE_MESSAGING: |
| 497 this.nativeMessagingHost_.getPairedClients(onDone, onError); | 326 this.nativeMessagingHost_.getPairedClients(onDone, onError); |
| 498 break; | 327 break; |
| 499 case remoting.HostDispatcher.State.NPAPI: | |
| 500 try { | |
| 501 this.npapiHost_.getPairedClients(callbackForNpapi); | |
| 502 } catch (err) { | |
| 503 onError(remoting.Error.MISSING_PLUGIN); | |
| 504 } | |
| 505 break; | |
| 506 case remoting.HostDispatcher.State.NOT_INSTALLED: | 328 case remoting.HostDispatcher.State.NOT_INSTALLED: |
| 507 onError(remoting.Error.MISSING_PLUGIN); | 329 onError(remoting.Error.MISSING_PLUGIN); |
| 508 break; | 330 break; |
| 509 } | 331 } |
| 510 }; | 332 }; |
| 511 | 333 |
| 512 /** | 334 /** |
| 513 * The pairing API returns a boolean to indicate success or failure, but | 335 * The pairing API returns a boolean to indicate success or failure, but |
| 514 * the JS API is defined in terms of onDone and onError callbacks. This | 336 * the JS API is defined in terms of onDone and onError callbacks. This |
| 515 * function converts one to the other. | 337 * function converts one to the other. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 537 var callback = | 359 var callback = |
| 538 remoting.HostDispatcher.runCallback_.bind(null, onDone, onError); | 360 remoting.HostDispatcher.runCallback_.bind(null, onDone, onError); |
| 539 switch (this.state_) { | 361 switch (this.state_) { |
| 540 case remoting.HostDispatcher.State.UNKNOWN: | 362 case remoting.HostDispatcher.State.UNKNOWN: |
| 541 this.pendingRequests_.push( | 363 this.pendingRequests_.push( |
| 542 this.clearPairedClients.bind(this, onDone, onError)); | 364 this.clearPairedClients.bind(this, onDone, onError)); |
| 543 break; | 365 break; |
| 544 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | 366 case remoting.HostDispatcher.State.NATIVE_MESSAGING: |
| 545 this.nativeMessagingHost_.clearPairedClients(callback, onError); | 367 this.nativeMessagingHost_.clearPairedClients(callback, onError); |
| 546 break; | 368 break; |
| 547 case remoting.HostDispatcher.State.NPAPI: | |
| 548 try { | |
| 549 this.npapiHost_.clearPairedClients(callback); | |
| 550 } catch (err) { | |
| 551 onError(remoting.Error.MISSING_PLUGIN); | |
| 552 } | |
| 553 break; | |
| 554 case remoting.HostDispatcher.State.NOT_INSTALLED: | 369 case remoting.HostDispatcher.State.NOT_INSTALLED: |
| 555 onError(remoting.Error.MISSING_PLUGIN); | 370 onError(remoting.Error.MISSING_PLUGIN); |
| 556 break; | 371 break; |
| 557 } | 372 } |
| 558 }; | 373 }; |
| 559 | 374 |
| 560 /** | 375 /** |
| 561 * @param {string} client | 376 * @param {string} client |
| 562 * @param {function():void} onDone | 377 * @param {function():void} onDone |
| 563 * @param {function(remoting.Error):void} onError | 378 * @param {function(remoting.Error):void} onError |
| 564 * @return {void} | 379 * @return {void} |
| 565 */ | 380 */ |
| 566 remoting.HostDispatcher.prototype.deletePairedClient = | 381 remoting.HostDispatcher.prototype.deletePairedClient = |
| 567 function(client, onDone, onError) { | 382 function(client, onDone, onError) { |
| 568 var callback = | 383 var callback = |
| 569 remoting.HostDispatcher.runCallback_.bind(null, onDone, onError); | 384 remoting.HostDispatcher.runCallback_.bind(null, onDone, onError); |
| 570 switch (this.state_) { | 385 switch (this.state_) { |
| 571 case remoting.HostDispatcher.State.UNKNOWN: | 386 case remoting.HostDispatcher.State.UNKNOWN: |
| 572 this.pendingRequests_.push( | 387 this.pendingRequests_.push( |
| 573 this.deletePairedClient.bind(this, client, onDone, onError)); | 388 this.deletePairedClient.bind(this, client, onDone, onError)); |
| 574 break; | 389 break; |
| 575 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | 390 case remoting.HostDispatcher.State.NATIVE_MESSAGING: |
| 576 this.nativeMessagingHost_.deletePairedClient(client, callback, onError); | 391 this.nativeMessagingHost_.deletePairedClient(client, callback, onError); |
| 577 break; | 392 break; |
| 578 case remoting.HostDispatcher.State.NPAPI: | |
| 579 try { | |
| 580 this.npapiHost_.deletePairedClient(client, callback); | |
| 581 } catch (err) { | |
| 582 onError(remoting.Error.MISSING_PLUGIN); | |
| 583 } | |
| 584 break; | |
| 585 case remoting.HostDispatcher.State.NOT_INSTALLED: | 393 case remoting.HostDispatcher.State.NOT_INSTALLED: |
| 586 onError(remoting.Error.MISSING_PLUGIN); | 394 onError(remoting.Error.MISSING_PLUGIN); |
| 587 break; | 395 break; |
| 588 } | 396 } |
| 589 }; | 397 }; |
| 590 | 398 |
| 591 /** | 399 /** |
| 592 * @param {function(string):void} onDone | 400 * @param {function(string):void} onDone |
| 593 * @param {function(remoting.Error):void} onError | 401 * @param {function(remoting.Error):void} onError |
| 594 * @return {void} | 402 * @return {void} |
| 595 */ | 403 */ |
| 596 remoting.HostDispatcher.prototype.getHostClientId = | 404 remoting.HostDispatcher.prototype.getHostClientId = |
| 597 function(onDone, onError) { | 405 function(onDone, onError) { |
| 598 switch (this.state_) { | 406 switch (this.state_) { |
| 599 case remoting.HostDispatcher.State.UNKNOWN: | 407 case remoting.HostDispatcher.State.UNKNOWN: |
| 600 this.pendingRequests_.push( | 408 this.pendingRequests_.push( |
| 601 this.getHostClientId.bind(this, onDone, onError)); | 409 this.getHostClientId.bind(this, onDone, onError)); |
| 602 break; | 410 break; |
| 603 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | 411 case remoting.HostDispatcher.State.NATIVE_MESSAGING: |
| 604 this.nativeMessagingHost_.getHostClientId(onDone, onError); | 412 this.nativeMessagingHost_.getHostClientId(onDone, onError); |
| 605 break; | 413 break; |
| 606 case remoting.HostDispatcher.State.NPAPI: | |
| 607 // The NPAPI plugin is packaged with the webapp, not the host, so it | |
| 608 // doesn't have access to the API keys baked into the installed host. | |
| 609 onError(remoting.Error.UNEXPECTED); | |
| 610 break; | |
| 611 case remoting.HostDispatcher.State.NOT_INSTALLED: | 414 case remoting.HostDispatcher.State.NOT_INSTALLED: |
| 612 onError(remoting.Error.MISSING_PLUGIN); | 415 onError(remoting.Error.MISSING_PLUGIN); |
| 613 break; | 416 break; |
| 614 } | 417 } |
| 615 }; | 418 }; |
| 616 | 419 |
| 617 /** | 420 /** |
| 618 * @param {string} authorizationCode | 421 * @param {string} authorizationCode |
| 619 * @param {function(string, string):void} onDone | 422 * @param {function(string, string):void} onDone |
| 620 * @param {function(remoting.Error):void} onError | 423 * @param {function(remoting.Error):void} onError |
| 621 * @return {void} | 424 * @return {void} |
| 622 */ | 425 */ |
| 623 remoting.HostDispatcher.prototype.getCredentialsFromAuthCode = | 426 remoting.HostDispatcher.prototype.getCredentialsFromAuthCode = |
| 624 function(authorizationCode, onDone, onError) { | 427 function(authorizationCode, onDone, onError) { |
| 625 switch (this.state_) { | 428 switch (this.state_) { |
| 626 case remoting.HostDispatcher.State.UNKNOWN: | 429 case remoting.HostDispatcher.State.UNKNOWN: |
| 627 this.pendingRequests_.push( | 430 this.pendingRequests_.push( |
| 628 this.getCredentialsFromAuthCode.bind( | 431 this.getCredentialsFromAuthCode.bind( |
| 629 this, authorizationCode, onDone, onError)); | 432 this, authorizationCode, onDone, onError)); |
| 630 break; | 433 break; |
| 631 case remoting.HostDispatcher.State.NATIVE_MESSAGING: | 434 case remoting.HostDispatcher.State.NATIVE_MESSAGING: |
| 632 this.nativeMessagingHost_.getCredentialsFromAuthCode( | 435 this.nativeMessagingHost_.getCredentialsFromAuthCode( |
| 633 authorizationCode, onDone, onError); | 436 authorizationCode, onDone, onError); |
| 634 break; | 437 break; |
| 635 case remoting.HostDispatcher.State.NPAPI: | |
| 636 // The NPAPI plugin is packaged with the webapp, not the host, so it | |
| 637 // doesn't have access to the API keys baked into the installed host. | |
| 638 onError(remoting.Error.UNEXPECTED); | |
| 639 break; | |
| 640 case remoting.HostDispatcher.State.NOT_INSTALLED: | 438 case remoting.HostDispatcher.State.NOT_INSTALLED: |
| 641 onError(remoting.Error.MISSING_PLUGIN); | 439 onError(remoting.Error.MISSING_PLUGIN); |
| 642 break; | 440 break; |
| 643 } | 441 } |
| 644 }; | 442 }; |
| 645 | |
| 646 /** | |
| 647 * Returns true if the NPAPI plugin is being used. | |
| 648 * @return {boolean} | |
| 649 */ | |
| 650 remoting.HostDispatcher.prototype.usingNpapiPlugin = function() { | |
| 651 return this.state_ == remoting.HostDispatcher.State.NPAPI; | |
| 652 } | |
| OLD | NEW |