Index: remoting/webapp/base/js/protocol_extension_manager.js |
diff --git a/remoting/webapp/base/js/protocol_extension_manager.js b/remoting/webapp/base/js/protocol_extension_manager.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..66b3fc1aff396525d8319506761f6e1a067217e2 |
--- /dev/null |
+++ b/remoting/webapp/base/js/protocol_extension_manager.js |
@@ -0,0 +1,120 @@ |
+// 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. |
+ |
+/** @suppress {duplicate} */ |
+var remoting = remoting || {}; |
+ |
+(function() { |
+ |
+'use strict'; |
+ |
+/** |
+ * @param {function(string, string)} sendClientMessageCallback Callback used to |
+ * send a client message to the plugin. |
+ * @constructor |
+ * @implements {base.Disposable} |
+ */ |
+remoting.ProtocolExtensionManager = function(sendClientMessageCallback) { |
+ /** @private */ |
+ this.sendExtensionMessage_ = sendClientMessageCallback; |
+ /** @private {Object<string,remoting.ProtocolExtension>} */ |
+ this.protocolExtensions_ = {}; |
+ |
+ /** |
+ * True once a session has been created and we've started the extensions. |
+ * This is used to immediately start any extensions that are registered |
+ * after the CONNECTED state change. |
+ * @private |
+ */ |
+ this.protocolExtensionsStarted_ = false; |
+}; |
+ |
+remoting.ProtocolExtensionManager.prototype.dispose = function() { |
+ this.sendExtensionMessage_ = base.doNothing; |
+ this.protocolExtensions_ = {}; |
+}; |
+ |
+/** Called by the plugin when the session is connected */ |
+remoting.ProtocolExtensionManager.prototype.start = function() { |
+ base.debug.assert(!this.protocolExtensionsStarted_); |
+ for (var type in this.protocolExtensions_) { |
+ this.startExtension_(type); |
+ } |
+ this.protocolExtensionsStarted_ = true; |
+}; |
+ |
+/** |
+ * @param {remoting.ProtocolExtension} extension |
+ */ |
+remoting.ProtocolExtensionManager.prototype.register = |
+ function(extension) { |
+ var types = extension.getExtensionTypes(); |
+ |
+ // Make sure we don't have an extension of that type already registered. |
+ for (var i=0, len=types.length; i < len; i++) { |
+ if (types[i] in this.protocolExtensions_) { |
+ console.error( |
+ 'Attempt to register multiple extensions of the same type: ', type); |
+ return; |
+ } |
+ } |
+ |
+ for (var i=0, len=types.length; i < len; i++) { |
+ var type = types[i]; |
+ this.protocolExtensions_[type] = extension; |
+ if (this.protocolExtensionsStarted_) { |
+ this.startExtension_(type); |
+ } |
+ } |
+}; |
+ |
+/** |
+ * @param {string} type |
+ * @private |
+ */ |
+remoting.ProtocolExtensionManager.prototype.startExtension_ = |
+ function(type) { |
+ var extension = this.protocolExtensions_[type]; |
+ extension.startExtension(this.sendExtensionMessage_); |
+}; |
+ |
+/** |
+ * Called when an extension message needs to be handled. |
+ * |
+ * @param {string} type The type of the extension message. |
+ * @param {string} data The payload of the extension message. |
+ * @return {boolean} Return true if the extension message was recognized. |
+ */ |
+remoting.ProtocolExtensionManager.prototype.onProtocolExtensionMessage = |
+ function(type, data) { |
+ if (type == 'test-echo-reply') { |
+ console.log('Got echo reply: ' + data); |
+ return true; |
+ } |
+ |
+ var message = base.jsonParseSafe(data); |
+ if (typeof message != 'object') { |
+ console.error('Error parsing extension json data: ' + data); |
+ return false; |
+ } |
+ |
+ if (type in this.protocolExtensions_) { |
+ /** @type {remoting.ProtocolExtension} */ |
+ var extension = this.protocolExtensions_[type]; |
+ var handled = false; |
+ try { |
+ handled = extension.onExtensionMessage(type, message); |
+ } catch (/** @type {*} */ err) { |
+ console.error('Failed to process protocol extension ' + type + |
+ ' message: ' + err); |
+ } |
+ if (handled) { |
+ return true; |
+ } |
+ } |
+ |
+ return false; |
+}; |
+ |
+})(); |