Bug 930243 - Add a processType flag to chrome manifest directives (r=froydnj)
authorBill McCloskey <wmccloskey@mozilla.com>
Tue, 07 Oct 2014 11:46:24 -0700
changeset 232446 e5c5d33293aa89bcae840849adba3438d57810c5
parent 232445 839f8ca256d48b595691bb54ddcf6ced0a253600
child 232447 c5e310d17e58610b6f1b1b13779a98a1ccc1acb4
push id1
push usersledru@mozilla.com
push dateThu, 04 Dec 2014 17:57:20 +0000
reviewersfroydnj
bugs930243
milestone35.0a1
Bug 930243 - Add a processType flag to chrome manifest directives (r=froydnj)
python/mozbuild/mozpack/chrome/flags.py
python/mozbuild/mozpack/chrome/manifest.py
xpcom/components/ManifestParser.cpp
xpcom/tests/unit/data/child_process_directive_service.js
xpcom/tests/unit/data/main_process_directive_service.js
xpcom/tests/unit/data/process_directive.manifest
xpcom/tests/unit/test_process_directives.js
xpcom/tests/unit/test_process_directives_child.js
xpcom/tests/unit/xpcshell.ini
--- a/python/mozbuild/mozpack/chrome/flags.py
+++ b/python/mozbuild/mozpack/chrome/flags.py
@@ -208,16 +208,17 @@ class Flags(OrderedDict):
         'platformversion': VersionFlag,
         'contentaccessible': Flag,
         'os': StringFlag,
         'osversion': VersionFlag,
         'abi': StringFlag,
         'platform': Flag,
         'xpcnativewrappers': Flag,
         'tablet': Flag,
+        'process': StringFlag,
     }
     RE = re.compile(r'([!<>=]+)')
 
     def __init__(self, *flags):
         '''
         Initialize a set of flags given in string form.
            flags = Flags('contentaccessible=yes', 'appversion>=3.5')
         '''
--- a/python/mozbuild/mozpack/chrome/manifest.py
+++ b/python/mozbuild/mozpack/chrome/manifest.py
@@ -30,16 +30,17 @@ class ManifestEntry(object):
     allowed_flags = [
         'application',
         'platformversion',
         'os',
         'osversion',
         'abi',
         'xpcnativewrappers',
         'tablet',
+        'process',
     ]
 
     def __init__(self, base, *flags):
         '''
         Initialize a manifest entry with the given base path and flags.
         '''
         self.base = base
         self.flags = Flags(*flags)
--- a/xpcom/components/ManifestParser.cpp
+++ b/xpcom/components/ManifestParser.cpp
@@ -488,28 +488,33 @@ ParseManifest(NSLocationType aType, File
   NS_NAMED_LITERAL_STRING(kPlatform, "platform");
   NS_NAMED_LITERAL_STRING(kContentAccessible, "contentaccessible");
   NS_NAMED_LITERAL_STRING(kApplication, "application");
   NS_NAMED_LITERAL_STRING(kAppVersion, "appversion");
   NS_NAMED_LITERAL_STRING(kGeckoVersion, "platformversion");
   NS_NAMED_LITERAL_STRING(kOs, "os");
   NS_NAMED_LITERAL_STRING(kOsVersion, "osversion");
   NS_NAMED_LITERAL_STRING(kABI, "abi");
+  NS_NAMED_LITERAL_STRING(kProcess, "process");
 #if defined(MOZ_WIDGET_ANDROID)
   NS_NAMED_LITERAL_STRING(kTablet, "tablet");
 #endif
 
+  NS_NAMED_LITERAL_STRING(kMain, "main");
+  NS_NAMED_LITERAL_STRING(kContent, "content");
+
   // Obsolete
   NS_NAMED_LITERAL_STRING(kXPCNativeWrappers, "xpcnativewrappers");
 
   nsAutoString appID;
   nsAutoString appVersion;
   nsAutoString geckoVersion;
   nsAutoString osTarget;
   nsAutoString abi;
+  nsAutoString process;
 
   nsCOMPtr<nsIXULAppInfo> xapp;
   if (!aXPTOnly) {
     // Avoid to create any component for XPT only mode.
     // No xapp means no ID, version, ..., modifiers checking.
     xapp = do_GetService(XULAPPINFO_SERVICE_CONTRACTID);
   }
   if (xapp) {
@@ -573,16 +578,22 @@ ParseManifest(NSLocationType aType, File
   if (mozilla::AndroidBridge::Bridge()) {
     mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build$VERSION",
                                                            "RELEASE",
                                                            osVersion);
     isTablet = mozilla::widget::android::GeckoAppShell::IsTablet();
   }
 #endif
 
+  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    process = kContent;
+  } else {
+    process = kMain;
+  }
+
   // Because contracts must be registered after CIDs, we save and process them
   // at the end.
   nsTArray<CachedDirective> contracts;
 
   char* token;
   char* newline = aBuf;
   uint32_t line = 0;
 
@@ -664,30 +675,32 @@ ParseManifest(NSLocationType aType, File
 
     bool ok = true;
     TriState stAppVersion = eUnspecified;
     TriState stGeckoVersion = eUnspecified;
     TriState stApp = eUnspecified;
     TriState stOsVersion = eUnspecified;
     TriState stOs = eUnspecified;
     TriState stABI = eUnspecified;
+    TriState stProcess = eUnspecified;
 #if defined(MOZ_WIDGET_ANDROID)
     TriState stTablet = eUnspecified;
 #endif
     bool platform = false;
     bool contentAccessible = false;
 
     while ((token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
            ok) {
       ToLowerCase(token);
       NS_ConvertASCIItoUTF16 wtoken(token);
 
       if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
           CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
           CheckStringFlag(kABI, wtoken, abi, stABI) ||
+          CheckStringFlag(kProcess, wtoken, process, stProcess) ||
           CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) ||
           CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion) ||
           CheckVersionFlag(kGeckoVersion, wtoken, geckoVersion, stGeckoVersion)) {
         continue;
       }
 
 #if defined(MOZ_WIDGET_ANDROID)
       bool tablet = false;
@@ -721,17 +734,18 @@ ParseManifest(NSLocationType aType, File
         stApp == eBad ||
         stAppVersion == eBad ||
         stGeckoVersion == eBad ||
         stOs == eBad ||
         stOsVersion == eBad ||
 #ifdef MOZ_WIDGET_ANDROID
         stTablet == eBad ||
 #endif
-        stABI == eBad) {
+        stABI == eBad ||
+        stProcess == eBad) {
       continue;
     }
 
 #ifdef MOZ_B2G_LOADER
     if (aXPTOnly) {
       directive->xptonlyfunc(xptonlycx, line, argv);
     } else
 #endif /* MOZ_B2G_LOADER */
new file mode 100644
--- /dev/null
+++ b/xpcom/tests/unit/data/child_process_directive_service.js
@@ -0,0 +1,21 @@
+/* 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/. */
+Components.utils.import("resource:///modules/XPCOMUtils.jsm");
+
+function TestProcessDirective() {}
+TestProcessDirective.prototype = {
+
+  /* Boilerplate */
+  QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupportsString]),
+  contractID: "@mozilla.org/xpcom/tests/ChildProcessDirectiveTest;1",
+  classID: Components.ID("{4bd1ba60-45c4-11e4-916c-0800200c9a66}"),
+
+  type: Components.interfaces.nsISupportsString.TYPE_STRING,
+  data: "child process",
+  toString: function() {
+    return this.data;
+  }
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TestProcessDirective]);
new file mode 100644
--- /dev/null
+++ b/xpcom/tests/unit/data/main_process_directive_service.js
@@ -0,0 +1,21 @@
+/* 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/. */
+Components.utils.import("resource:///modules/XPCOMUtils.jsm");
+
+function TestProcessDirective() {}
+TestProcessDirective.prototype = {
+
+  /* Boilerplate */
+  QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupportsString]),
+  contractID: "@mozilla.org/xpcom/tests/MainProcessDirectiveTest;1",
+  classID: Components.ID("{9b6f4160-45be-11e4-916c-0800200c9a66}"),
+
+  type: Components.interfaces.nsISupportsString.TYPE_STRING,
+  data: "main process",
+  toString: function() {
+    return this.data;
+  }
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TestProcessDirective]);
new file mode 100644
--- /dev/null
+++ b/xpcom/tests/unit/data/process_directive.manifest
@@ -0,0 +1,5 @@
+component {9b6f4160-45be-11e4-916c-0800200c9a66} main_process_directive_service.js process=main
+contract @mozilla.org/xpcom/tests/MainProcessDirectiveTest;1 {9b6f4160-45be-11e4-916c-0800200c9a66} process=main
+
+component {4bd1ba60-45c4-11e4-916c-0800200c9a66} child_process_directive_service.js process=content
+contract @mozilla.org/xpcom/tests/ChildProcessDirectiveTest;1 {4bd1ba60-45c4-11e4-916c-0800200c9a66} process=content
new file mode 100644
--- /dev/null
+++ b/xpcom/tests/unit/test_process_directives.js
@@ -0,0 +1,25 @@
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+
+Components.utils.import("resource:///modules/Services.jsm");
+
+function run_test()
+{
+  Components.manager.autoRegister(do_get_file("data/process_directive.manifest"));
+
+  let isChild = Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT;
+
+  if (isChild) {
+    do_check_false("@mozilla.org/xpcom/tests/MainProcessDirectiveTest;1" in Cc);
+  } else {
+    let svc = Cc["@mozilla.org/xpcom/tests/MainProcessDirectiveTest;1"].createInstance(Ci.nsISupportsString);
+    do_check_eq(svc.data, "main process");
+  }
+
+  if (!isChild) {
+    do_check_false("@mozilla.org/xpcom/tests/ChildProcessDirectiveTest;1" in Cc);
+  } else {
+    let svc = Cc["@mozilla.org/xpcom/tests/ChildProcessDirectiveTest;1"].createInstance(Ci.nsISupportsString);
+    do_check_eq(svc.data, "child process");
+  }
+}
new file mode 100644
--- /dev/null
+++ b/xpcom/tests/unit/test_process_directives_child.js
@@ -0,0 +1,3 @@
+function run_test() {
+  run_test_in_child("test_process_directives.js");
+}
--- a/xpcom/tests/unit/xpcshell.ini
+++ b/xpcom/tests/unit/xpcshell.ini
@@ -44,16 +44,18 @@ fail-if = os == "android"
 skip-if = os == "win" # bug 582821
 # Bug 676998: test fails consistently on Android
 fail-if = os == "android"
 [test_nsIProcess_stress.js]
 # bug 676412, test isn't needed on windows
 # bug 704368: test causes harness to be killed on debug Linux64
 skip-if = os == "win" || (os == "linux" && debug && bits == 64)
 [test_pipe.js]
+[test_process_directives.js]
+[test_process_directives_child.js]
 [test_storagestream.js]
 [test_streams.js]
 [test_seek_multiplex.js]
 [test_stringstream.js]
 [test_symlinks.js]
 # Bug 676998: test fails consistently on Android
 fail-if = os == "android"
 [test_systemInfo.js]