Bug 876397 - Inter-App Communication API (part 1, Web IDLs). r=nsm,ted sr=smaug
authorGene Lian <clian@mozilla.com>
Tue, 30 Jul 2013 22:03:06 +0800
changeset 159740 f473c47457f5e6e74d3870c9aad42ab93a7b6432
parent 159739 e2977628a9d505c64e8d03de98c66d4d40247577
child 159741 7987756e88e86cdfdea9804569d46cbcef3d2c0b
push idunknown
push userunknown
push dateunknown
reviewersnsm, ted, smaug
bugs876397
milestone26.0a1
Bug 876397 - Inter-App Communication API (part 1, Web IDLs). r=nsm,ted sr=smaug
b2g/app/b2g.js
b2g/installer/package-manifest.in
dom/apps/src/InterAppComm.cpp
dom/apps/src/InterAppComm.h
dom/apps/src/InterAppComm.manifest
dom/apps/src/InterAppConnection.js
dom/apps/src/InterAppMessagePort.js
dom/apps/src/Makefile.in
dom/apps/src/Webapps.js
dom/apps/src/moz.build
dom/interfaces/apps/nsIDOMApplicationRegistry.idl
dom/webidl/InterAppConnection.webidl
dom/webidl/InterAppConnectionRequest.webidl
dom/webidl/InterAppMessagePort.webidl
dom/webidl/moz.build
layout/build/Makefile.in
modules/libpref/src/init/all.js
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -745,16 +745,22 @@ pref("captivedetect.canonicalContent", "
 pref("ping.manifestURL", "https://marketplace.firefox.com/packaged.webapp");
 
 // Enable the disk space watcher
 pref("disk_space_watcher.enabled", true);
 
 // Enable promise
 pref("dom.promise.enabled", false);
 
+// DOM Inter-App Communication API.
+#ifdef MOZ_WIDGET_GONK
+// Enable this only for gonk-specific build but not for desktop build.
+pref("dom.inter-app-communication-api.enabled", true);
+#endif
+
 // Allow ADB to run for this many hours before disabling
 // (only applies when marionette is disabled)
 // 0 disables the timer.
 pref("b2g.adb.timeout-hours", 12);
 
 // Absolute path to the devtool unix domain socket file used
 // to communicate with a usb cable via adb forward
 pref("devtools.debugger.unix-domain-socket", "/data/local/debugger-socket");
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -500,16 +500,20 @@
 @BINPATH@/components/Webapps.js
 @BINPATH@/components/Webapps.manifest
 @BINPATH@/components/AppsService.js
 @BINPATH@/components/AppsService.manifest
 @BINPATH@/components/Push.js
 @BINPATH@/components/Push.manifest
 @BINPATH@/components/PushServiceLauncher.js
 
+@BINPATH@/components/InterAppComm.manifest
+@BINPATH@/components/InterAppConnection.js
+@BINPATH@/components/InterAppMessagePort.js
+
 @BINPATH@/components/nsDOMIdentity.js
 @BINPATH@/components/nsIDService.js
 @BINPATH@/components/Identity.manifest
 
 @BINPATH@/components/SystemMessageInternal.js
 @BINPATH@/components/SystemMessageManager.js
 @BINPATH@/components/SystemMessageManager.manifest
 
new file mode 100644
--- /dev/null
+++ b/dom/apps/src/InterAppComm.cpp
@@ -0,0 +1,25 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "InterAppComm.h"
+#include "nsContentUtils.h"
+#include "nsPIDOMWindow.h"
+#include "nsJSPrincipals.h"
+#include "mozilla/Preferences.h"
+#include "AccessCheck.h"
+
+using namespace mozilla::dom;
+
+/* static */ bool
+InterAppComm::EnabledForScope(JSContext* /* unused */, JSObject* aObj)
+{
+  // Disable the constructors if they're disabled by the preference for sure.
+  if (!Preferences::GetBool("dom.inter-app-communication-api.enabled", false)) {
+  	return false;
+  }
+
+  // Only expose the constructors to the chrome codes for Gecko internal uses.
+  // The content pages shouldn't be aware of the constructors.
+  return xpc::AccessCheck::isChrome(aObj);
+}
new file mode 100644
--- /dev/null
+++ b/dom/apps/src/InterAppComm.h
@@ -0,0 +1,24 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_apps_InterAppComm_h
+#define mozilla_dom_apps_InterAppComm_h
+
+// Forward declarations.
+struct JSContext;
+class JSObject;
+
+namespace mozilla {
+namespace dom {
+
+class InterAppComm
+{
+public:
+  static bool EnabledForScope(JSContext* /* unused */, JSObject* aObj);
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_apps_InterAppComm_h
new file mode 100644
--- /dev/null
+++ b/dom/apps/src/InterAppComm.manifest
@@ -0,0 +1,8 @@
+component {9dbfa904-0718-11e3-8e77-0721a45514b8} InterAppConnection.js
+contract @mozilla.org/dom/inter-app-connection;1 {9dbfa904-0718-11e3-8e77-0721a45514b8}
+
+component {6a77e9e0-0645-11e3-b90b-73bb7c78e06a} InterAppConnection.js
+contract @mozilla.org/dom/inter-app-connection-request;1 {6a77e9e0-0645-11e3-b90b-73bb7c78e06a}
+
+component {c66e0f8c-e3cb-11e2-9e85-43ef6244b884} InterAppMessagePort.js
+contract @mozilla.org/dom/inter-app-message-port;1 {c66e0f8c-e3cb-11e2-9e85-43ef6244b884}
new file mode 100644
--- /dev/null
+++ b/dom/apps/src/InterAppConnection.js
@@ -0,0 +1,77 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function debug(aMsg) {
+  // dump("-- InterAppConnection: " + Date.now() + ": " + aMsg + "\n");
+}
+
+/**
+ * MozInterAppConnection implementation.
+ */
+
+function InterAppConnection() {
+  debug("InterAppConnection()");
+  this.keyword = null;
+  this.publisher = null;
+  this.subscriber = null;
+};
+
+InterAppConnection.prototype = {
+  classDescription: "MozInterAppConnection",
+
+  classID: Components.ID("{9dbfa904-0718-11e3-8e77-0721a45514b8}"),
+
+  contractID: "@mozilla.org/dom/inter-app-connection;1",
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
+
+  __init: function(aKeyword, aPublisher, aSubscriber) {
+    debug("__init: aKeyword: " + aKeyword +
+          " aPublisher: " + aPublisher + " aSubscriber: " + aSubscriber);
+    this.keyword = aKeyword;
+    this.publisher = aPublisher;
+    this.subscriber = aSubscriber;
+  },
+
+  cancel: function() {
+    // TODO
+  }
+};
+
+
+/**
+ * MozInterAppConnectionRequest implementation.
+ */
+
+function InterAppConnectionRequest() {
+  debug("InterAppConnectionRequest()");
+  this.keyword = null;
+  this.port = null;
+};
+
+InterAppConnectionRequest.prototype = {
+  classDescription: "MozInterAppConnectionRequest",
+
+  classID: Components.ID("{6a77e9e0-0645-11e3-b90b-73bb7c78e06a}"),
+
+  contractID: "@mozilla.org/dom/inter-app-connection-request;1",
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
+
+  __init: function(aKeyword, aPort) {
+    debug("__init: aKeyword: " + aKeyword + " aPort: " + aPort);
+    this.keyword = aKeyword;
+    this.port = aPort;
+  }
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([InterAppConnection,
+                                                     InterAppConnectionRequest]);
new file mode 100644
--- /dev/null
+++ b/dom/apps/src/InterAppMessagePort.js
@@ -0,0 +1,51 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function debug(aMsg) {
+  // dump("-- InterAppMessagePort: " + Date.now() + ": " + aMsg + "\n");
+}
+
+function InterAppMessagePort() {
+  debug("InterAppMessagePort()");
+};
+
+InterAppMessagePort.prototype = {
+  classDescription: "MozInterAppMessagePort",
+
+  classID: Components.ID("{c66e0f8c-e3cb-11e2-9e85-43ef6244b884}"),
+
+  contractID: "@mozilla.org/dom/inter-app-message-port;1",
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
+
+  postMessage: function(aMessage) {
+    // TODO
+  },
+
+  start: function() {
+    // TODO
+  },
+
+  close: function() {
+    // TODO
+  },
+
+  get onmessage() {
+    return this.__DOM_IMPL__.getEventHandler("onmessage");
+  },
+
+  set onmessage(aHandler) {
+    this.__DOM_IMPL__.setEventHandler("onmessage", aHandler);
+  }
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([InterAppMessagePort]);
+
new file mode 100644
--- /dev/null
+++ b/dom/apps/src/Makefile.in
@@ -0,0 +1,10 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+LOCAL_INCLUDES += \
+  -I$(topsrcdir)/js/xpconnect/wrappers \
+  $(NULL)
+
+include $(topsrcdir)/dom/dom-config.mk
+include $(topsrcdir)/config/rules.mk
--- a/dom/apps/src/Webapps.js
+++ b/dom/apps/src/Webapps.js
@@ -455,16 +455,24 @@ WebappsApplication.prototype = {
         }
       }
       Services.tm.currentThread.dispatch(runnable,
                                          Ci.nsIThread.DISPATCH_NORMAL);
     }
     return request;
   },
 
+  connect: function(aKeyword, aRules) {
+    // TODO
+  },
+
+  getConnections: function() {
+    // TODO
+  },
+
   uninit: function() {
     this._onprogress = null;
     cpmm.sendAsyncMessage("Webapps:UnregisterForMessages",
                           ["Webapps:OfflineCache",
                            "Webapps:PackageEvent",
                            "Webapps:CheckForUpdate:Return:OK"]);
 
     manifestCache.evict(this.manifestURL, this.innerWindowID);
--- a/dom/apps/src/moz.build
+++ b/dom/apps/src/moz.build
@@ -1,17 +1,28 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+EXPORTS.mozilla.dom += [
+    'InterAppComm.h',
+]
+
+CPP_SOURCES += [
+    'InterAppComm.cpp',
+]
+
 EXTRA_COMPONENTS += [
     'AppsService.js',
     'AppsService.manifest',
+    'InterAppComm.manifest',
+    'InterAppConnection.js',
+    'InterAppMessagePort.js',
     'Webapps.js',
     'Webapps.manifest',
 ]
 
 EXTRA_JS_MODULES += [
     'AppDownloadManager.jsm',
     'AppsServiceChild.jsm',
     'FreeSpaceWatcher.jsm',
@@ -20,8 +31,13 @@ EXTRA_JS_MODULES += [
     'PermissionsTable.jsm',
 ]
 
 EXTRA_PP_JS_MODULES += [
     'AppsUtils.jsm',
     'Webapps.jsm',
 ]
 
+FAIL_ON_WARNINGS = True
+
+LIBXUL_LIBRARY = True
+
+LIBRARY_NAME = 'dom_apps_s'
--- a/dom/interfaces/apps/nsIDOMApplicationRegistry.idl
+++ b/dom/interfaces/apps/nsIDOMApplicationRegistry.idl
@@ -2,17 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "domstubs.idl"
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMDOMRequest;
 
-[scriptable, uuid(8bdeef38-e9cd-46f8-b8de-ed9e6b4d01ea)]
+[scriptable, uuid(4081390c-08cf-11e3-9200-b3c0a8744b20)]
 interface mozIDOMApplication  : nsISupports
 {
   readonly attribute jsval manifest;
   readonly attribute jsval updateManifest;
   readonly attribute DOMString manifestURL;
   readonly attribute jsval receipts; /* an array of strings */
   readonly attribute DOMString origin;
   readonly attribute DOMString installOrigin;
@@ -85,16 +85,26 @@ interface mozIDOMApplication  : nsISuppo
   /* startPoint will be used when several launch_path exists for an app */
   nsIDOMDOMRequest launch([optional] in DOMString startPoint);
 
   /**
    * Clear data that has been collected through mozbrowser elements.
    * onsuccess will be called once data is actually cleared.
    */
   nsIDOMDOMRequest clearBrowserData();
+
+  /**
+   * Inter-App Communication APIs.
+   *
+   * https://wiki.mozilla.org/WebAPI/Inter_App_Communication_Alt_proposal
+   */
+  nsISupports connect(in DOMString keyword,
+                      [optional] in jsval rules); // nsISupports is a Promise.
+
+  nsISupports getConnections(); // nsISupports is a Promise.
 };
 
 [scriptable, uuid(cf742022-5ba3-11e2-868f-03310341b006)]
 interface mozIDOMApplicationMgmt : nsISupports
 {
   /**
    * the request will return the all the applications installed. Only accessible
    * to privileged callers.
new file mode 100644
--- /dev/null
+++ b/dom/webidl/InterAppConnection.webidl
@@ -0,0 +1,15 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+[HeaderFile="mozilla/dom/InterAppComm.h",
+ Func="mozilla::dom::InterAppComm::EnabledForScope",
+ Constructor(DOMString keyword, DOMString publisher, DOMString subsriber),
+ JSImplementation="@mozilla.org/dom/inter-app-connection;1"]
+interface MozInterAppConnection {
+  readonly attribute DOMString keyword;
+  readonly attribute DOMString publisher;
+  readonly attribute DOMString subscriber;
+
+  void cancel();
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/InterAppConnectionRequest.webidl
@@ -0,0 +1,13 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+[HeaderFile="mozilla/dom/InterAppComm.h",
+ Func="mozilla::dom::InterAppComm::EnabledForScope",
+ Constructor(DOMString keyword, MozInterAppMessagePort port),
+ JSImplementation="@mozilla.org/dom/inter-app-connection-request;1"]
+interface MozInterAppConnectionRequest {
+  readonly attribute DOMString keyword;
+
+  readonly attribute MozInterAppMessagePort port;
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/InterAppMessagePort.webidl
@@ -0,0 +1,23 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// TODO Bug 907060 Per off-line discussion, after the MessagePort is done
+// at Bug 643325, we will start to refactorize the common logic of both
+// Inter-App Communication and Shared Worker. For now, we hope to design an
+// MozInterAppMessagePort to meet the timeline, which still follows exactly
+// the same interface and semantic as the MessagePort is. In the future,
+// we can then align it back to MessagePort with backward compatibility.
+
+[HeaderFile="mozilla/dom/InterAppComm.h",
+ Func="mozilla::dom::InterAppComm::EnabledForScope",
+ JSImplementation="@mozilla.org/dom/inter-app-message-port;1"]
+interface MozInterAppMessagePort : EventTarget {
+  void postMessage(any message);
+
+  void start();
+
+  void close();
+
+  attribute EventHandler onmessage;
+};
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -181,16 +181,19 @@ WEBIDL_FILES = [
     'IDBObjectStore.webidl',
     'IDBOpenDBRequest.webidl',
     'IDBRequest.webidl',
     'IDBTransaction.webidl',
     'IDBVersionChangeEvent.webidl',
     'ImageData.webidl',
     'ImageDocument.webidl',
     'InspectorUtils.webidl',
+    'InterAppConnection.webidl',
+    'InterAppConnectionRequest.webidl',
+    'InterAppMessagePort.webidl',
     'KeyboardEvent.webidl',
     'KeyEvent.webidl',
     'LinkStyle.webidl',
     'LocalMediaStream.webidl',
     'Location.webidl',
     'MediaElementAudioSourceNode.webidl',
     'MediaError.webidl',
     'MediaRecorder.webidl',
--- a/layout/build/Makefile.in
+++ b/layout/build/Makefile.in
@@ -33,16 +33,17 @@ SHARED_LIBRARY_LIBS = \
 	$(DEPTH)/content/xslt/src/base/$(LIB_PREFIX)txbase_s.$(LIB_SUFFIX) \
 	$(DEPTH)/content/xslt/src/xml/$(LIB_PREFIX)txxml_s.$(LIB_SUFFIX) \
 	$(DEPTH)/content/xslt/src/xpath/$(LIB_PREFIX)txxpath_s.$(LIB_SUFFIX) \
 	$(DEPTH)/content/xslt/src/xslt/$(LIB_PREFIX)txxslt_s.$(LIB_SUFFIX) \
 	$(DEPTH)/content/xbl/src/$(LIB_PREFIX)gkconxbl_s.$(LIB_SUFFIX) \
 	$(DEPTH)/content/xul/document/src/$(LIB_PREFIX)gkconxuldoc_s.$(LIB_SUFFIX) \
 	$(DEPTH)/view/src/$(LIB_PREFIX)gkview_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/activities/src/$(LIB_PREFIX)dom_activities_s.$(LIB_SUFFIX) \
+	$(DEPTH)/dom/apps/src/$(LIB_PREFIX)dom_apps_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/base/$(LIB_PREFIX)jsdombase_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/battery/$(LIB_PREFIX)dom_battery_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/alarm/$(LIB_PREFIX)domalarm_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/devicestorage/$(LIB_PREFIX)domdevicestorage_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/encoding/$(LIB_PREFIX)domencoding_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/file/$(LIB_PREFIX)domfile_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/power/$(LIB_PREFIX)dom_power_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/quota/$(LIB_PREFIX)domquota_s.$(LIB_SUFFIX) \
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -4390,8 +4390,11 @@ pref("captivedetect.pollingTime", 3000);
 pref("captivedetect.maxRetryCount", 5);
 #endif
 
 #ifdef RELEASE_BUILD
 pref("dom.forms.inputmode", false);
 #else
 pref("dom.forms.inputmode", true);
 #endif
+
+// DOM Inter-App Communication API.
+pref("dom.inter-app-communication-api.enabled", false);