Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Unified Diff: remoting/webapp/base/js/remote_methods.js

Issue 868203002: Handle authentication failures in the v2 app by restarting the app (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: remoting/webapp/base/js/remote_methods.js
diff --git a/remoting/webapp/base/js/remote_methods.js b/remoting/webapp/base/js/remote_methods.js
new file mode 100644
index 0000000000000000000000000000000000000000..20c0a6aa6b7eb9998daa5dd51c67466913980460
--- /dev/null
+++ b/remoting/webapp/base/js/remote_methods.js
@@ -0,0 +1,150 @@
+// Copyright 2014 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
+*
+* In Chrome Apps, some platform APIs can only be called from the background
+* page. For example, you can only reload an chrome.app.AppWindow from a
+* background page. Likewise, some chrome API's must be initiated by user
+* interaction, which can only be called from the foreground.
+*
+* This class provides helper functions to invoke methods on different pages
+* using chrome.runtime.sendMessage. Messages are passed in the following
+* format:
+* {requestType:{string}, params:{Array}}
+*
+* chrome.runtime.sendMessage allows multiple handlers to be registered on a
+* document, but only one handler can send a response.
+* This class uniquely identifies a request with the requestType and enforces
+* that only one handler can be registered per requestType in the document.
+*
+* For example, to call method foo() in the background page from the foreground
+* chrome.app.AppWindow, you can do the following.
+* In the background page:
+* var remoteMethods = new base.remoteMethods();
+* remoteMethods.register('my.service.name', foo);
+*
+* In the AppWindow document:
+* base.remoteMethods.invoke('my.service.name', [arg1, arg2]).then(
Jamie 2015/01/23 23:33:26 Would it be a lot of work to allow args to be pass
+* function(result) {
+* console.log('The result is ' + result);
+* });
+*
+* This will invoke foo() with the args [arg1, arg2].
+* The return value of foo() will be passed back to the caller in the
+* form of a promise.
+*/
+
+/** @suppress {duplicate} */
+var base = base || {};
+
+(function() {
+
+'use strict';
+
+/**
+ * @constructor
+ * @implements {base.Disposable}
+ */
+base.RemoteMethods = function() {
Jamie 2015/01/23 23:33:26 I suggest base.Ipc as a name instead.
Jamie 2015/01/23 23:33:26 With a suitable chrome.runtime.sendMessage mock, I
+ /**
+ * @type {!Object.<Function>}
+ * @private
+ */
+ this.handlers_ = {};
+ this.onMessageHandler_ = this.onMessage_.bind(this);
+ chrome.runtime.onMessage.addListener(this.onMessageHandler_);
+};
+
+
+/**
+ * @constructor
+ * @param {string} requestType
+ * @param {?Array} params
+ * @struct
+ */
+base.RemoteMethods.Request_ = function(requestType, params) {
Jamie 2015/01/23 23:33:26 If this is a private type, does it need to be expo
+ this.requestType = requestType;
+ this.params = params;
+};
+
+base.RemoteMethods.prototype.dispose = function() {
+ chrome.runtime.onMessage.removeListener(this.onMessageHandler_);
+};
+
+/**
+ * @param {string} requestType
Jamie 2015/01/23 23:33:26 Since we're talking about methods, I think methodN
+ * @param {Function} handler
Jamie 2015/01/23 23:33:26 s/Function/function(*):void/
+ * @return {boolean} Whether the handler is successfully registered.
+ */
+base.RemoteMethods.prototype.register = function(requestType, handler) {
+ if (requestType in this.handlers_) {
+ console.error('service :' + requestType + ' is already registered.');
+ return false;
+ }
+ this.handlers_[requestType] = handler;
+ return true;
+};
+
+/**
+ * @param {string} requestType
+ */
+base.RemoteMethods.prototype.unregister = function(requestType) {
+ delete this.handlers_[requestType];
+};
+
+/**
+ * @param {base.RemoteMethods.Request_} message
+ * @param {chrome.runtime.MessageSender} sender
+ * @param {function(*): void} sendResponse
+ */
+base.RemoteMethods.prototype.onMessage_ = function(message, sender,
+ sendResponse) {
+ if (sender.id !== chrome.runtime.id) {
+ // We only handle incoming requests from our extension.
+ return;
+ }
+
+ var requestType = message.requestType;
+ if (typeof requestType !== 'string') {
+ return;
+ }
+
+ var remoteMethod =
+ /** @type {function(*):void} */ (this.handlers_[requestType]);
+ if (!remoteMethod) {
+ sendResponse({error : 'Unsupported request:= ' + requestType});
Jamie 2015/01/23 23:33:26 Nit: s/:=/:/
+ return;
+ }
+
+ try {
+ sendResponse(remoteMethod.apply(null, message.params));
+ } catch (/** @type {Error} */ e) {
+ sendResponse({error: e.message});
+ }
+};
+
+/**
+ * Invokes a method on a remote page
Jamie 2015/01/23 23:33:26 Blank (comment) line after method description.
+ * @param {string} requestType
+ * @param {Array} params
Jamie 2015/01/23 23:33:26 @return?
+ */
+base.RemoteMethods.invoke = function(requestType, params) {
+ var sendMessage = base.Promise.as(
+ chrome.runtime.sendMessage,
+ [null, new base.RemoteMethods.Request_(requestType, params)]);
Jamie 2015/01/23 23:33:26 I don't think you need the leading null, since the
+
+ return sendMessage.then(
+ /** @param {{error: Error}} response */
+ function(response) {
+ if (response.error) {
+ Promise.reject(response.error);
+ } else {
+ Promise.resolve(response);
Jamie 2015/01/23 23:33:26 Don't these reject/resolves need to be returned?
+ }
+ });
+};
+
+})();
Jamie 2015/01/23 23:33:26 Although we have too many globals in our code, I t

Powered by Google App Engine
This is Rietveld 408576698