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.
7 * This class provides an interface between the HostController and either the
8 * NativeMessaging Host.
13 /** @suppress {duplicate} */
14 var remoting = remoting || {};
19 remoting.HostDispatcher = function() {
20 /** @type {remoting.HostNativeMessaging} @private */
21 this.nativeMessagingHost_ = new remoting.HostNativeMessaging();
23 /** @type {remoting.HostDispatcher.State} @private */
24 this.state_ = remoting.HostDispatcher.State.UNKNOWN;
26 /** @type {Array.<function()>} @private */
27 this.pendingRequests_ = [];
29 this.tryToInitialize_();
33 remoting.HostDispatcher.State = {
39 remoting.HostDispatcher.prototype.tryToInitialize_ = function() {
40 /** @type {remoting.HostDispatcher} */
43 if (this.state_ != remoting.HostDispatcher.State.UNKNOWN)
46 function sendPendingRequests() {
47 var pendingRequests = that.pendingRequests_;
48 that.pendingRequests_ = [];
49 for (var i = 0; i < pendingRequests.length; i++) {
54 function onNativeMessagingInit() {
55 that.state_ = remoting.HostDispatcher.State.NATIVE_MESSAGING;
56 sendPendingRequests();
59 function onNativeMessagingFailed(error) {
60 that.state_ = remoting.HostDispatcher.State.NOT_INSTALLED;
61 sendPendingRequests();
64 this.nativeMessagingHost_.initialize(onNativeMessagingInit,
65 onNativeMessagingFailed);
69 * @param {remoting.HostController.Feature} feature The feature to test for.
70 * @param {function(boolean):void} onDone
73 remoting.HostDispatcher.prototype.hasFeature = function(
75 switch (this.state_) {
76 case remoting.HostDispatcher.State.UNKNOWN:
77 this.pendingRequests_.push(
78 this.hasFeature.bind(this, feature, onDone));
80 case remoting.HostDispatcher.State.NATIVE_MESSAGING:
81 onDone(this.nativeMessagingHost_.hasFeature(feature));
83 case remoting.HostDispatcher.State.NOT_INSTALLED:
90 * @param {function(string):void} onDone
91 * @param {function(remoting.Error):void} onError
94 remoting.HostDispatcher.prototype.getHostName = function(onDone, onError) {
95 switch (this.state_) {
96 case remoting.HostDispatcher.State.UNKNOWN:
97 this.pendingRequests_.push(
98 this.getHostName.bind(this, onDone, onError));
100 case remoting.HostDispatcher.State.NATIVE_MESSAGING:
101 this.nativeMessagingHost_.getHostName(onDone, onError);
103 case remoting.HostDispatcher.State.NOT_INSTALLED:
104 onError(remoting.Error.MISSING_PLUGIN);
110 * @param {string} hostId
111 * @param {string} pin
112 * @param {function(string):void} onDone
113 * @param {function(remoting.Error):void} onError
116 remoting.HostDispatcher.prototype.getPinHash =
117 function(hostId, pin, onDone, onError) {
118 switch (this.state_) {
119 case remoting.HostDispatcher.State.UNKNOWN:
120 this.pendingRequests_.push(
121 this.getPinHash.bind(this, hostId, pin, onDone, onError));
123 case remoting.HostDispatcher.State.NATIVE_MESSAGING:
124 this.nativeMessagingHost_.getPinHash(hostId, pin, onDone, onError);
126 case remoting.HostDispatcher.State.NOT_INSTALLED:
127 onError(remoting.Error.MISSING_PLUGIN);
133 * @param {function(string, string):void} onDone
134 * @param {function(remoting.Error):void} onError
137 remoting.HostDispatcher.prototype.generateKeyPair = function(onDone, onError) {
138 switch (this.state_) {
139 case remoting.HostDispatcher.State.UNKNOWN:
140 this.pendingRequests_.push(
141 this.generateKeyPair.bind(this, onDone, onError));
143 case remoting.HostDispatcher.State.NATIVE_MESSAGING:
144 this.nativeMessagingHost_.generateKeyPair(onDone, onError);
146 case remoting.HostDispatcher.State.NOT_INSTALLED:
147 onError(remoting.Error.MISSING_PLUGIN);
153 * @param {Object} config
154 * @param {function(remoting.HostController.AsyncResult):void} onDone
155 * @param {function(remoting.Error):void} onError
158 remoting.HostDispatcher.prototype.updateDaemonConfig =
159 function(config, onDone, onError) {
160 switch (this.state_) {
161 case remoting.HostDispatcher.State.UNKNOWN:
162 this.pendingRequests_.push(
163 this.updateDaemonConfig.bind(this, config, onDone, onError));
165 case remoting.HostDispatcher.State.NATIVE_MESSAGING:
166 this.nativeMessagingHost_.updateDaemonConfig(config, onDone, onError);
168 case remoting.HostDispatcher.State.NOT_INSTALLED:
169 onError(remoting.Error.MISSING_PLUGIN);
175 * @param {function(Object):void} onDone
176 * @param {function(remoting.Error):void} onError
179 remoting.HostDispatcher.prototype.getDaemonConfig = function(onDone, onError) {
180 switch (this.state_) {
181 case remoting.HostDispatcher.State.UNKNOWN:
182 this.pendingRequests_.push(
183 this.getDaemonConfig.bind(this, onDone, onError));
185 case remoting.HostDispatcher.State.NATIVE_MESSAGING:
186 this.nativeMessagingHost_.getDaemonConfig(onDone, onError);
188 case remoting.HostDispatcher.State.NOT_INSTALLED:
195 * @param {function(string):void} onDone
196 * @param {function(remoting.Error):void} onError
199 remoting.HostDispatcher.prototype.getDaemonVersion = function(onDone, onError) {
200 switch (this.state_) {
201 case remoting.HostDispatcher.State.UNKNOWN:
202 this.pendingRequests_.push(
203 this.getDaemonVersion.bind(this, onDone, onError));
205 case remoting.HostDispatcher.State.NATIVE_MESSAGING:
206 onDone(this.nativeMessagingHost_.getDaemonVersion());
208 case remoting.HostDispatcher.State.NOT_INSTALLED:
209 onError(remoting.Error.MISSING_PLUGIN);
215 * @param {function(boolean, boolean, boolean):void} onDone
216 * @param {function(remoting.Error):void} onError
219 remoting.HostDispatcher.prototype.getUsageStatsConsent =
220 function(onDone, onError) {
221 switch (this.state_) {
222 case remoting.HostDispatcher.State.UNKNOWN:
223 this.pendingRequests_.push(
224 this.getUsageStatsConsent.bind(this, onDone, onError));
226 case remoting.HostDispatcher.State.NATIVE_MESSAGING:
227 this.nativeMessagingHost_.getUsageStatsConsent(onDone, onError);
229 case remoting.HostDispatcher.State.NOT_INSTALLED:
230 onError(remoting.Error.MISSING_PLUGIN);
236 * @param {Object} config
237 * @param {boolean} consent
238 * @param {function(remoting.HostController.AsyncResult):void} onDone
239 * @param {function(remoting.Error):void} onError
242 remoting.HostDispatcher.prototype.startDaemon =
243 function(config, consent, onDone, onError) {
244 switch (this.state_) {
245 case remoting.HostDispatcher.State.UNKNOWN:
246 this.pendingRequests_.push(
247 this.startDaemon.bind(this, config, consent, onDone, onError));
249 case remoting.HostDispatcher.State.NATIVE_MESSAGING:
250 this.nativeMessagingHost_.startDaemon(config, consent, onDone, onError);
252 case remoting.HostDispatcher.State.NOT_INSTALLED:
253 onError(remoting.Error.MISSING_PLUGIN);
259 * @param {function(remoting.HostController.AsyncResult):void} onDone
260 * @param {function(remoting.Error):void} onError
263 remoting.HostDispatcher.prototype.stopDaemon = function(onDone, onError) {
264 switch (this.state_) {
265 case remoting.HostDispatcher.State.UNKNOWN:
266 this.pendingRequests_.push(this.stopDaemon.bind(this, onDone, onError));
268 case remoting.HostDispatcher.State.NATIVE_MESSAGING:
269 this.nativeMessagingHost_.stopDaemon(onDone, onError);
271 case remoting.HostDispatcher.State.NOT_INSTALLED:
272 onError(remoting.Error.MISSING_PLUGIN);
278 * @param {function(remoting.HostController.State):void} onDone
279 * @param {function(remoting.Error):void} onError
282 remoting.HostDispatcher.prototype.getDaemonState = function(onDone, onError) {
283 // If the host was in not-initialized state try initializing it again in case
285 if (this.state_ == remoting.HostDispatcher.State.NOT_INSTALLED) {
286 this.state_ = remoting.HostDispatcher.State.UNKNOWN;
287 this.tryToInitialize_();
290 this.getDaemonStateInternal_(onDone, onError);
294 * @param {function(remoting.HostController.State):void} onDone
295 * @param {function(remoting.Error):void} onError
298 remoting.HostDispatcher.prototype.getDaemonStateInternal_ =
299 function(onDone, onError) {
300 switch (this.state_) {
301 case remoting.HostDispatcher.State.UNKNOWN:
302 this.pendingRequests_.push(
303 this.getDaemonStateInternal_.bind(this, onDone, onError));
305 case remoting.HostDispatcher.State.NATIVE_MESSAGING:
306 this.nativeMessagingHost_.getDaemonState(onDone, onError);
308 case remoting.HostDispatcher.State.NOT_INSTALLED:
309 onDone(remoting.HostController.State.NOT_INSTALLED);
315 * @param {function(Array.<remoting.PairedClient>):void} onDone
316 * @param {function(remoting.Error):void} onError
319 remoting.HostDispatcher.prototype.getPairedClients = function(onDone, onError) {
320 switch (this.state_) {
321 case remoting.HostDispatcher.State.UNKNOWN:
322 this.pendingRequests_.push(
323 this.getPairedClients.bind(this, onDone, onError));
325 case remoting.HostDispatcher.State.NATIVE_MESSAGING:
326 this.nativeMessagingHost_.getPairedClients(onDone, onError);
328 case remoting.HostDispatcher.State.NOT_INSTALLED:
329 onError(remoting.Error.MISSING_PLUGIN);
335 * The pairing API returns a boolean to indicate success or failure, but
336 * the JS API is defined in terms of onDone and onError callbacks. This
337 * function converts one to the other.
339 * @param {function():void} onDone Success callback.
340 * @param {function(remoting.Error):void} onError Error callback.
341 * @param {boolean} success True if the operation succeeded; false otherwise.
344 remoting.HostDispatcher.runCallback_ = function(onDone, onError, success) {
348 onError(remoting.Error.UNEXPECTED);
353 * @param {function():void} onDone
354 * @param {function(remoting.Error):void} onError
357 remoting.HostDispatcher.prototype.clearPairedClients =
358 function(onDone, onError) {
360 remoting.HostDispatcher.runCallback_.bind(null, onDone, onError);
361 switch (this.state_) {
362 case remoting.HostDispatcher.State.UNKNOWN:
363 this.pendingRequests_.push(
364 this.clearPairedClients.bind(this, onDone, onError));
366 case remoting.HostDispatcher.State.NATIVE_MESSAGING:
367 this.nativeMessagingHost_.clearPairedClients(callback, onError);
369 case remoting.HostDispatcher.State.NOT_INSTALLED:
370 onError(remoting.Error.MISSING_PLUGIN);
376 * @param {string} client
377 * @param {function():void} onDone
378 * @param {function(remoting.Error):void} onError
381 remoting.HostDispatcher.prototype.deletePairedClient =
382 function(client, onDone, onError) {
384 remoting.HostDispatcher.runCallback_.bind(null, onDone, onError);
385 switch (this.state_) {
386 case remoting.HostDispatcher.State.UNKNOWN:
387 this.pendingRequests_.push(
388 this.deletePairedClient.bind(this, client, onDone, onError));
390 case remoting.HostDispatcher.State.NATIVE_MESSAGING:
391 this.nativeMessagingHost_.deletePairedClient(client, callback, onError);
393 case remoting.HostDispatcher.State.NOT_INSTALLED:
394 onError(remoting.Error.MISSING_PLUGIN);
400 * @param {function(string):void} onDone
401 * @param {function(remoting.Error):void} onError
404 remoting.HostDispatcher.prototype.getHostClientId =
405 function(onDone, onError) {
406 switch (this.state_) {
407 case remoting.HostDispatcher.State.UNKNOWN:
408 this.pendingRequests_.push(
409 this.getHostClientId.bind(this, onDone, onError));
411 case remoting.HostDispatcher.State.NATIVE_MESSAGING:
412 this.nativeMessagingHost_.getHostClientId(onDone, onError);
414 case remoting.HostDispatcher.State.NOT_INSTALLED:
415 onError(remoting.Error.MISSING_PLUGIN);
421 * @param {string} authorizationCode
422 * @param {function(string, string):void} onDone
423 * @param {function(remoting.Error):void} onError
426 remoting.HostDispatcher.prototype.getCredentialsFromAuthCode =
427 function(authorizationCode, onDone, onError) {
428 switch (this.state_) {
429 case remoting.HostDispatcher.State.UNKNOWN:
430 this.pendingRequests_.push(
431 this.getCredentialsFromAuthCode.bind(
432 this, authorizationCode, onDone, onError));
434 case remoting.HostDispatcher.State.NATIVE_MESSAGING:
435 this.nativeMessagingHost_.getCredentialsFromAuthCode(
436 authorizationCode, onDone, onError);
438 case remoting.HostDispatcher.State.NOT_INSTALLED:
439 onError(remoting.Error.MISSING_PLUGIN);