Index: remoting/webapp/crd/js/combined_host_list_api.js |
diff --git a/remoting/webapp/crd/js/combined_host_list_api.js b/remoting/webapp/crd/js/combined_host_list_api.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..20051817509e0392d958f0235ef944d9590033de |
--- /dev/null |
+++ b/remoting/webapp/crd/js/combined_host_list_api.js |
@@ -0,0 +1,187 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+/** |
+ * @fileoverview |
+ * API implementation that combines two other implementations. |
+ */ |
+ |
+/** @suppress {duplicate} */ |
+var remoting = remoting || {}; |
+ |
+(function() { |
+ |
+'use strict'; |
+ |
+/** |
+ * @constructor |
+ * @param {!remoting.HostListApi} legacyImpl |
+ * @param {!remoting.HostListApi} gcdImpl |
+ * @implements {remoting.HostListApi} |
+ */ |
+remoting.CombinedHostListApi = function(legacyImpl, gcdImpl) { |
+ /** @const {!remoting.HostListApi} */ |
+ this.legacyImpl_ = legacyImpl; |
+ |
+ /** @const {!remoting.HostListApi} */ |
+ this.gcdImpl_ = gcdImpl; |
+ |
+ /** @type {!Set<string>} */ |
+ this.gcdIds_ = new Set(); |
+ |
+ /** @type {!Set<string>} */ |
+ this.legacyIds_ = new Set(); |
+}; |
+ |
+/** @override */ |
+remoting.CombinedHostListApi.prototype.register = function( |
+ hostName, publicKey, hostClientId) { |
+ var that = this; |
+ if (remoting.settings.PREFER_GCD) { |
+ // First, register the new host with GCD, which will create a |
+ // service account and generate a host ID. |
+ return this.gcdImpl_.register(hostName, publicKey, hostClientId).then( |
+ function(gcdRegResult) { |
+ // After the GCD registration has been created, copy the |
+ // registration to the legacy directory so that clients not yet |
+ // upgraded to use GCD can see the new host. |
+ // |
+ // This is an ugly hack for multiple reasons: |
+ // |
+ // 1. It completely ignores |this.legacyImpl_|, complicating |
+ // unit tests. |
+ // |
+ // 2. It relies on the fact that, when |hostClientId| is null, |
+ // the legacy directory will "register" a host without |
+ // creating a service account. This is an obsolete feature |
+ // of the legacy directory that is being revived for a new |
+ // purposes. |
+ // |
+ // 3. It assumes the device ID generated by GCD is usable as a |
+ // host ID by the legacy directory. Fortunately both systems |
+ // use UUIDs. |
+ return remoting.LegacyHostListApi.registerWithHostId( |
+ gcdRegResult.hostId, hostName, publicKey, null).then( |
+ function() { |
+ // On success, return the result from GCD, ignoring |
+ // the result returned by the legacy directory. |
+ that.gcdIds_.add(gcdRegResult.hostId); |
+ that.legacyIds_.add(gcdRegResult.hostId); |
+ return gcdRegResult; |
+ }, |
+ function(error) { |
+ console.warn( |
+ 'Error copying host GCD host registration ' + |
+ 'to legacy directory: ' + error); |
kelvinp
2015/06/29 23:53:45
Nit: alignment
John Williams
2015/07/17 23:29:33
Done.
|
+ throw error; |
+ } |
+ ); |
+ }); |
+ } else { |
+ // Just register the host in the legacy directory. GCD does not |
+ // provide an API that can be used to copy the registration into |
+ // GCD. |
+ return this.legacyImpl_.register(hostName, publicKey, hostClientId).then( |
+ function(regResult) { |
+ that.legacyIds_.add(regResult.hostId); |
+ return regResult; |
+ }); |
+ } |
+}; |
+ |
+/** @override */ |
+remoting.CombinedHostListApi.prototype.get = function() { |
+ // Fetch the host list from both directories and merge hosts that |
+ // have the same ID. Normally the data retrieved from both |
+ // directories should be the same, but in the case of a conflict, |
+ // the value of |remoting.settings.PREFER_GCD| determines which |
+ // directory's information is returned. |
+ var that = this; |
+ var legacyPromise = this.legacyImpl_.get(); |
+ var gcdPromise = this.gcdImpl_.get(); |
+ return legacyPromise.then(function(legacyHosts) { |
+ return gcdPromise.then(function(gcdHosts) { |
+ var hosts = []; |
+ var newLegacyIds = new Set(); |
+ var newGcdIds = new Set(); |
+ function addLegacyHosts() { |
+ legacyHosts.forEach(function(host) { |
+ newLegacyIds.add(host.hostId); |
+ if (!newGcdIds.has(host.hostId)) { |
+ hosts.push(host); |
+ } |
+ }); |
+ } |
+ function addGcdHosts() { |
+ gcdHosts.forEach(function(host) { |
+ newGcdIds.add(host.hostId); |
+ if (!newLegacyIds.has(host.hostId)) { |
+ hosts.push(host); |
+ } |
+ }); |
+ } |
+ if (remoting.settings.PREFER_GCD) { |
+ addGcdHosts(); |
+ addLegacyHosts(); |
+ } else { |
+ addLegacyHosts(); |
+ addGcdHosts(); |
+ } |
+ that.legacyIds_ = newLegacyIds; |
+ that.gcdIds_ = newGcdIds; |
+ return hosts; |
+ }); |
+ }); |
+}; |
+ |
+/** @override */ |
+remoting.CombinedHostListApi.prototype.put = |
+ function(hostId, hostName, hostPublicKey) { |
+ var legacyPromise = Promise.resolve(); |
+ if (this.legacyIds_.has(hostId)) { |
+ legacyPromise = this.legacyImpl_.put(hostId, hostName, hostPublicKey); |
+ } |
+ var gcdPromise = Promise.resolve(); |
+ if (this.gcdIds_.has(hostId)) { |
+ gcdPromise = this.gcdImpl_.put(hostId, hostName, hostPublicKey); |
+ } |
+ return legacyPromise.then(function() { |
kelvinp
2015/06/29 23:53:45
Does other matter? Can we do Promise.all instead?
John Williams
2015/07/17 23:29:33
Order doesn't matter in this version, bit I wrote
|
+ return gcdPromise; |
+ }); |
+}; |
+ |
+/** @override */ |
+remoting.CombinedHostListApi.prototype.remove = function(hostId) { |
+ var legacyPromise = Promise.resolve(); |
+ if (this.legacyIds_.has(hostId)) { |
+ legacyPromise = this.legacyImpl_.remove(hostId); |
+ } |
+ var gcdPromise = Promise.resolve(); |
+ if (this.gcdIds_.has(hostId)) { |
+ gcdPromise = this.gcdImpl_.remove(hostId); |
+ } |
+ return legacyPromise.then(function() { |
+ return gcdPromise; |
+ }); |
+}; |
+ |
+/** @override */ |
+remoting.CombinedHostListApi.prototype.getSupportHost = function(supportId) { |
+ return this.legacyImpl_.getSupportHost(supportId); |
+}; |
+ |
+/** @override */ |
+remoting.CombinedHostListApi.prototype.getHostIdFromConfig = function(config) { |
+ var gcdId = base.getStringAttr(config, 'gcd_device_id', ''); |
+ var legacyId = base.getStringAttr(config, 'host_id', ''); |
+ if (gcdId && (!legacyId || remoting.settings.PREFER_GCD)) { |
+ return gcdId; |
+ } |
+ else { |
+ base.debug.assert(Boolean(legacyId)); |
+ return legacyId; |
+ } |
+}; |
+ |
+})(); |