Merge b-i to m-c, a=merge
authorPhil Ringnalda <philringnalda@gmail.com>
Sat, 04 Apr 2015 11:04:11 -0700
changeset 237670 421548077f12e72251aafac1ca2f33760a2c91e6
parent 237641 eeb9438975a5f2349f23b6b2322acebef4f87d87 (current diff)
parent 237669 33c1ec12e618960453d1809c4e94d9ac96d1217d (diff)
child 237672 644662d12dfa3212bd799e7a7f616c907b5e8210
child 237676 d81453353b89490edc82e9a95a5d3664879dac1b
child 237680 a80446d490c2fde05324139a47348c246d43149d
push id28542
push userphilringnalda@gmail.com
push dateSat, 04 Apr 2015 18:04:33 +0000
treeherdermozilla-central@421548077f12 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone40.0a1
first release with
nightly linux32
421548077f12 / 40.0a1 / 20150405030238 / files
nightly linux64
421548077f12 / 40.0a1 / 20150405030238 / files
nightly mac
421548077f12 / 40.0a1 / 20150405030238 / files
nightly win32
421548077f12 / 40.0a1 / 20150405030238 / files
nightly win64
421548077f12 / 40.0a1 / 20150405030238 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge b-i to m-c, a=merge
--- a/b2g/components/ProcessGlobal.js
+++ b/b2g/components/ProcessGlobal.js
@@ -161,17 +161,18 @@ ProcessGlobal.prototype = {
     }
     case 'console-api-log-event': {
       // Pipe `console` log messages to the nsIConsoleService which
       // writes them to logcat on Gonk.
       let message = subject.wrappedJSObject;
       let args = message.arguments;
       let stackTrace = '';
 
-      if (message.level == 'assert' || message.level == 'error' || message.level == 'trace') {
+      if (message.stacktrace &&
+          (message.level == 'assert' || message.level == 'error' || message.level == 'trace')) {
         stackTrace = Array.map(message.stacktrace, formatStackFrame).join('\n');
       } else {
         stackTrace = formatStackFrame(message);
       }
 
       if (stackTrace) {
         args.push('\n' + stackTrace);
       }
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="16383ec2bf3ed46f893b15b3fab2892e9fadc4e7"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="e370e6beecd28785beef8c7ff299cf788693f0cc"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="1b1d86462d3150dceacff927536ded9fcc168419"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="16383ec2bf3ed46f893b15b3fab2892e9fadc4e7"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="e370e6beecd28785beef8c7ff299cf788693f0cc"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="3b3407510d6e2c60242e8b9b5f2bc1783ca0a0e4"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="16383ec2bf3ed46f893b15b3fab2892e9fadc4e7"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="e370e6beecd28785beef8c7ff299cf788693f0cc"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="1b1d86462d3150dceacff927536ded9fcc168419"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="16383ec2bf3ed46f893b15b3fab2892e9fadc4e7"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="e370e6beecd28785beef8c7ff299cf788693f0cc"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="1b1d86462d3150dceacff927536ded9fcc168419"/>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="52775e03a2d8532429dff579cb2cd56718e488c3">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="16383ec2bf3ed46f893b15b3fab2892e9fadc4e7"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="e370e6beecd28785beef8c7ff299cf788693f0cc"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="1b1d86462d3150dceacff927536ded9fcc168419"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="16383ec2bf3ed46f893b15b3fab2892e9fadc4e7"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="e370e6beecd28785beef8c7ff299cf788693f0cc"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="3b3407510d6e2c60242e8b9b5f2bc1783ca0a0e4"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="16383ec2bf3ed46f893b15b3fab2892e9fadc4e7"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="e370e6beecd28785beef8c7ff299cf788693f0cc"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="1b1d86462d3150dceacff927536ded9fcc168419"/>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="16383ec2bf3ed46f893b15b3fab2892e9fadc4e7"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="e370e6beecd28785beef8c7ff299cf788693f0cc"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="1b1d86462d3150dceacff927536ded9fcc168419"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "16383ec2bf3ed46f893b15b3fab2892e9fadc4e7", 
+        "git_revision": "e370e6beecd28785beef8c7ff299cf788693f0cc", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "2b1fea55c45ae4b59eb077840bfe5361ecd48d54", 
+    "revision": "e4abf3a2e6a68bafbeec52cdc2a388ff7b9adf3d", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="16383ec2bf3ed46f893b15b3fab2892e9fadc4e7"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="e370e6beecd28785beef8c7ff299cf788693f0cc"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="1b1d86462d3150dceacff927536ded9fcc168419"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="52775e03a2d8532429dff579cb2cd56718e488c3">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="16383ec2bf3ed46f893b15b3fab2892e9fadc4e7"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="e370e6beecd28785beef8c7ff299cf788693f0cc"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="1b1d86462d3150dceacff927536ded9fcc168419"/>
--- a/dom/apps/tests/mochitest.ini
+++ b/dom/apps/tests/mochitest.ini
@@ -49,13 +49,15 @@ skip-if = buildapp == "b2g" || toolkit =
 [test_packaged_app_install.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_packaged_app_update.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_receipt_operations.html]
 [test_signed_pkg_install.html]
 [test_uninstall_errors.html]
 [test_theme_role.html]
+[test_third_party_homescreen.html]
+skip-if = os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
 [test_web_app_install.html]
 [test_widget.html]
 skip-if = os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
 [test_widget_browser.html]
 skip-if = os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
new file mode 100644
--- /dev/null
+++ b/dom/apps/tests/test_third_party_homescreen.html
@@ -0,0 +1,203 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id={1097468}
+-->
+<head>
+  <title>Test for Bug {1097468}</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={1097468}">Mozilla Bug {1097468}</a>
+
+<script class="testbody" type="application/javascript;version=1.7">
+
+var gManifestURL = "http://test/tests/dom/apps/tests/file_app.sjs?apptype=hosted&getmanifest=true";
+var gGenerator = runTest();
+
+const { Services } = SpecialPowers.Cu.import('resource://gre/modules/Services.jsm', {});
+
+function runApp(aApp, aCallback) {
+  var ifr = document.createElement('iframe');
+  ifr.setAttribute('mozbrowser', 'true');
+  ifr.setAttribute('mozapp', aApp.manifestURL);
+  ifr.src = Services.io.newURI(aApp.manifestURL, null, null)
+                       .resolve(aApp.manifest.launch_path);
+
+  ifr.addEventListener('mozbrowsershowmodalprompt', function onAlert(e) {
+    var message = e.detail.message;
+    info("Got message " + message);
+
+    if (message.startsWith("OK: ")) {
+      ok(true, message.substring(4, message.length));
+    } else if (message.startsWith("ERROR: ")) {
+      ok(false, message.substring(7, message.length));
+    } else if (message == "DONE") {
+      ifr.removeEventListener('mozbrowsershowmodalprompt', onAlert, false);
+      loadFrameScript(mm);
+    }
+  }, false);
+
+  document.body.appendChild(ifr);
+
+  var mm = SpecialPowers.getBrowserFrameMessageManager(ifr);
+  ok(mm, "mm is not null");
+  mm.addMessageListener('OK', function(msg) {
+    ok(true, "Message from app: " + SpecialPowers.wrap(msg).json);
+  });
+  mm.addMessageListener('KO', function(msg) {
+    ok(false, "Message from app: " + SpecialPowers.wrap(msg).json);
+  });
+  mm.addMessageListener('DONE', function() {
+    ok(true, "Message from app: complete");
+    document.body.removeChild(ifr);
+    aCallback();
+  });
+
+  // Test permission |homescreen-webapps-manage|
+  function frameScript()
+  {
+    function ok(p, msg) {
+      if (p) {
+      sendAsyncMessage("OK", msg);
+      } else {
+      sendAsyncMessage("KO", msg);
+      }
+    }
+
+    function is(a, b, msg) {
+      if (a == b) {
+        sendAsyncMessage("OK", a + " == " + b + " - " + msg);
+      } else {
+        sendAsyncMessage("KO", a + " != " + b + " - " + msg);
+      }
+    }
+
+    function finish() {
+      sendAsyncMessage("DONE", "");
+    }
+
+    if ('mgmt' in content.window.navigator.mozApps) {
+      ok(true, "get mgmt");
+      var mgmt = content.window.navigator.mozApps.mgmt;
+      is(typeof mgmt.getAll, "function", "get getAll");
+      is(typeof mgmt.uninstall, "function", "get uninstall");
+      is(typeof mgmt.oninstall, "object", "get oninstall");
+      is(typeof mgmt.onuninstall, "object", "get onuninstall");
+      is(typeof mgmt.onenabledstatechange, "object", "get onenabledstatechange");
+
+      [
+        "getNotInstalled",
+        "applyDownload",
+        "import",
+        "extractManifest",
+        "setEnabled"
+      ].forEach(function(func) {
+         is(typeof mgmt[func], "undefined", "shouldn't get" + func);
+       });
+    } else {
+      ok(false, "can not get mgmt");
+    }
+    finish();
+  }
+
+  function loadFrameScript(mm) {
+    var script = "data:,(" + frameScript.toString() + ")();";
+    mm.loadFrameScript(script, /* allowDelayedLoad = */ false);
+  }
+}
+
+function go() {
+  SpecialPowers.pushPermissions(
+    [{ "type": "webapps-manage", "allow": 1, "context": document },
+     { "type": "browser", "allow": 1, "context": document },
+     { "type": "embed-apps", "allow": 1, "context": document }],
+    function() {
+      SpecialPowers.pushPrefEnv({'set': [["dom.mozBrowserFramesEnabled", true],
+                                         ["dom.mozApps.homescreenURL",
+                                          gManifestURL]]},  continueTest)});
+}
+
+function continueTest() {
+  try {
+    gGenerator.next();
+  } catch (e if e instanceof StopIteration) {
+    finish();
+  }
+}
+
+function finish() {
+  SimpleTest.finish();
+}
+
+function cbError(aEvent) {
+  ok(false, "Error callback invoked " +
+            aEvent.target.error.name + " " + aEvent.target.error.message);
+  finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+/**
+ * Test third-party homescreen (permission |homescreen-webapps-manage|)
+ */
+function runTest() {
+  SpecialPowers.setAllAppsLaunchable(true);
+
+  SpecialPowers.autoConfirmAppInstall(continueTest);
+  yield undefined;
+
+  SpecialPowers.autoConfirmAppUninstall(continueTest);
+  yield undefined;
+
+  // Install a app.
+  var request = navigator.mozApps.install(gManifestURL, { });
+  request.onerror = cbError;
+  request.onsuccess = continueTest;
+  yield undefined;
+
+  var app = request.result;
+  ok(app, "App is non-null");
+  is(app.manifestURL, gManifestURL, "App manifest url is correct.");
+
+  var context = {"manifestURL": app.manifestURL, "isInBrowserElement": false};
+
+  SpecialPowers.pushPermissions([{"type": "homescreen-webapps-manage",
+                                  "allow": 1,
+                                  "context": context}], continueTest);
+  yield undefined;
+
+  // Launch the app.
+  info("Running " + app.manifestURL);
+  runApp(app, continueTest);
+  yield undefined;
+
+  SpecialPowers.popPermissions(continueTest);
+  yield undefined;
+
+  // Uninstall the app to cleanup after ourself.
+  navigator.mozApps.mgmt.onuninstall = function(event) {
+    var app = event.application;
+    is(app.manifestURL, gManifestURL, "App uninstall event ok.");
+    is(app.manifest.name, "Really Rapid Release (hosted)",
+       "App uninstall manifest ok.");
+    continueTest();
+  }
+  request = navigator.mozApps.mgmt.uninstall(app);
+  request.onerror = cbError;
+  request.onsuccess = continueTest;
+  yield undefined;
+  yield undefined;
+  is(request.result, gManifestURL, "App uninstalled.");
+  navigator.mozApps.mgmt.onuninstall = null;
+}
+
+addLoadEvent(go);
+
+</script>
+</pre>
+</body>
+</html>
--- a/dom/bluetooth/BluetoothProfileController.cpp
+++ b/dom/bluetooth/BluetoothProfileController.cpp
@@ -171,16 +171,26 @@ BluetoothProfileController::SetupProfile
    * all of them sequencely.
    */
   bool hasAudio = HAS_AUDIO(mTarget.cod);
   bool hasRendering = HAS_RENDERING(mTarget.cod);
   bool isPeripheral = IS_PERIPHERAL(mTarget.cod);
   bool isRemoteControl = IS_REMOTE_CONTROL(mTarget.cod);
   bool isKeyboard = IS_KEYBOARD(mTarget.cod);
   bool isPointingDevice = IS_POINTING_DEVICE(mTarget.cod);
+  bool isInvalid = IS_INVALID_COD(mTarget.cod);
+
+  // The value of CoD is invalid. Since the device didn't declare its class of
+  // device properly, we assume the device may support all of these profiles.
+  if (isInvalid) {
+    AddProfile(BluetoothHfpManager::Get());
+    AddProfile(BluetoothA2dpManager::Get());
+    AddProfile(BluetoothHidManager::Get());
+    return;
+  }
 
   NS_ENSURE_TRUE_VOID(hasAudio || hasRendering || isPeripheral);
 
   // Audio bit should be set if remote device supports HFP/HSP.
   if (hasAudio) {
     AddProfile(BluetoothHfpManager::Get());
   }
 
--- a/dom/bluetooth/BluetoothProfileController.h
+++ b/dom/bluetooth/BluetoothProfileController.h
@@ -48,16 +48,27 @@ BEGIN_BLUETOOTH_NAMESPACE
 #define IS_REMOTE_CONTROL(cod)       ((GET_MINOR_DEVICE_CLASS(cod) & 0xf) == 0x3)
 
 // Keyboard: sub-field of minor device class (Bit 6)
 #define IS_KEYBOARD(cod)             ((GET_MINOR_DEVICE_CLASS(cod) & 0x10) >> 4)
 
 // Pointing device: sub-field of minor device class (Bit 7)
 #define IS_POINTING_DEVICE(cod)      ((GET_MINOR_DEVICE_CLASS(cod) & 0x20) >> 5)
 
+/**
+ * Check whether the value of CoD is invalid. (i.e. Bit 31 ~ Bit 24 != 0x0)
+ *
+ * According to Bluetooth core spec v4.1. Vol 2, Sec. 7.3, the data length of
+ * CoD (class of device) is 3 bytes. The two least significant bits are used to
+ * indicate 'format type'. The following 22 bits are used to indicate category
+ * of service class and device type. The remaining 8 bits (Bit 31 ~ Bit 24)
+ * should be unassigned bits, since BlueDroid uses uint32_t to store CoD.
+ */
+#define IS_INVALID_COD(cod)          (cod >> 24)
+
 class BluetoothProfileManagerBase;
 class BluetoothReplyRunnable;
 typedef void (*BluetoothProfileControllerCallback)();
 
 class BluetoothProfileController final
 {
   ~BluetoothProfileController();
 
--- a/dom/bluetooth2/BluetoothProfileController.cpp
+++ b/dom/bluetooth2/BluetoothProfileController.cpp
@@ -168,16 +168,26 @@ BluetoothProfileController::SetupProfile
    * all of them sequencely.
    */
   bool hasAudio = HAS_AUDIO(mTarget.cod);
   bool hasRendering = HAS_RENDERING(mTarget.cod);
   bool isPeripheral = IS_PERIPHERAL(mTarget.cod);
   bool isRemoteControl = IS_REMOTE_CONTROL(mTarget.cod);
   bool isKeyboard = IS_KEYBOARD(mTarget.cod);
   bool isPointingDevice = IS_POINTING_DEVICE(mTarget.cod);
+  bool isInvalid = IS_INVALID_COD(mTarget.cod);
+
+  // The value of CoD is invalid. Since the device didn't declare its class of
+  // device properly, we assume the device may support all of these profiles.
+  if (isInvalid) {
+    AddProfile(BluetoothHfpManager::Get());
+    AddProfile(BluetoothA2dpManager::Get());
+    AddProfile(BluetoothHidManager::Get());
+    return;
+  }
 
   NS_ENSURE_TRUE_VOID(hasAudio || hasRendering || isPeripheral);
 
   // Audio bit should be set if remote device supports HFP/HSP.
   if (hasAudio) {
     AddProfile(BluetoothHfpManager::Get());
   }
 
--- a/dom/bluetooth2/BluetoothProfileController.h
+++ b/dom/bluetooth2/BluetoothProfileController.h
@@ -48,16 +48,27 @@ BEGIN_BLUETOOTH_NAMESPACE
 #define IS_REMOTE_CONTROL(cod)       ((GET_MINOR_DEVICE_CLASS(cod) & 0xf) == 0x3)
 
 // Keyboard: sub-field of minor device class (Bit 6)
 #define IS_KEYBOARD(cod)             ((GET_MINOR_DEVICE_CLASS(cod) & 0x10) >> 4)
 
 // Pointing device: sub-field of minor device class (Bit 7)
 #define IS_POINTING_DEVICE(cod)      ((GET_MINOR_DEVICE_CLASS(cod) & 0x20) >> 5)
 
+/**
+ * Check whether the value of CoD is invalid. (i.e. Bit 31 ~ Bit 24 != 0x0)
+ *
+ * According to Bluetooth core spec v4.1. Vol 2, Sec. 7.3, the data length of
+ * CoD (class of device) is 3 bytes. The two least significant bits are used to
+ * indicate 'format type'. The following 22 bits are used to indicate category
+ * of service class and device type. The remaining 8 bits (Bit 31 ~ Bit 24)
+ * should be unassigned bits, since BlueDroid uses uint32_t to store CoD.
+ */
+#define IS_INVALID_COD(cod)          (cod >> 24)
+
 class BluetoothProfileManagerBase;
 class BluetoothReplyRunnable;
 typedef void (*BluetoothProfileControllerCallback)();
 
 class BluetoothProfileController final
 {
   ~BluetoothProfileController();
 
--- a/dom/browser-element/BrowserElementChildPreload.js
+++ b/dom/browser-element/BrowserElementChildPreload.js
@@ -167,16 +167,21 @@ BrowserElementChild.prototype = {
                      /* useCapture = */ true,
                      /* wantsUntrusted = */ false);
 
     addEventListener('scrollviewchange',
                      this._ScrollViewChangeHandler.bind(this),
                      /* useCapture = */ true,
                      /* wantsUntrusted = */ false);
 
+    addEventListener('click',
+                     this._ClickHandler.bind(this),
+                     /* useCapture = */ false,
+                     /* wantsUntrusted = */ false);
+
     // This listens to unload events from our message manager, but /not/ from
     // the |content| window.  That's because the window's unload event doesn't
     // bubble, and we're not using a capturing listener.  If we'd used
     // useCapture == true, we /would/ hear unload events from the window, which
     // is not what we want!
     addEventListener('unload',
                      this._unloadHandler.bind(this),
                      /* useCapture = */ false,
@@ -574,16 +579,28 @@ BrowserElementChild.prototype = {
   _ScrollViewChangeHandler: function(e) {
     e.stopPropagation();
     let detail = {
       state: e.state,
     };
     sendAsyncMsg('scrollviewchange', detail);
   },
 
+  _ClickHandler: function(e) {
+    let elem = e.target;
+    if (elem instanceof Ci.nsIDOMHTMLAnchorElement && elem.href) {
+      // Open in a new tab if middle click or ctrl/cmd-click.
+      if ((Services.appinfo.OS == 'Darwin' && e.metaKey) ||
+          (Services.appinfo.OS != 'Darwin' && e.ctrlKey) ||
+           e.button == 1) {
+        sendAsyncMsg('opentab', {url: elem.href});
+      }
+    }
+  },
+
   _selectionStateChangedHandler: function(e) {
     e.stopPropagation();
 
     if (!this._isContentWindowCreated) {
       return;
     }
 
     let boundingClientRect = e.boundingClientRect;
@@ -1080,17 +1097,17 @@ BrowserElementChild.prototype = {
   _recvOwnerVisibilityChange: function(data) {
     debug("Received ownerVisibilityChange: (" + data.json.visible + ")");
     this._ownerVisible = data.json.visible;
     this._updateVisibility();
   },
 
   _updateVisibility: function() {
     var visible = this._forcedVisible && this._ownerVisible;
-    if (docShell.isActive !== visible) {
+    if (docShell && docShell.isActive !== visible) {
       docShell.isActive = visible;
       sendAsyncMsg('visibilitychange', {visible: visible});
     }
   },
 
   _recvSendMouseEvent: function(data) {
     let json = data.json;
     let utils = content.QueryInterface(Ci.nsIInterfaceRequestor)
--- a/dom/browser-element/BrowserElementParent.js
+++ b/dom/browser-element/BrowserElementParent.js
@@ -209,17 +209,18 @@ BrowserElementParent.prototype = {
       "iconchange": this._fireEventFromMsg,
       "scrollareachanged": this._fireEventFromMsg,
       "titlechange": this._fireProfiledEventFromMsg,
       "opensearch": this._fireEventFromMsg,
       "manifestchange": this._fireEventFromMsg,
       "metachange": this._fireEventFromMsg,
       "resize": this._fireEventFromMsg,
       "activitydone": this._fireEventFromMsg,
-      "scroll": this._fireEventFromMsg
+      "scroll": this._fireEventFromMsg,
+      "opentab": this._fireEventFromMsg
     };
 
     this._mm.addMessageListener('browser-element-api:call', function(aMsg) {
       if (!self._isAlive()) {
         return;
       }
 
       if (aMsg.data.msg_name in mmCalls) {
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/browserElement_OpenTab.js
@@ -0,0 +1,69 @@
+/* Any copyright is dedicated to the public domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Bug 1144015 - test middle/ctrl/cmd-click on a link.
+
+"use strict";
+SimpleTest.waitForExplicitFinish();
+browserElementTestHelpers.setEnabledPref(true);
+browserElementTestHelpers.addPermission();
+
+function runTest() {
+  let iframe = document.createElement('iframe');
+  iframe.setAttribute('mozbrowser', 'true');
+  document.body.appendChild(iframe);
+
+  let x = 2;
+  let y = 2;
+  // First we force a reflow so that getChildProcessOffset actually returns
+  // meaningful data.
+  iframe.getBoundingClientRect();
+  // We need to make sure the event coordinates are actually inside the iframe,
+  // relative to the chome window.
+  let tabParent = SpecialPowers.wrap(iframe)
+                  .QueryInterface(SpecialPowers.Ci.nsIFrameLoaderOwner)
+                  .frameLoader.tabParent;
+  if (tabParent) {
+    let offsetX = {};
+    let offsetY = {};
+    tabParent.getChildProcessOffset(offsetX, offsetY);
+    x -= offsetX.value;
+    y -= offsetY.value;
+  }
+
+  let sendCtrlClick = () => {
+    let nsIDOMWindowUtils = SpecialPowers.Ci.nsIDOMWindowUtils;
+    let mod = nsIDOMWindowUtils.MODIFIER_META |
+              nsIDOMWindowUtils.MODIFIER_CONTROL;
+    iframe.sendMouseEvent('mousedown', x, y, 0, 1, mod);
+    iframe.sendMouseEvent('mouseup', x, y, 0, 1, mod);
+  }
+
+  let onCtrlClick = e => {
+    is(e.detail.url, 'http://example.com/', 'URL matches');
+    iframe.removeEventListener('mozbrowseropentab', onCtrlClick);
+    iframe.addEventListener('mozbrowseropentab', onMiddleClick);
+    sendMiddleClick();
+  }
+
+  let sendMiddleClick = () => {
+    iframe.sendMouseEvent('mousedown', x, y, 1, 1, 0);
+    iframe.sendMouseEvent('mouseup', x, y, 1, 1, 0);
+  }
+
+  let onMiddleClick= e => {
+    is(e.detail.url, 'http://example.com/', 'URL matches');
+    iframe.removeEventListener('mozbrowseropentab', onMiddleClick);
+    SimpleTest.finish();
+  }
+
+  iframe.addEventListener('mozbrowserloadend', e => {
+    iframe.addEventListener('mozbrowseropentab', onCtrlClick);
+    sendCtrlClick();
+  });
+
+
+  iframe.src = 'data:text/html,<body style="margin:0"><a href="http://example.com">click here</a></body>';
+}
+
+addEventListener('testready', runTest);
--- a/dom/browser-element/mochitest/mochitest-oop.ini
+++ b/dom/browser-element/mochitest/mochitest-oop.ini
@@ -2,16 +2,17 @@
 # Both the "inproc" and "oop" versions of OpenMixedProcess open remote frames,
 # so we don't run that test on platforms which don't support OOP tests.
 # OOP tests don't work on native-fennec (bug 774939).
 # Bug 960345 - Disabled on OSX debug for frequent crashes.
 skip-if = os == "android" || (toolkit == "cocoa" && debug) || buildapp == 'mulet' || (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || e10s
 support-files =
   browserElement_OpenMixedProcess.js
   file_browserElement_OpenMixedProcess.html
+  browserElement_OpenTab.js
 
 [test_browserElement_oop_ThemeColor.html]
 [test_browserElement_inproc_ErrorSecurity.html]
 skip-if = toolkit=='gonk'
 [test_browserElement_inproc_OpenMixedProcess.html]
 skip-if = toolkit=='gonk' || (toolkit == 'gonk' && !debug)
 [test_browserElement_oop_Alert.html]
 [test_browserElement_oop_AlertInFrame.html]
@@ -55,16 +56,18 @@ skip-if = (toolkit == 'gonk' && !debug)
 skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_oop_OpenWindowDifferentOrigin.html]
 skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_oop_OpenWindowInFrame.html]
 skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_oop_OpenWindowRejected.html]
 skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_oop_Opensearch.html]
+[test_browserElement_oop_OpenTab.html]
+skip-if = (toolkit == 'gonk') # Disabled on emulator. See bug 1144015 comment 8
 [test_browserElement_oop_PrivateBrowsing.html]
 [test_browserElement_oop_PromptCheck.html]
 [test_browserElement_oop_PromptConfirm.html]
 [test_browserElement_oop_PurgeHistory.html]
 [test_browserElement_oop_Reload.html]
 [test_browserElement_oop_ReloadPostRequest.html]
 [test_browserElement_oop_RemoveBrowserElement.html]
 [test_browserElement_oop_ScrollEvent.html]
--- a/dom/browser-element/mochitest/mochitest.ini
+++ b/dom/browser-element/mochitest/mochitest.ini
@@ -33,16 +33,17 @@ support-files =
   browserElement_GetScreenshot.js
   browserElement_GetScreenshotDppx.js
   browserElement_Iconchange.js
   browserElement_LoadEvents.js
   browserElement_Manifestchange.js
   browserElement_Metachange.js
   browserElement_NextPaint.js
   browserElement_OpenNamed.js
+  browserElement_OpenTab.js
   browserElement_OpenWindow.js
   browserElement_OpenWindowDifferentOrigin.js
   browserElement_OpenWindowInFrame.js
   browserElement_OpenWindowRejected.js
   browserElement_Opensearch.js
   browserElement_PrivateBrowsing.js
   browserElement_PromptCheck.js
   browserElement_PromptConfirm.js
@@ -163,16 +164,18 @@ skip-if = (toolkit == 'android' && proce
 [test_browserElement_inproc_GetScreenshotDppx.html]
 [test_browserElement_inproc_Iconchange.html]
 [test_browserElement_inproc_LoadEvents.html]
 [test_browserElement_inproc_Manifestchange.html]
 [test_browserElement_inproc_Metachange.html]
 [test_browserElement_inproc_NextPaint.html]
 [test_browserElement_inproc_OpenNamed.html]
 skip-if = (toolkit == 'gonk' && !debug)
+[test_browserElement_inproc_OpenTab.html]
+disabled = won't work as Firefox desktop will intercept ctrl-click
 [test_browserElement_inproc_OpenWindow.html]
 skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_inproc_OpenWindowDifferentOrigin.html]
 skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_inproc_OpenWindowInFrame.html]
 skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_inproc_OpenWindowRejected.html]
 skip-if = (toolkit == 'gonk' && !debug)
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/test_browserElement_inproc_OpenTab.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1144015
+-->
+<head>
+  <title>Test for Bug 1144015</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1144015">Mozilla Bug 1144015</a>
+
+<script type="application/javascript;version=1.7" src="browserElement_OpenTab.js">
+</script>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/test_browserElement_oop_OpenTab.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1144015
+-->
+<head>
+  <title>Test for Bug 1144015</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1144015">Mozilla Bug 1144015</a>
+
+<script type="application/javascript;version=1.7" src="browserElement_OpenTab.js">
+</script>
+</body>
+</html>
+
--- a/dom/system/gonk/NetworkUtils.cpp
+++ b/dom/system/gonk/NetworkUtils.cpp
@@ -987,24 +987,49 @@ void NetworkUtils::setDefaultInterface(C
 
   doCommand(command, aChain, aCallback);
 }
 
 void NetworkUtils::removeDefaultRoute(CommandChain* aChain,
                                       CommandCallback aCallback,
                                       NetworkResultOptions& aResult)
 {
+  if (GET_FIELD(mLoopIndex) >= GET_FIELD(mGateways).Length()) {
+    aCallback(aChain, false, aResult);
+    return;
+  }
+
   char command[MAX_COMMAND_SIZE];
-  // FIXME: (Bug 1121795) We only remove the first gateway to the default route.
-  //        For dual stack (ipv4/ipv6) device, one of the gateway would
-  //        not be added to the default route.
-  snprintf(command, MAX_COMMAND_SIZE - 1, "network route remove %d %s 0.0.0.0/0 %s",
-                    GET_FIELD(mNetId), GET_CHAR(mIfname), GET_CHAR(mGateways[0]));
-
-  doCommand(command, aChain, aCallback);
+  nsTArray<nsString>& gateways = GET_FIELD(mGateways);
+  NS_ConvertUTF16toUTF8 autoGateway(gateways[GET_FIELD(mLoopIndex)]);
+
+  int type = getIpType(autoGateway.get());
+  snprintf(command, MAX_COMMAND_SIZE - 1, "network route remove %d %s %s/0 %s",
+           GET_FIELD(mNetId), GET_CHAR(mIfname),
+           type == AF_INET6 ? "::" : "0.0.0.0", autoGateway.get());
+
+  struct MyCallback {
+    static void callback(CommandCallback::CallbackType aOriginalCallback,
+                         CommandChain* aChain,
+                         bool aError,
+                         mozilla::dom::NetworkResultOptions& aResult)
+    {
+      NS_ConvertUTF16toUTF8 reason(aResult.mResultReason);
+      NU_DBG("removeDefaultRoute's reason: %s", reason.get());
+      if (aError && !reason.EqualsASCII("removeRoute() failed (No such process)")) {
+        return aOriginalCallback(aChain, aError, aResult);
+      }
+
+      GET_FIELD(mLoopIndex)++;
+      return removeDefaultRoute(aChain, aOriginalCallback, aResult);
+    }
+  };
+
+  CommandCallback wrappedCallback(MyCallback::callback, aCallback);
+  doCommand(command, aChain, wrappedCallback);
 }
 
 void NetworkUtils::setInterfaceDns(CommandChain* aChain,
                                    CommandCallback aCallback,
                                    NetworkResultOptions& aResult)
 {
   char command[MAX_COMMAND_SIZE];
   int written;
@@ -1142,37 +1167,44 @@ void NetworkUtils::modifyRouteOnInterfac
 
   doCommand(command, aChain, aCallback);
 }
 
 void NetworkUtils::addDefaultRouteToNetwork(CommandChain* aChain,
                                             CommandCallback aCallback,
                                             NetworkResultOptions& aResult)
 {
+  if (GET_FIELD(mLoopIndex) >= GET_FIELD(mGateways).Length()) {
+    aCallback(aChain, false, aResult);
+    return;
+  }
+
   char command[MAX_COMMAND_SIZE];
-
-  // FIXME: (Bug 1121795) We only add the first gateway to the default route.
-  //        For dual stack (ipv4/ipv6) device, one of the gateway would
-  //        not be added to the default route.
-  snprintf(command, MAX_COMMAND_SIZE - 1, "network route add %d %s 0.0.0.0/0 %s",
-                    GET_FIELD(mNetId), GET_CHAR(mIfname), GET_CHAR(mGateways[0]));
+  nsTArray<nsString>& gateways = GET_FIELD(mGateways);
+  NS_ConvertUTF16toUTF8 autoGateway(gateways[GET_FIELD(mLoopIndex)]);
+
+  int type = getIpType(autoGateway.get());
+  snprintf(command, MAX_COMMAND_SIZE - 1, "network route add %d %s %s/0 %s",
+           GET_FIELD(mNetId), GET_CHAR(mIfname),
+           type == AF_INET6 ? "::" : "0.0.0.0", autoGateway.get());
 
   struct MyCallback {
     static void callback(CommandCallback::CallbackType aOriginalCallback,
                          CommandChain* aChain,
                          bool aError,
                          mozilla::dom::NetworkResultOptions& aResult)
     {
       NS_ConvertUTF16toUTF8 reason(aResult.mResultReason);
       NU_DBG("addDefaultRouteToNetwork's reason: %s", reason.get());
-      if (aError && reason.EqualsASCII("addRoute() failed (File exists)")) {
-        NU_DBG("Ignore \"File exists\" error when adding host route.");
-        return aOriginalCallback(aChain, false, aResult);
+      if (aError && !reason.EqualsASCII("addRoute() failed (File exists)")) {
+        return aOriginalCallback(aChain, aError, aResult);
       }
-      aOriginalCallback(aChain, aError, aResult);
+
+      GET_FIELD(mLoopIndex)++;
+      return addDefaultRouteToNetwork(aChain, aOriginalCallback, aResult);
     }
   };
 
   CommandCallback wrappedCallback(MyCallback::callback, aCallback);
   doCommand(command, aChain, wrappedCallback);
 }
 
 void NetworkUtils::setDefaultNetwork(CommandChain* aChain,
@@ -1805,18 +1837,19 @@ CommandResult NetworkUtils::setDefaultRo
 
   NetIdManager::NetIdInfo netIdInfo;
   if (!mNetIdManager.lookup(GET_FIELD(mIfname), &netIdInfo)) {
     ERROR("No such interface");
     return -1;
   }
 
   aOptions.mNetId = netIdInfo.mNetId;
-
+  aOptions.mLoopIndex = 0;
   runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler);
+
   return CommandResult::Pending();
 }
 
 /**
  * Set default route and DNS servers for given network interface by obsoleted libnetutils.
  */
 CommandResult NetworkUtils::setDefaultRouteLegacy(NetworkParams& aOptions)
 {
@@ -1888,16 +1921,17 @@ CommandResult NetworkUtils::removeDefaul
   if (!mNetIdManager.lookup(GET_FIELD(mIfname), &netIdInfo)) {
     ERROR("No such interface: %s", GET_CHAR(mIfname));
     return -1;
   }
 
   NU_DBG("Obtained netid %d for interface %s", netIdInfo.mNetId, GET_CHAR(mIfname));
 
   aOptions.mNetId = netIdInfo.mNetId;
+  aOptions.mLoopIndex = 0;
   runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler);
 
   return CommandResult::Pending();
 }
 
 /**
  * Remove default route for given network interface by obsoleted libnetutils.
  */
--- a/dom/system/gonk/NetworkUtils.h
+++ b/dom/system/gonk/NetworkUtils.h
@@ -141,16 +141,18 @@ public:
     COPY_OPT_STRING_FIELD(mCurExternalIfname, EmptyString())
     COPY_OPT_FIELD(mThreshold, -1)
     COPY_OPT_FIELD(mIpaddr, 0)
     COPY_OPT_FIELD(mMask, 0)
     COPY_OPT_FIELD(mGateway_long, 0)
     COPY_OPT_FIELD(mDns1_long, 0)
     COPY_OPT_FIELD(mDns2_long, 0)
 
+    mLoopIndex = 0;
+
 #undef COPY_SEQUENCE_FIELD
 #undef COPY_OPT_STRING_FIELD
 #undef COPY_OPT_FIELD
 #undef COPY_FIELD
   }
 
   // Followings attributes are 1-to-1 mapping to NetworkCommandOptions.
   int32_t mId;
@@ -193,17 +195,18 @@ public:
   long mThreshold;
   long mIpaddr;
   long mMask;
   long mGateway_long;
   long mDns1_long;
   long mDns2_long;
 
   // Auxiliary information required to carry accros command chain.
-  int mNetId;     // A locally defined id per interface.
+  int mNetId; // A locally defined id per interface.
+  uint32_t mLoopIndex; // Loop index for adding/removing multiple gateways.
 };
 
 // CommandChain store the necessary information to execute command one by one.
 // Including :
 // 1. Command parameters.
 // 2. Command list.
 // 3. Error callback function.
 // 4. Index of current execution command.
--- a/dom/webidl/Apps.webidl
+++ b/dom/webidl/Apps.webidl
@@ -19,17 +19,17 @@ enum LocaleResourceType {
   "binary",
   "json",
   "text"
 };
 
 [NoInterfaceObject, NavigatorProperty="mozApps",
  JSImplementation="@mozilla.org/webapps;1"]
 interface DOMApplicationsRegistry {
-  [CheckPermissions="webapps-manage"]
+  [CheckPermissions="webapps-manage homescreen-webapps-manage"]
   readonly attribute DOMApplicationsManager mgmt;
   DOMRequest install(DOMString url, optional InstallParameters params);
   DOMRequest installPackage(DOMString url, optional InstallParameters params);
   DOMRequest getSelf();
   DOMRequest getInstalled();
   DOMRequest checkInstalled(DOMString manifestUrl);
 
   // Language pack API.
@@ -111,26 +111,32 @@ interface DOMApplication : EventTarget {
   // a langpack if one is available.
   Promise<DOMString> getLocalizedValue(DOMString property,
                                        DOMString locale,
                                        optional DOMString entryPoint);
 };
 
 [JSImplementation="@mozilla.org/webapps/manager;1",
  ChromeOnly,
- CheckPermissions="webapps-manage"]
+ CheckPermissions="webapps-manage homescreen-webapps-manage"]
 interface DOMApplicationsManager : EventTarget {
   DOMRequest getAll();
+
+  [CheckPermissions="webapps-manage"]
   DOMRequest getNotInstalled();
+  [CheckPermissions="webapps-manage"]
   void applyDownload(DOMApplication app);
   DOMRequest uninstall(DOMApplication app);
 
+  [CheckPermissions="webapps-manage"]
   Promise<DOMApplication> import(Blob blob);
+  [CheckPermissions="webapps-manage"]
   Promise<any> extractManifest(Blob blob);
 
+  [CheckPermissions="webapps-manage"]
   void setEnabled(DOMApplication app, boolean state);
   Promise<Blob> getIcon(DOMApplication app, DOMString iconID,
                         optional DOMString entryPoint);
 
   attribute EventHandler oninstall;
   attribute EventHandler onuninstall;
   attribute EventHandler onenabledstatechange;
 };
--- a/gfx/layers/composite/CompositableHost.h
+++ b/gfx/layers/composite/CompositableHost.h
@@ -151,16 +151,22 @@ public:
   {
     MOZ_ASSERT(aCompositor, "Compositor is required");
     NS_ASSERTION(aFlags & ALLOW_REATTACH || !mAttached,
                  "Re-attaching compositables must be explicitly authorised");
     SetCompositor(aCompositor);
     SetLayer(aLayer);
     mAttached = true;
     mKeepAttached = aFlags & KEEP_ATTACHED;
+
+    // If we already have a textureHost before, use that in this moment.
+    RefPtr<TextureHost> frontBuffer = GetAsTextureHost();
+    if (frontBuffer) {
+      UseTextureHost(frontBuffer);
+    }
   }
   // Detach this compositable host from its layer.
   // If we are used for async video, then it is not safe to blindly detach since
   // we might be re-attached to a different layer. aLayer is the layer which the
   // caller expects us to be attached to, we will only detach if we are in fact
   // attached to that layer. If we are part of a normal layer, then we will be
   // detached in any case. if aLayer is null, then we will only detach if we are
   // not async.
--- a/testing/taskcluster/tasks/builds/b2g_desktop_opt.yml
+++ b/testing/taskcluster/tasks/builds/b2g_desktop_opt.yml
@@ -1,15 +1,19 @@
 $inherits:
   from: 'tasks/builds/b2g_desktop_base.yml'
   variables:
     build_name: 'b2g-desktop'
     build_type: 'opt'
 task:
   scopes:
-      - 'docker-worker:cache:workspace-b2g-desktop-objects-opt'
+    - 'docker-worker:cache:workspace-b2g-desktop-objects-opt'
+  routes:
+    - 'index.buildbot.branches.{{project}}.linux64_gecko'
+    - 'index.buildbot.revisions.{{head_rev}}.{{project}}.linux64_gecko'
+
   workerType: b2g-desktop-opt
   payload:
     cache:
       workspace-b2g-desktop-objects-opt: '/home/worker/workspace'
 
     env:
       MOZCONFIG: 'b2g/config/mozconfigs/linux64_gecko/nightly'
--- a/testing/taskcluster/tasks/builds/mulet_linux.yml
+++ b/testing/taskcluster/tasks/builds/mulet_linux.yml
@@ -4,16 +4,21 @@
     build_name: 'mulet'
     build_type: 'opt'
 task:
   metadata:
     name: '[TC] Mulet Linux'
     description: Mulet Linux
 
   workerType: mulet-opt
+
+  routes:
+    - 'index.buildbot.branches.{{project}}.linux64-mulet'
+    - 'index.buildbot.revisions.{{head_rev}}.{{project}}.linux64-mulet'
+
   scopes:
     - 'docker-worker:cache:build-mulet-linux-workspace'
     - 'docker-worker:cache:tooltool-cache'
 
   payload:
     cache:
       build-mulet-linux-workspace: '/home/worker/workspace'
       tooltool-cache: '/home/worker/tools/tooltool-cache'