Merge b2g-inbound to mozilla-central a=merge
authorWes Kocher <wkocher@mozilla.com>
Wed, 04 Jun 2014 17:36:15 -0700
changeset 206873 2ebadbba6cc8a05d5e2a196316295b9857f02cb1
parent 206822 951e3a671279b5958a4e8bb984fd1882cb9642bf (current diff)
parent 206872 bd6e2010a4ec4de0b08d244cf7fb102830d3d0e3 (diff)
child 206894 8828261990767364e2b6c54ecd214924fe12f44b
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge b2g-inbound to mozilla-central a=merge
--- 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="2a165bebfa19b11b697837409f9550dd2917c46c">
     <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="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="d2cfef555dabab415085e548ed44c48a99be5c32"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8e4420c0c5c8e8c8e58a000278a7129403769f96"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9100fa82fc355f5201e23e400fc6b40e875304ed"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
   <!-- 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="6e2a3b589d1e8cc1d9df25f5e630ce30a0aa39f3">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="d2cfef555dabab415085e548ed44c48a99be5c32"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
   <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="276ce45e78b09c4a4ee643646f691d22804754c1">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="d2cfef555dabab415085e548ed44c48a99be5c32"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <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="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
--- 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="2a165bebfa19b11b697837409f9550dd2917c46c">
     <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="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="d2cfef555dabab415085e548ed44c48a99be5c32"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8e4420c0c5c8e8c8e58a000278a7129403769f96"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9100fa82fc355f5201e23e400fc6b40e875304ed"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- 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="6e2a3b589d1e8cc1d9df25f5e630ce30a0aa39f3">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="d2cfef555dabab415085e548ed44c48a99be5c32"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
   <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": "", 
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "cd1a16d6212a1867ecf1d1cfcd62f80abf9ae0b1", 
+    "revision": "7f0af1e164a39efb732c0c341c2a8e51f681d913", 
     "repo_path": "/integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <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="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="d2cfef555dabab415085e548ed44c48a99be5c32"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <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="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="d2cfef555dabab415085e548ed44c48a99be5c32"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- 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="6e2a3b589d1e8cc1d9df25f5e630ce30a0aa39f3">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="d2cfef555dabab415085e548ed44c48a99be5c32"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
   <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/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <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="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="d2cfef555dabab415085e548ed44c48a99be5c32"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/content/media/AudioStream.cpp
+++ b/content/media/AudioStream.cpp
@@ -128,18 +128,18 @@ static cubeb_stream_type ConvertChannelT
     case dom::AudioChannel::Notification:
       return CUBEB_STREAM_TYPE_NOTIFICATION;
     case dom::AudioChannel::Alarm:
       return CUBEB_STREAM_TYPE_ALARM;
     case dom::AudioChannel::Telephony:
       return CUBEB_STREAM_TYPE_VOICE_CALL;
     case dom::AudioChannel::Ringer:
       return CUBEB_STREAM_TYPE_RING;
-    // Currently Android openSLES library doesn't support FORCE_AUDIBLE yet.
     case dom::AudioChannel::Publicnotification:
+      return CUBEB_STREAM_TYPE_SYSTEM_ENFORCED;
     default:
       NS_ERROR("The value of AudioChannel is invalid");
       return CUBEB_STREAM_TYPE_MAX;
   }
 }
 #endif
 
 AudioStream::AudioStream()
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -659,41 +659,48 @@ this.DOMApplicationRegistry = {
     }
 
     if (!root.messages || !Array.isArray(root.messages) ||
         root.messages.length == 0) {
       return;
     }
 
     let manifest = new ManifestHelper(aManifest, aApp.origin);
-    let launchPath = Services.io.newURI(manifest.fullLaunchPath(aEntryPoint), null, null);
-    let manifestURL = Services.io.newURI(aApp.manifestURL, null, null);
+    let launchPathURI = Services.io.newURI(manifest.fullLaunchPath(aEntryPoint), null, null);
+    let manifestURI = Services.io.newURI(aApp.manifestURL, null, null);
     root.messages.forEach(function registerPages(aMessage) {
-      let href = launchPath;
+      let handlerPageURI = launchPathURI;
       let messageName;
       if (typeof(aMessage) === "object" && Object.keys(aMessage).length === 1) {
         messageName = Object.keys(aMessage)[0];
-        let uri;
+        let handlerPath = aMessage[messageName];
+        // Resolve the handler path from origin. If |handler_path| is absent,
+        // simply skip.
+        let fullHandlerPath;
         try {
-          uri = manifest.resolveFromOrigin(aMessage[messageName]);
+          if (handlerPath && handlerPath.trim()) {
+            fullHandlerPath = manifest.resolveFromOrigin(handlerPath);
+          } else {
+            throw new Error("Empty or blank handler path.");
+          }
         } catch(e) {
-          debug("system message url (" + aMessage[messageName] + ") is invalid, skipping. " +
-                "Error is: " + e);
+          debug("system message handler path (" + handlerPath + ") is " +
+                "invalid, skipping. Error is: " + e);
           return;
         }
-        href = Services.io.newURI(uri, null, null);
+        handlerPageURI = Services.io.newURI(fullHandlerPath, null, null);
       } else {
         messageName = aMessage;
       }
 
       if (SystemMessagePermissionsChecker
             .isSystemMessagePermittedToRegister(messageName,
                                                 aApp.origin,
                                                 aManifest)) {
-        msgmgr.registerPage(messageName, href, manifestURL);
+        msgmgr.registerPage(messageName, handlerPageURI, manifestURI);
       }
     });
   },
 
   // |aEntryPoint| is either the entry_point name or the null in which case we
   // use the root of the manifest.
   //
   // TODO Bug 908094 Refine _registerInterAppConnectionsForEntryPoint(...).
@@ -822,24 +829,24 @@ this.DOMApplicationRegistry = {
 
       if (aRunUpdate) {
         activitiesToRegister.push({ "manifest": aApp.manifestURL,
                                     "name": activity,
                                     "icon": manifest.iconURLForSize(128),
                                     "description": newDesc });
       }
 
-      let launchPath = Services.io.newURI(href, null, null);
-      let manifestURL = Services.io.newURI(aApp.manifestURL, null, null);
+      let launchPathURI = Services.io.newURI(href, null, null);
+      let manifestURI = Services.io.newURI(aApp.manifestURL, null, null);
 
       if (SystemMessagePermissionsChecker
             .isSystemMessagePermittedToRegister("activity",
                                                 aApp.origin,
                                                 aManifest)) {
-        msgmgr.registerPage("activity", launchPath, manifestURL);
+        msgmgr.registerPage("activity", launchPathURI, manifestURI);
       }
     }
     return activitiesToRegister;
   },
 
   // |aAppsToRegister| contains an array of apps to be registered, where
   // each element is an object in the format of {manifest: foo, app: bar}.
   _registerActivitiesForApps: function(aAppsToRegister, aRunUpdate) {
--- a/dom/bluetooth2/ipc/BluetoothParent.cpp
+++ b/dom/bluetooth2/ipc/BluetoothParent.cpp
@@ -19,17 +19,17 @@
 
 using mozilla::unused;
 USING_BLUETOOTH_NAMESPACE
 
 /*******************************************************************************
  * BluetoothRequestParent::ReplyRunnable
  ******************************************************************************/
 
-class BluetoothRequestParent::ReplyRunnable : public BluetoothReplyRunnable
+class BluetoothRequestParent::ReplyRunnable MOZ_FINAL : public BluetoothReplyRunnable
 {
   BluetoothRequestParent* mRequest;
 
 public:
   ReplyRunnable(BluetoothRequestParent* aRequest)
   : BluetoothReplyRunnable(nullptr), mRequest(aRequest)
   {
     MOZ_ASSERT(NS_IsMainThread());
@@ -54,25 +54,32 @@ public:
 
     ReleaseMembers();
     return NS_OK;
   }
 
   void
   Revoke()
   {
-    MOZ_ASSERT(NS_IsMainThread());
-    mRequest = nullptr;
+    ReleaseMembers();
   }
 
   virtual bool
   ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) MOZ_OVERRIDE
   {
     MOZ_CRASH("This should never be called!");
   }
+
+  virtual void
+  ReleaseMembers() MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    mRequest = nullptr;
+    BluetoothReplyRunnable::ReleaseMembers();
+  }
 };
 
 /*******************************************************************************
  * BluetoothParent
  ******************************************************************************/
 
 BluetoothParent::BluetoothParent()
 : mShutdownState(Running)
--- a/dom/camera/GonkCameraParameters.cpp
+++ b/dom/camera/GonkCameraParameters.cpp
@@ -133,16 +133,17 @@ GonkCameraParameters::Parameters::GetTex
       return nullptr;
   }
 }
 
 GonkCameraParameters::GonkCameraParameters()
   : mLock(PR_NewRWLock(PR_RWLOCK_RANK_NONE, "GonkCameraParameters.Lock"))
   , mDirty(false)
   , mInitialized(false)
+  , mExposureCompensationStep(0.0)
 {
   MOZ_COUNT_CTOR(GonkCameraParameters);
   if (!mLock) {
     MOZ_CRASH("Out of memory getting new PRRWLock");
   }
 }
 
 GonkCameraParameters::~GonkCameraParameters()
@@ -194,25 +195,30 @@ GonkCameraParameters::MapIsoFromGonk(con
 
 // Any members that need to be initialized on the first parameter pull
 // need to get handled in here.
 nsresult
 GonkCameraParameters::Initialize()
 {
   nsresult rv;
 
-  rv = GetImpl(CAMERA_PARAM_SUPPORTED_MINEXPOSURECOMPENSATION, mExposureCompensationMin);
-  if (NS_FAILED(rv)) {
-    NS_WARNING("Failed to initialize minimum exposure compensation");
-    mExposureCompensationMin = 0;
-  }
-  rv = GetImpl(CAMERA_PARAM_SUPPORTED_EXPOSURECOMPENSATIONSTEP, mExposureCompensationStep);
+  rv = GetImpl(Parameters::KEY_EXPOSURE_COMPENSATION_STEP, mExposureCompensationStep);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to initialize exposure compensation step size");
-    mExposureCompensationStep = 0;
+    mExposureCompensationStep = 0.0;
+  }
+  rv = GetImpl(Parameters::KEY_MIN_EXPOSURE_COMPENSATION, mExposureCompensationMinIndex);
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Failed to initialize minimum exposure compensation index");
+    mExposureCompensationMinIndex = 0;
+  }
+  rv = GetImpl(Parameters::KEY_MAX_EXPOSURE_COMPENSATION, mExposureCompensationMaxIndex);
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Failed to initialize maximum exposure compensation index");
+    mExposureCompensationMaxIndex = 0;
   }
 
   rv = GetListAsArray(CAMERA_PARAM_SUPPORTED_ZOOMRATIOS, mZoomRatios);
   if (NS_FAILED(rv)) {
     // zoom is not supported
     mZoomRatios.Clear();
   }
   for (uint32_t i = 1; i < mZoomRatios.Length(); ++i) {
@@ -535,28 +541,35 @@ GonkCameraParameters::GetTranslated(uint
 nsresult
 GonkCameraParameters::SetTranslated(uint32_t aKey, const double& aValue)
 {
   int index;
   int value;
 
   switch (aKey) {
     case CAMERA_PARAM_EXPOSURECOMPENSATION:
-      if (mExposureCompensationStep == 0) {
-        DOM_CAMERA_LOGE("Exposure compensation not supported, can't set %f\n", aValue);
+      if (mExposureCompensationStep == 0.0) {
+        DOM_CAMERA_LOGE("Exposure compensation not supported, can't set EV=%f\n", aValue);
         return NS_ERROR_NOT_AVAILABLE;
       }
 
       /**
        * Convert from real value to a Gonk index, round
        * to the nearest step; index is 1-based.
        */
-      index =
-        (aValue - mExposureCompensationMin + mExposureCompensationStep / 2) /
-        mExposureCompensationStep + 1;
+      {
+        double i = round(aValue / mExposureCompensationStep);
+        if (i < mExposureCompensationMinIndex) {
+          index = mExposureCompensationMinIndex;
+        } else if (i > mExposureCompensationMaxIndex) {
+          index = mExposureCompensationMaxIndex;
+        } else {
+          index = i;
+        }
+      }
       DOM_CAMERA_LOGI("Exposure compensation = %f --> index = %d\n", aValue, index);
       return SetImpl(CAMERA_PARAM_EXPOSURECOMPENSATION, index);
 
     case CAMERA_PARAM_ZOOM:
       {
         /**
          * Convert from a real zoom multipler (e.g. 2.5x) to
          * the index of the nearest supported value.
@@ -638,25 +651,26 @@ GonkCameraParameters::GetTranslated(uint
           val = focusDistance[index];
         } else {
           val = 0.0;
         }
       }
       break;
 
     case CAMERA_PARAM_EXPOSURECOMPENSATION:
+    case CAMERA_PARAM_SUPPORTED_MINEXPOSURECOMPENSATION:
+    case CAMERA_PARAM_SUPPORTED_MAXEXPOSURECOMPENSATION:
+      if (mExposureCompensationStep == 0.0) {
+        DOM_CAMERA_LOGE("Exposure compensation not supported, can't get EV\n");
+        return NS_ERROR_NOT_AVAILABLE;
+      }
       rv = GetImpl(aKey, index);
       if (NS_SUCCEEDED(rv)) {
-        if (!index) {
-          // NaN indicates automatic exposure compensation
-          val = NAN;
-        } else {
-          val = (index - 1) * mExposureCompensationStep + mExposureCompensationMin;
-          DOM_CAMERA_LOGI("index = %d --> compensation = %f\n", index, val);
-        }
+        val = index * mExposureCompensationStep;
+        DOM_CAMERA_LOGI("exposure compensation (aKey=%d): index=%d --> EV=%f\n", aKey, index, val);
       }
       break;
 
     default:
       rv = GetImpl(aKey, val);
       break;
   }
 
--- a/dom/camera/GonkCameraParameters.h
+++ b/dom/camera/GonkCameraParameters.h
@@ -90,18 +90,19 @@ public:
   }
 
 protected:
   PRRWLock* mLock;
   bool mDirty;
   bool mInitialized;
 
   // Required internal properties
-  double mExposureCompensationMin;
   double mExposureCompensationStep;
+  int32_t mExposureCompensationMinIndex;
+  int32_t mExposureCompensationMaxIndex;
   nsTArray<int> mZoomRatios;
   nsTArray<nsString> mIsoModes;
 
   // This subclass of android::CameraParameters just gives
   // all of the AOSP getters and setters the same signature.
   class Parameters : public android::CameraParameters
   {
   public:
--- a/dom/camera/test/test_camera_fake_parameters.html
+++ b/dom/camera/test/test_camera_fake_parameters.html
@@ -205,16 +205,77 @@ var tests = [
       ok(areas[0].bottom == 502, "area[0] bottom = " + areas[0].bottom);
       ok(areas[0].left == -503, "area[0] left = " + areas[0].left);
       ok(areas[0].right == 504, "area[0] right = " + areas[0].right);
       ok(areas[0].weight == 105, "area[0] weight = " + areas[0].weight);
 
       next();
     },
   },
+  {
+    key: "fake-exposure-compensation",
+    prep: function setupFakeExposureCompensation(test) {
+      test.setFakeParameters("exposure-compensation=-1;max-exposure-compensation=6;min-exposure-compensation=-6;exposure-compensation-step=0.5", function () {
+        run();
+      });
+    },
+    test: function testFakeFocusAreas(cam, cap) {
+      ok(cap.exposureCompensationStep == 0.5,
+         "exposureCompensationStep = " + cap.exposureCompensationStep);
+      ok(cap.minExposureCompensation == -3.0,
+         "minExposureCompensation = " + cap.minExposureCompensation);
+      ok(cap.maxExposureCompensation == 3.0,
+         "maxExposureCompensation = " + cap.maxExposureCompensation);
+      ok(cam.exposureCompensation == -0.5,
+         "exposureCompensation = " + cam.exposureCompensation);
+
+      // Check normal values
+      cam.setExposureCompensation(0.0);
+      ok(cam.exposureCompensation == 0.0,
+         "exposureCompensation = " + cam.exposureCompensation);
+      cam.setExposureCompensation(cap.minExposureCompensation);
+      ok(cam.exposureCompensation == cap.minExposureCompensation,
+         "exposureCompensation(min) = " + cam.exposureCompensation);
+      cam.setExposureCompensation(cap.maxExposureCompensation);
+      ok(cam.exposureCompensation == cap.maxExposureCompensation,
+         "exposureCompensation(max) = " + cam.exposureCompensation);
+
+      // Rounding
+      cam.setExposureCompensation(1.24);
+      ok(cam.exposureCompensation == 1.0,
+         "exposureCompensation(1.24) = " + cam.exposureCompensation);
+      cam.setExposureCompensation(1.25);
+      ok(cam.exposureCompensation == 1.5,
+         "exposureCompensation(1.25) = " + cam.exposureCompensation);
+      cam.setExposureCompensation(-1.24);
+      ok(cam.exposureCompensation == -1.0,
+         "exposureCompensation(-1.24) = " + cam.exposureCompensation);
+      cam.setExposureCompensation(-1.25);
+      ok(cam.exposureCompensation == -1.5,
+         "exposureCompensation(-1.25) = " + cam.exposureCompensation);
+
+      // Check out-of-bounds values
+      cam.setExposureCompensation(cap.minExposureCompensation - 1.0);
+      ok(cam.exposureCompensation == cap.minExposureCompensation,
+         "exposureCompensation(min - 1.0) = " + cam.exposureCompensation);
+      cam.setExposureCompensation(cap.maxExposureCompensation + 1.0);
+      ok(cam.exposureCompensation == cap.maxExposureCompensation,
+         "exposureCompensation(max + 1.0) = " + cam.exposureCompensation);
+
+      // Check extreme values
+      cam.setExposureCompensation(-1 * Math.pow(2, 32));
+      ok(cam.exposureCompensation == cap.minExposureCompensation,
+         "exposureCompensation(-2^32) = " + cam.exposureCompensation);
+      cam.setExposureCompensation(Math.pow(2, 32));
+      ok(cam.exposureCompensation == cap.maxExposureCompensation,
+         "exposureCompensation(2^32) = " + cam.exposureCompensation);
+
+      next();
+    },
+  },
 ];
 
 var testGenerator = function() {
   for (var i = 0; i < tests.length; ++i ) {
     yield tests[i];
   }
 }();
 
--- a/dom/nfc/MozNDEFRecord.cpp
+++ b/dom/nfc/MozNDEFRecord.cpp
@@ -94,24 +94,27 @@ MozNDEFRecord::MozNDEFRecord(JSContext* 
                              const Optional<Uint8Array>& aType,
                              const Optional<Uint8Array>& aId,
                              const Optional<Uint8Array>& aPayload)
   : mTnf(aTnf)
 {
   mWindow = aWindow; // For GetParentObject()
 
   if (aType.WasPassed()) {
+    aType.Value().ComputeLengthAndData();
     mType = Uint8Array::Create(aCx, this, aType.Value().Length(), aType.Value().Data());
   }
 
   if (aId.WasPassed()) {
+    aId.Value().ComputeLengthAndData();
     mId = Uint8Array::Create(aCx, this, aId.Value().Length(), aId.Value().Data());
   }
 
   if (aPayload.WasPassed()) {
+    aPayload.Value().ComputeLengthAndData();
     mPayload = Uint8Array::Create(aCx, this, aPayload.Value().Length(), aPayload.Value().Data());
   }
 
   SetIsDOMBinding();
   HoldData();
 }
 
 MozNDEFRecord::~MozNDEFRecord()
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -21,18 +21,18 @@
 #include "nsPoint.h"                    // for nsIntPoint
 #include "nsThreadUtils.h"              // for NS_IsMainThread
 #include "mozilla/gfx/Logging.h"        // for gfx::TreeLog
 #include "UnitTransforms.h"             // for ViewAs
 #include "gfxPrefs.h"                   // for gfxPrefs
 
 #include <algorithm>                    // for std::stable_sort
 
-#define APZC_LOG(...)
-// #define APZC_LOG(...) printf_stderr("APZC: " __VA_ARGS__)
+#define APZCTM_LOG(...)
+// #define APZCTM_LOG(...) printf_stderr("APZCTM: " __VA_ARGS__)
 
 namespace mozilla {
 namespace layers {
 
 float APZCTreeManager::sDPI = 160.0;
 
 // Pref that enables printing of the APZC tree for debugging.
 static bool gPrintApzcTree = false;
@@ -144,17 +144,17 @@ APZCTreeManager::UpdatePanZoomController
                                 aCompositor ? aCompositor->RootLayerTreeId() : 0,
                                 gfx3DMatrix(), nullptr, nullptr,
                                 aIsFirstPaint, aOriginatingLayersId,
                                 paintLogger, &apzcsToDestroy);
     mApzcTreeLog << "[end]\n";
   }
 
   for (size_t i = 0; i < apzcsToDestroy.Length(); i++) {
-    APZC_LOG("Destroying APZC at %p\n", apzcsToDestroy[i].get());
+    APZCTM_LOG("Destroying APZC at %p\n", apzcsToDestroy[i].get());
     apzcsToDestroy[i]->Destroy();
   }
 }
 
 AsyncPanZoomController*
 APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
                                              Layer* aLayer, uint64_t aLayersId,
                                              gfx3DMatrix aTransform,
@@ -222,17 +222,17 @@ APZCTreeManager::UpdatePanZoomController
           // so that it doesn't continue pointing to APZCs that should no longer
           // be in the tree. These pointers will get reset properly as we continue
           // building the tree. Also remove it from the set of APZCs that are going
           // to be destroyed, because it's going to remain active.
           aApzcsToDestroy->RemoveElement(apzc);
           apzc->SetPrevSibling(nullptr);
           apzc->SetLastChild(nullptr);
         }
-        APZC_LOG("Using APZC %p for layer %p with identifiers %lld %lld\n", apzc, aLayer, aLayersId, container->GetFrameMetrics().GetScrollId());
+        APZCTM_LOG("Using APZC %p for layer %p with identifiers %lld %lld\n", apzc, aLayer, aLayersId, container->GetFrameMetrics().GetScrollId());
 
         apzc->NotifyLayersUpdated(metrics,
                                   aIsFirstPaint && (aLayersId == aOriginatingLayersId));
         apzc->SetScrollHandoffParentId(container->GetScrollHandoffParentId());
 
         // Use the composition bounds as the hit test region.
         // Optionally, the GeckoContentController can provide a touch-sensitive
         // region that constrains all frames associated with the controller.
@@ -246,17 +246,17 @@ APZCTreeManager::UpdatePanZoomController
           visible = visible.Intersect(touchSensitiveRegion
                                       * metrics.mDevPixelsPerCSSPixel
                                       * metrics.GetParentResolution());
         }
         gfx3DMatrix transform;
         gfx::To3DMatrix(aLayer->GetTransform(), transform);
 
         apzc->SetLayerHitTestData(visible, aTransform, transform);
-        APZC_LOG("Setting rect(%f %f %f %f) as visible region for APZC %p\n", visible.x, visible.y,
+        APZCTM_LOG("Setting rect(%f %f %f %f) as visible region for APZC %p\n", visible.x, visible.y,
                                                                               visible.width, visible.height,
                                                                               apzc);
 
         mApzcTreeLog << "APZC " << guid
                      << "\tcb=" << visible
                      << "\tsr=" << container->GetFrameMetrics().mScrollableRect
                      << (aLayer->GetVisibleRegion().IsEmpty() ? "\tscrollinfo" : "")
                      << "\t" << container->GetFrameMetrics().GetContentDescription();
@@ -389,33 +389,33 @@ APZCTreeManager::ReceiveInputEvent(const
           // If we have one touch point, this might be the start of a pan.
           // Prepare for possible overscroll handoff.
           BuildOverscrollHandoffChain(mApzcForInputBlock);
         }
         for (size_t i = 1; i < multiTouchInput.mTouches.Length(); i++) {
           nsRefPtr<AsyncPanZoomController> apzc2 = GetTargetAPZC(ScreenPoint(multiTouchInput.mTouches[i].mScreenPoint),
                                                                  &mInOverscrolledApzc);
           mApzcForInputBlock = CommonAncestor(mApzcForInputBlock.get(), apzc2.get());
-          APZC_LOG("Using APZC %p as the common ancestor\n", mApzcForInputBlock.get());
+          APZCTM_LOG("Using APZC %p as the common ancestor\n", mApzcForInputBlock.get());
           // For now, we only ever want to do pinching on the root APZC for a given layers id. So
           // when we find the common ancestor of multiple points, also walk up to the root APZC.
           mApzcForInputBlock = RootAPZCForLayersId(mApzcForInputBlock);
-          APZC_LOG("Using APZC %p as the root APZC for multi-touch\n", mApzcForInputBlock.get());
+          APZCTM_LOG("Using APZC %p as the root APZC for multi-touch\n", mApzcForInputBlock.get());
         }
 
         if (mApzcForInputBlock) {
           // Cache transformToApzc so it can be used for future events in this block.
           GetInputTransforms(mApzcForInputBlock, transformToApzc, transformToGecko);
           mCachedTransformToApzcForInputBlock = transformToApzc;
         } else {
           // Reset the cached apz transform
           mCachedTransformToApzcForInputBlock = gfx3DMatrix();
         }
       } else if (mApzcForInputBlock) {
-        APZC_LOG("Re-using APZC %p as continuation of event block\n", mApzcForInputBlock.get());
+        APZCTM_LOG("Re-using APZC %p as continuation of event block\n", mApzcForInputBlock.get());
       }
       if (mApzcForInputBlock) {
         mApzcForInputBlock->GetGuid(aOutTargetGuid);
         // Use the cached transform to compute the point to send to the APZC.
         // This ensures that the sequence of touch points an APZC sees in an
         // input block are all in the same coordinate space.
         transformToApzc = mCachedTransformToApzcForInputBlock;
         MultiTouchInput inputForApzc(multiTouchInput);
@@ -493,21 +493,21 @@ APZCTreeManager::GetTouchInputBlockAPZC(
     // If we have one touch point, this might be the start of a pan.
     // Prepare for possible overscroll handoff.
     BuildOverscrollHandoffChain(apzc);
   }
   for (size_t i = 1; i < aEvent.touches.Length(); i++) {
     point = ScreenPoint(aEvent.touches[i]->mRefPoint.x, aEvent.touches[i]->mRefPoint.y);
     nsRefPtr<AsyncPanZoomController> apzc2 = GetTargetAPZC(point, aOutInOverscrolledApzc);
     apzc = CommonAncestor(apzc.get(), apzc2.get());
-    APZC_LOG("Using APZC %p as the common ancestor\n", apzc.get());
+    APZCTM_LOG("Using APZC %p as the common ancestor\n", apzc.get());
     // For now, we only ever want to do pinching on the root APZC for a given layers id. So
     // when we find the common ancestor of multiple points, also walk up to the root APZC.
     apzc = RootAPZCForLayersId(apzc);
-    APZC_LOG("Using APZC %p as the root APZC for multi-touch\n", apzc.get());
+    APZCTM_LOG("Using APZC %p as the root APZC for multi-touch\n", apzc.get());
   }
   return apzc.forget();
 }
 
 nsEventStatus
 APZCTreeManager::ProcessTouchEvent(WidgetTouchEvent& aEvent,
                                    ScrollableLayerGuid* aOutTargetGuid)
 {
@@ -1062,44 +1062,44 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPan
   // It is OC.Inverse() * NC.Inverse() * MC.Inverse() at recursion level for L,
   //   and RC.Inverse() * QC.Inverse()                at recursion level for P.
   gfx3DMatrix ancestorUntransform = aApzc->GetAncestorTransform().Inverse();
 
   // Hit testing for this layer takes place in our parent layer coordinates,
   // since the composition bounds (used to initialize the visible rect against
   // which we hit test are in those coordinates).
   gfxPoint hitTestPointForThisLayer = ancestorUntransform.ProjectPoint(aHitTestPoint);
-  APZC_LOG("Untransformed %f %f to transient coordinates %f %f for hit-testing APZC %p\n",
+  APZCTM_LOG("Untransformed %f %f to transient coordinates %f %f for hit-testing APZC %p\n",
            aHitTestPoint.x, aHitTestPoint.y,
            hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, aApzc);
 
   // childUntransform takes points from aApzc's parent APZC's layer coordinates
   // to aApzc's layer coordinates (which are aApzc's children's ParentLayer coordinates).
   // It is OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LA.Inverse() at L
   //   and RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse()                at P.
   gfx3DMatrix childUntransform = ancestorUntransform
                                * aApzc->GetCSSTransform().Inverse()
                                * gfx3DMatrix(aApzc->GetCurrentAsyncTransform()).Inverse();
   gfxPoint hitTestPointForChildLayers = childUntransform.ProjectPoint(aHitTestPoint);
-  APZC_LOG("Untransformed %f %f to layer coordinates %f %f for APZC %p\n",
+  APZCTM_LOG("Untransformed %f %f to layer coordinates %f %f for APZC %p\n",
            aHitTestPoint.x, aHitTestPoint.y,
            hitTestPointForChildLayers.x, hitTestPointForChildLayers.y, aApzc);
 
   AsyncPanZoomController* result = nullptr;
   // This walks the tree in depth-first, reverse order, so that it encounters
   // APZCs front-to-back on the screen.
   for (AsyncPanZoomController* child = aApzc->GetLastChild(); child; child = child->GetPrevSibling()) {
     AsyncPanZoomController* match = GetAPZCAtPoint(child, hitTestPointForChildLayers, aOutInOverscrolledApzc);
     if (match) {
       result = match;
       break;
     }
   }
   if (!result && aApzc->VisibleRegionContains(ViewAs<ParentLayerPixel>(hitTestPointForThisLayer))) {
-    APZC_LOG("Successfully matched untransformed point %f %f to visible region for APZC %p\n",
+    APZCTM_LOG("Successfully matched untransformed point %f %f to visible region for APZC %p\n",
              hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, aApzc);
     result = aApzc;
   }
 
   // If we are overscrolled, and the point matches us or one of our children,
   // the result is inside an overscrolled APZC, inform our caller of this
   // (callers typically ignore events targeted at overscrolled APZCs).
   if (result && aApzc->IsOverscrolled()) {
--- a/hal/Hal.cpp
+++ b/hal/Hal.cpp
@@ -759,16 +759,17 @@ DisableSwitchNotifications(SwitchDevice 
 SwitchState GetCurrentSwitchState(SwitchDevice aDevice)
 {
   AssertMainThread();
   RETURN_PROXY_IF_SANDBOXED(GetCurrentSwitchState(aDevice), SWITCH_STATE_UNKNOWN);
 }
 
 void NotifySwitchStateFromInputDevice(SwitchDevice aDevice, SwitchState aState)
 {
+  AssertMainThread();
   PROXY_IF_SANDBOXED(NotifySwitchStateFromInputDevice(aDevice, aState));
 }
 
 typedef mozilla::ObserverList<SwitchEvent> SwitchObserverList;
 
 static SwitchObserverList *sSwitchObserverLists = nullptr;
 
 static SwitchObserverList&
--- a/hal/sandbox/PHal.ipdl
+++ b/hal/sandbox/PHal.ipdl
@@ -170,17 +170,16 @@ parent:
     sync LockScreenOrientation(ScreenOrientation aOrientation)
       returns (bool allowed);
     UnlockScreenOrientation();
  
     EnableSwitchNotifications(SwitchDevice aDevice);
     DisableSwitchNotifications(SwitchDevice aDevice);
     sync GetCurrentSwitchState(SwitchDevice aDevice)
       returns (SwitchState aState);
-    NotifySwitchStateFromInputDevice(SwitchDevice aDevice, SwitchState aState);
 
     FactoryReset();
 
 child:
     NotifySensorChange(SensorData aSensorData);
 
 parent:
     EnableSensorNotifications(SensorType aSensor);
--- a/hal/sandbox/SandboxHal.cpp
+++ b/hal/sandbox/SandboxHal.cpp
@@ -339,17 +339,19 @@ GetCurrentSwitchState(SwitchDevice aDevi
   SwitchState state;
   Hal()->SendGetCurrentSwitchState(aDevice, &state);
   return state;
 }
 
 void
 NotifySwitchStateFromInputDevice(SwitchDevice aDevice, SwitchState aState)
 {
-  Hal()->SendNotifySwitchStateFromInputDevice(aDevice, aState);
+  unused << aDevice;
+  unused << aState;
+  NS_RUNTIMEABORT("Only the main process may notify switch state change.");
 }
 
 bool
 EnableAlarm()
 {
   NS_RUNTIMEABORT("Alarms can't be programmed from sandboxed contexts.  Yet.");
   return false;
 }
@@ -857,24 +859,16 @@ public:
   virtual bool
   RecvGetCurrentSwitchState(const SwitchDevice& aDevice, hal::SwitchState *aState) MOZ_OVERRIDE
   {
     // Content has no reason to listen to switch events currently.
     *aState = hal::GetCurrentSwitchState(aDevice);
     return true;
   }
 
-  virtual bool
-  RecvNotifySwitchStateFromInputDevice(const SwitchDevice& aDevice,
-                                       const SwitchState& aState) MOZ_OVERRIDE
-  {
-    hal::NotifySwitchStateFromInputDevice(aDevice, aState);
-    return true;
-  }
-
   void Notify(const int64_t& aClockDeltaMS)
   {
     unused << SendNotifySystemClockChange(aClockDeltaMS);
   }
 
   void Notify(const SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo)
   {
     unused << SendNotifySystemTimezoneChange(aSystemTimezoneChangeInfo);
--- a/media/libcubeb/include/cubeb.h
+++ b/media/libcubeb/include/cubeb.h
@@ -104,17 +104,17 @@ typedef enum {
 typedef enum {
     CUBEB_STREAM_TYPE_VOICE_CALL = 0,
     CUBEB_STREAM_TYPE_SYSTEM = 1,
     CUBEB_STREAM_TYPE_RING = 2,
     CUBEB_STREAM_TYPE_MUSIC = 3,
     CUBEB_STREAM_TYPE_ALARM = 4,
     CUBEB_STREAM_TYPE_NOTIFICATION = 5,
     CUBEB_STREAM_TYPE_BLUETOOTH_SCO = 6,
-    CUBEB_STREAM_TYPE_ENFORCED_AUDIBLE = 7,
+    CUBEB_STREAM_TYPE_SYSTEM_ENFORCED = 7,
     CUBEB_STREAM_TYPE_DTMF = 8,
     CUBEB_STREAM_TYPE_TTS = 9,
     CUBEB_STREAM_TYPE_FM = 10,
 
     CUBEB_STREAM_TYPE_MAX
 } cubeb_stream_type;
 #endif
 
--- a/media/libcubeb/src/android/sles_definitions.h
+++ b/media/libcubeb/src/android/sles_definitions.h
@@ -58,10 +58,14 @@
 /*      same as android.media.AudioManager.STREAM_RING */
 #define SL_ANDROID_STREAM_RING         ((SLint32) 0x00000002)
 /*      same as android.media.AudioManager.STREAM_MUSIC */
 #define SL_ANDROID_STREAM_MEDIA        ((SLint32) 0x00000003)
 /*      same as android.media.AudioManager.STREAM_ALARM */
 #define SL_ANDROID_STREAM_ALARM        ((SLint32) 0x00000004)
 /*      same as android.media.AudioManager.STREAM_NOTIFICATION */
 #define SL_ANDROID_STREAM_NOTIFICATION ((SLint32) 0x00000005)
+/*      same as android.media.AudioManager.STREAM_BLUETOOTH_SCO */
+#define SL_ANDROID_STREAM_BLUETOOTH_SCO ((SLint32) 0x00000006)
+/*      same as android.media.AudioManager.STREAM_SYSTEM_ENFORCED */
+#define SL_ANDROID_STREAM_SYSTEM_ENFORCED ((SLint32) 0x00000007)
 
 #endif /* OPENSL_ES_ANDROIDCONFIGURATION_H_ */
--- a/media/libcubeb/src/cubeb_opensl.c
+++ b/media/libcubeb/src/cubeb_opensl.c
@@ -112,17 +112,18 @@ convert_stream_type_to_sl_stream(cubeb_s
     case CUBEB_STREAM_TYPE_NOTIFICATION:
       return SL_ANDROID_STREAM_NOTIFICATION;
     case CUBEB_STREAM_TYPE_ALARM:
       return SL_ANDROID_STREAM_ALARM;
     case CUBEB_STREAM_TYPE_VOICE_CALL:
       return SL_ANDROID_STREAM_VOICE;
     case CUBEB_STREAM_TYPE_RING:
       return SL_ANDROID_STREAM_RING;
-    case CUBEB_STREAM_TYPE_ENFORCED_AUDIBLE:
+    case CUBEB_STREAM_TYPE_SYSTEM_ENFORCED:
+      return SL_ANDROID_STREAM_SYSTEM_ENFORCED;
     default:
       return 0xFFFFFFFF;
   }
 }
 #endif
 
 static void opensl_destroy(cubeb * ctx);