Merge m-c to inbound, a=merge
authorWes Kocher <wkocher@mozilla.com>
Thu, 24 Sep 2015 17:14:17 -0700
changeset 264303 0ab67cace54fdce557e2156106d30b1e4ac94883
parent 264270 e9bb88c728f962bfe4c8feaed0663aa4615c7ae5 (current diff)
parent 264302 737517ce8115b2b5ecea745ff52918a7192dd092 (diff)
child 264304 2b5a7e0e2082f72e9bab6f879c5a74ff7d590450
push id65590
push userkwierso@gmail.com
push dateFri, 25 Sep 2015 00:14:23 +0000
treeherdermozilla-inbound@0ab67cace54f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone44.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 m-c to inbound, a=merge
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -15,16 +15,17 @@ const Cr = Components.results;
 
 // The load order is important here SettingsRequestManager _must_ be loaded
 // prior to using SettingsListener otherwise there is a race in acquiring the
 // lock and fulfilling it. If we ever move SettingsListener or this file down in
 // the load order of shell.html things will likely break.
 Cu.import('resource://gre/modules/SettingsRequestManager.jsm');
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.import('resource://gre/modules/Services.jsm');
+Cu.import('resource://gre/modules/AppConstants.jsm');
 
 #ifdef MOZ_WIDGET_GONK
 XPCOMUtils.defineLazyGetter(this, "libcutils", function () {
   Cu.import("resource://gre/modules/systemlibs.js");
   return libcutils;
 });
 #endif
 
@@ -322,17 +323,18 @@ setUpdateTrackingId();
           window.navigator.mozSettings.createLock().set(setting);
         }
       } catch(e) {
         console.log('Unable to read pref ' + prefName + ': ' + e);
       }
     });
   }
 
-  syncCharPref('app.update.url');
+  syncCharPref(AppConstants.MOZ_B2GDROID ? 'app.update.url.android'
+                                         : 'app.update.url');
   syncCharPref('app.update.channel');
 })();
 
 // ================ Debug ================
 (function Composer2DSettingToPref() {
   //layers.composer.enabled can be enabled in three ways
   //In order of precedence they are:
   //
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4bb17b24620818cbda0ba0c0d69e0ce3f914e1b7"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f1cb3089ee2a77dd779408ca86dbb5e4ed5af0b3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="828317e64d28138f24d578ab340c2a0ff8552df0"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
--- 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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4bb17b24620818cbda0ba0c0d69e0ce3f914e1b7"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f1cb3089ee2a77dd779408ca86dbb5e4ed5af0b3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="828317e64d28138f24d578ab340c2a0ff8552df0"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
--- 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="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <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="4bb17b24620818cbda0ba0c0d69e0ce3f914e1b7"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="f1cb3089ee2a77dd779408ca86dbb5e4ed5af0b3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="12ff7481566587aa4198cf1287598acb3a999973"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="828317e64d28138f24d578ab340c2a0ff8552df0"/>
   <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="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <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="4bb17b24620818cbda0ba0c0d69e0ce3f914e1b7"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f1cb3089ee2a77dd779408ca86dbb5e4ed5af0b3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="828317e64d28138f24d578ab340c2a0ff8552df0"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <!-- 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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4bb17b24620818cbda0ba0c0d69e0ce3f914e1b7"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f1cb3089ee2a77dd779408ca86dbb5e4ed5af0b3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="828317e64d28138f24d578ab340c2a0ff8552df0"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
--- 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="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4bb17b24620818cbda0ba0c0d69e0ce3f914e1b7"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f1cb3089ee2a77dd779408ca86dbb5e4ed5af0b3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="828317e64d28138f24d578ab340c2a0ff8552df0"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
--- 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="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <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="4bb17b24620818cbda0ba0c0d69e0ce3f914e1b7"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="f1cb3089ee2a77dd779408ca86dbb5e4ed5af0b3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="12ff7481566587aa4198cf1287598acb3a999973"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="828317e64d28138f24d578ab340c2a0ff8552df0"/>
   <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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4bb17b24620818cbda0ba0c0d69e0ce3f914e1b7"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f1cb3089ee2a77dd779408ca86dbb5e4ed5af0b3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="828317e64d28138f24d578ab340c2a0ff8552df0"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "4bb17b24620818cbda0ba0c0d69e0ce3f914e1b7", 
+        "git_revision": "f1cb3089ee2a77dd779408ca86dbb5e4ed5af0b3", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "0bdd0b54cb40d7e928e9e6de720c0506dc7e52db", 
+    "revision": "754c41de25dcb48c7b1f18f13900d0212ed7fb07", 
     "repo_path": "integration/gaia-central"
 }
new file mode 100644
--- /dev/null
+++ b/b2g/config/nexus-4-kk/sources.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0" ?><manifest>
+  <!--original fetch url was https://android.googlesource.com/-->
+  <remote fetch="https://git.mozilla.org/external/aosp" name="aosp"/>
+  <!--original fetch url was git://github.com/mozilla-b2g/-->
+  <remote fetch="https://git.mozilla.org/b2g" name="b2g"/>
+  <!--original fetch url was git://github.com/mozilla/-->
+  <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
+  <!--original fetch url was git://github.com/apitrace/-->
+  <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
+  <!--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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
+    <copyfile dest="Makefile" src="core/root.mk"/>
+  </project>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f1cb3089ee2a77dd779408ca86dbb5e4ed5af0b3"/>
+  <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
+  <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="828317e64d28138f24d578ab340c2a0ff8552df0"/>
+  <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
+  <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
+  <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
+  <!-- Stock Android things -->
+  <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
+  <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
+  <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/>
+  <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="ac6eb97a37035c09fb5ede0852f0881e9aadf9ad"/>
+  <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="737f591c5f95477148d26602c7be56cbea0cdeb9"/>
+  <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="51da9b1981be481b92a59a826d4d78dc73d0989a"/>
+  <project name="device/common" path="device/common" revision="798a3664597e6041985feab9aef42e98d458bc3d"/>
+  <project name="device/sample" path="device/sample" revision="9aebb4ac5b6c1b2552599651a0e51b01e720eea6"/>
+  <project name="platform/abi/cpp" path="abi/cpp" revision="77d97588f8ca4ea280d4e6b6225fc72853078778"/>
+  <project name="platform/bionic" path="bionic" revision="ab513342d514efb2b6b5eddaa11fdb332ee6b857"/>
+  <project name="platform/bootable/recovery" path="bootable/recovery" revision="4fd89afeff2706cc226724dd039e086b2b5a86d4"/>
+  <project name="platform/external/aac" path="external/aac" revision="585942dfe8ce0b450af2409720cc0bd9a595ceae"/>
+  <project name="platform/external/bison" path="external/bison" revision="00953c546c8e02ba618355544009f373b465471e"/>
+  <project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="067eac306279fd677fcf7408cc960741dd07d01a"/>
+  <project name="platform/external/bsdiff" path="external/bsdiff" revision="79e9d7bac946b2d89c468766699c8ea35dff33eb"/>
+  <project name="platform/external/bzip2" path="external/bzip2" revision="145950eb384ccc6261ee649d802d58795fc3ff29"/>
+  <project name="platform/external/checkpolicy" path="external/checkpolicy" revision="25648e00091208cad15505ef7f10183d22d4e2ea"/>
+  <project name="platform/external/dhcpcd" path="external/dhcpcd" revision="d3307f4cf6c3dc99ff3993881874c7498502e346"/>
+  <project name="platform/external/dnsmasq" path="external/dnsmasq" revision="8501b339deaad1354697fb4adada267b4600b142"/>
+  <project name="platform/external/dropbear" path="external/dropbear" revision="c4af303ab2f8a989feadf7ad211e74e77bd14edf"/>
+  <project name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="42e25ab63418386ccf39ac781ba52a847fa88602"/>
+  <project name="platform/external/elfutils" path="external/elfutils" revision="801c347fd1ef0685e4ec040aba5cef331ec14350"/>
+  <project name="platform/external/expat" path="external/expat" revision="4a65b6cb6d2aae6bf952b0e6b44881f84fdf5128"/>
+  <project name="platform/external/fdlibm" path="external/fdlibm" revision="e24fa134127a9f2a298ad04c5d092ce2c6b43791"/>
+  <project name="platform/external/flac" path="external/flac" revision="d835398098fcbcb904e99ec6bdb9e4a78ef82a7d"/>
+  <project name="platform/external/freetype" path="external/freetype" revision="d5a7ed510903655138246192e031960b09418209"/>
+  <project name="platform/external/gcc-demangle" path="external/gcc-demangle" revision="41a7d241271ff1738bcb90ef98fc657938899f17"/>
+  <project name="platform/external/genext2fs" path="external/genext2fs" revision="a14feae5ebbcda801c26623ec6b04884e2a9ed5b"/>
+  <project name="platform/external/giflib" path="external/giflib" revision="50ca09a5b13245c7357733a9072d67fd3d8d4709"/>
+  <project name="platform/external/gtest" path="external/gtest" revision="0e87f7087bead3fbba86ad24fb888b23c25b35d3"/>
+  <project name="platform/external/harfbuzz" path="external/harfbuzz" revision="77bfb851261572216aeba5a5e1bb1d910d40ecb9"/>
+  <project name="platform/external/harfbuzz_ng" path="external/harfbuzz_ng" revision="6e3a3edf0a9ae09a7b92637c2a7131df0bde4760"/>
+  <project name="platform/external/iproute2" path="external/iproute2" revision="b438b9c63d6f79cb08391f0b0f12b8457ea99395"/>
+  <project name="platform/external/ipsec-tools" path="external/ipsec-tools" revision="c493b85a54d27cbcb1dcb91bb86545254cf28684"/>
+  <project name="platform/external/iptables" path="external/iptables" revision="fe8cf0795af508d6bd413d0ab729ed6afabd237e"/>
+  <project name="platform/external/jack" path="external/jack" revision="f4e712ba487ef9c26360bce0ae2a7bf62cb36e0a"/>
+  <project name="platform/external/jhead" path="external/jhead" revision="369044ba5a78dd3378a804402d43819551350bfc"/>
+  <project name="platform/external/jpeg" path="external/jpeg" revision="b0d8c64f08ef085025b60d9d398e66089cafe2c0"/>
+  <project name="platform/external/junit" path="external/junit" revision="4304fac3d9e09955b1d73adfe3dff49a8d14b38a"/>
+  <project name="platform/external/libgsm" path="external/libgsm" revision="ffb6eeb53ef4ec427e24862c30317179fb303006"/>
+  <project name="platform/external/liblzf" path="external/liblzf" revision="32666d6cf523e154c47a2378d5344f574f537f31"/>
+  <project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="06209143852be5967c67eb7675d80ea6250c6487"/>
+  <project name="platform/external/libnl-headers" path="external/libnl-headers" revision="35499a49e8475844a1ea4f7d17cef7c6ebb85051"/>
+  <project name="platform/external/libogg" path="external/libogg" revision="b33f5501cc0ef62a776f1223ede90beacb54ffa3"/>
+  <project name="platform/external/libpcap" path="external/libpcap" revision="b8abe0f4ea706357680930f86fdd6cd26bf30b31"/>
+  <project name="platform/external/libpng" path="external/libpng" revision="e79b02c09f131d26a4b95d025fe85f3e0bd87a55"/>
+  <project name="platform/external/libselinux" path="external/libselinux" revision="f2a93748f1974a76f1676f66049b3a29f1b4e532"/>
+  <project name="platform/external/libsepol" path="external/libsepol" revision="cf9b75ee1949969c6620fcbec854e67a305dbbc7"/>
+  <project name="platform/external/libvpx" path="external/libvpx" revision="11e4fb71a745e7d0f76099f8861d7e6083c104fa"/>
+  <project name="platform/external/mdnsresponder" path="external/mdnsresponder" remote="caf" revision="dd17df3f6775c4366a5c1d21865370d60a3b1295"/>
+  <project name="platform/external/mksh" path="external/mksh" revision="221fb0e62a39d4cedd6469a048cadb28fbf01a96"/>
+  <project name="platform/external/netcat" path="external/netcat" revision="0c2bf20f00ca9d74080a75eda76d0a5550702eaa"/>
+  <project name="platform/external/openssl" path="external/openssl" revision="aa09f63881e72abb398d301c8c19c56583790c84"/>
+  <project name="platform/external/protobuf" path="external/protobuf" revision="fa764bcb74c08acb4143facd9849722570c2f72b"/>
+  <project name="platform/external/safe-iop" path="external/safe-iop" revision="f9e8d80a28c31202759760ead2444d2170830b3c"/>
+  <project name="platform/external/scrypt" path="external/scrypt" revision="98e45237eb006217a8d011da70090932a342707e"/>
+  <project name="platform/external/sepolicy" path="external/sepolicy" revision="5801984a666503748a7df6ad6c88b559e871b400"/>
+  <project name="platform/external/sfntly" path="external/sfntly" revision="2386cc392b9c6bf0ab17b23e853a1aa4b1f3db9a"/>
+  <project name="platform/external/skia" path="external/skia" revision="62efe29dfe1e5d425bcfd2d187ea8950b972762a"/>
+  <project name="platform/external/sonivox" path="external/sonivox" revision="ad7c4fc233e6725e508a7f798c443b2985819c64"/>
+  <project name="platform/external/speex" path="external/speex" revision="ab4d3d4aebf76d88c664e4da19c9afcf01f59da1"/>
+  <project name="platform/external/sqlite" path="external/sqlite" revision="5c8e8d23e689b53ce2adb5865556900b6402ad46"/>
+  <project name="platform/external/stlport" path="external/stlport" revision="b0ff03ade03fa080ca8a1932cc7e328661d33927"/>
+  <project name="platform/external/strace" path="external/strace" revision="df60312a98c0cdb419d130a454bd5f3190ee6a16"/>
+  <project name="platform/external/svox" path="external/svox" revision="1cc8a28a4089b0a2041c4077e917e5964dd10e4d"/>
+  <project name="platform/external/tagsoup" path="external/tagsoup" revision="ab78ce1be9f67f787282796f8accc7d50a2fb051"/>
+  <project name="platform/external/tcpdump" path="external/tcpdump" revision="c76d00f367d39014256d478aa917f57f6424d455"/>
+  <project name="platform/external/tinyalsa" path="external/tinyalsa" revision="4b3f554e49d94a41276dddcc1a11fa0442c2044b"/>
+  <project name="platform/external/tinycompress" path="external/tinycompress" revision="4ef0577bf643bc5ae8168015d2a0aa437d165564"/>
+  <project name="platform/external/tinyxml" path="external/tinyxml" revision="2a1ec6642c9f7672d9681ebb3f3a313fd07076ce"/>
+  <project name="platform/external/tinyxml2" path="external/tinyxml2" revision="e3247e3d0b61e8f7a8542ee5d0d3bb3c6fd225fe"/>
+  <project name="platform/external/tremolo" path="external/tremolo" revision="0d21d46a2ff991df430b76be5f6980e4cbb288d4"/>
+  <project name="platform/external/webp" path="external/webp" revision="69b867b7841425c3c8a195cf995d0a1ce910a564"/>
+  <project name="platform/external/webrtc" path="external/webrtc" revision="d329bff545502138fc328853bd8ee81cbb65f9db"/>
+  <project name="platform/external/yaffs2" path="external/yaffs2" revision="e748574e9fa44cfd85df28b75d56f7f2f1cb4293"/>
+  <project name="platform/external/zlib" path="external/zlib" revision="72f197d0cc4009f97d3b0ae2d2f3eb2088468d45"/>
+  <project name="platform/frameworks/base" path="frameworks/base" revision="a155d358adbd5e06152f4c5329b12955ba5372b1"/>
+  <project name="platform/frameworks/native" path="frameworks/native" revision="2176649bcda07ff82ba6e83f3b5ee8b80f2c5cb1"/>
+  <project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="7a2d17bd2190556c9c804721ad7b19d45948bb1f"/>
+  <project name="platform/frameworks/wilhelm" path="frameworks/wilhelm" revision="eb6077f10ae6255a72337124188f0e08dcd10e3e"/>
+  <project name="platform/hardware/libhardware" path="hardware/libhardware" revision="3b80c725cea54132df05d208930d91e00d19f999"/>
+  <project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="01f436c51dc68aec7cc1c85fda6e6792b2a95066"/>
+  <project name="platform/libcore" path="libcore" revision="9877ade9617bb0db6e59aa2a54719a9bc92600f3"/>
+  <project name="platform/libnativehelper" path="libnativehelper" revision="46c96ace65eb1ccab05bf15b9bf8e53e443039af"/>
+  <project name="platform/ndk" path="ndk" revision="cb5519af32ae7b4a9c334913a612462ecd04c5d0"/>
+  <project name="platform_prebuilts_misc" path="prebuilts/misc" remote="b2g" revision="23404f05422c6bf3c39573325a4f4909167671b4"/>
+  <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="6aa61f8557a22039a30b42b7f283996381fd625d"/>
+  <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="6a1bb59af65b6485b1090522f66fac95c3f9e22c"/>
+  <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="b562b01c93de9578d5db537b6a602a38e1aaa0ce"/>
+  <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="387f03e815f57d536dd922706db1622bddba8d81"/>
+  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="fd241573c00112ca6e456b8021fb68df0349f6dd"/>
+  <project name="platform/system/extras" path="system/extras" revision="5356165f67f4a81c2ef28671c13697f1657590df"/>
+  <project name="platform/system/media" path="system/media" revision="be0e2fe59a8043fa5200f75697df9220a99abe9d"/>
+  <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
+  <project name="platform/system/netd" path="system/netd" revision="36704b0da24debcab8090156568ac236315036bb"/>
+  <project name="platform/system/security" path="system/security" revision="583374f69f531ba68fc3dcbff1f74893d2a96406"/>
+  <project name="platform/system/vold" path="system/vold" revision="d4455b8cf361f8353e8aebac15ffd64b4aedd2b9"/>
+  <project name="platform/external/icu4c" path="external/icu4c" remote="aosp" revision="b4c6379528887dc25ca9991a535a8d92a61ad6b6"/>
+  <project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="2da3a2d5100f8afa1229bb50aa2a29ea0aaf8417"/>
+  <project name="platform_system_core" path="system/core" remote="b2g" revision="8586f55fe4b015911b48e731b69c592ad82a0807"/>
+  <default remote="caf" revision="refs/tags/android-4.4.2_r1" sync-j="4"/>
+  <!-- Nexus 4 specific things -->
+  <project name="device-mako" path="device/lge/mako" remote="b2g" revision="aea6908cd694b4ef9e7ad64a930d52eab6ab1e17"/>
+  <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="72ffdf71c68a96309212eb13d63560d66db14c9e"/>
+  <project name="device_lge_mako-kernel" path="device/lge/mako-kernel" remote="b2g" revision="a49f2c34bc50a07b02f010a53d80477542209a81"/>
+  <project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="f37bd545063039e30a92f2550ae78c0e6e4e2d08"/>
+  <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="694cecf256122d0cb3b6a1a4efb4b5c7401db223"/>
+  <project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="5eb5fb95dbc095c554686bdded852c46f1299e37"/>
+  <project name="platform/hardware/qcom/audio" path="hardware/qcom/audio" revision="e168f3dc6c821239497e7358a968b99da6d9df5b"/>
+  <project name="platform/hardware/qcom/bt" path="hardware/qcom/bt" revision="9c274df08174e762523ca0c84249c875c76f0cc2"/>
+  <project name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="b951a32c1afaec2547b082c2c1c56d79f6797426"/>
+  <project name="platform/hardware/qcom/display" path="hardware/qcom/display" revision="2a1a2869b7d8e512c0fe4d74e03cb00ea4722629"/>
+  <project name="platform/hardware/qcom/keymaster" path="hardware/qcom/keymaster" revision="584f1e418478f412b0d47bbaab35e34fca38ade7"/>
+  <project name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="eef7d1a3d4b1584e62424ce06fee4c70f2edf9bb"/>
+  <project name="platform/hardware/qcom/msm8960" path="hardware/qcom/msm8960" revision="8f23611b843eacc3177b31987f3708b4c3b33621"/>
+  <project name="platform/hardware/qcom/power" path="hardware/qcom/power" revision="f8c9e51bd67c04ce4c19bf0515204118ea6b322a"/>
+  <project name="platform/hardware/qcom/sensors" path="hardware/qcom/sensors" revision="ef6ad16db4e9f796da493edfba600b9073b72eeb"/>
+  <project name="platform/hardware/qcom/wlan" path="hardware/qcom/wlan" revision="40d2275d17714cd524503b7080ff7bfcde134752"/>
+  <project name="platform/hardware/ril" path="hardware/ril" revision="321468d7cf1fa5c56422243d857a73d4f23f7574"/>
+  <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="5f4b68c799927b6e078f987b12722c3a6ccd4a45"/>
+</manifest>
--- 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="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <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="4bb17b24620818cbda0ba0c0d69e0ce3f914e1b7"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f1cb3089ee2a77dd779408ca86dbb5e4ed5af0b3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="828317e64d28138f24d578ab340c2a0ff8552df0"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <!-- 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="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4bb17b24620818cbda0ba0c0d69e0ce3f914e1b7"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f1cb3089ee2a77dd779408ca86dbb5e4ed5af0b3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="828317e64d28138f24d578ab340c2a0ff8552df0"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -594,26 +594,23 @@ toolbar[mode="text"] #bookmarks-menu-but
 }
 toolbar[mode="text"] #bookmarks-menu-button > .toolbarbutton-menubutton-button > .toolbarbutton-text {
   display: none;
 }
 
 menupopup[emptyplacesresult="true"] > .hide-if-empty-places-result {
   display: none;
 }
-
 menuitem.spell-suggestion {
   font-weight: bold;
 }
-
 /* apply Fitts' law to the notification bar's close button */
-window[sizemode="maximized"] #content .notification-inner {
-  border-right: 0px !important;
+window:not([sizemode="normal"]) .notification-inner {
+  -moz-border-end-width: 0 !important;
 }
-
 /* Hide extension toolbars that neglected to set the proper class */
 window[chromehidden~="location"][chromehidden~="toolbar"] toolbar:not(.chromeclass-menubar),
 window[chromehidden~="toolbar"] toolbar:not(#nav-bar):not(#TabsToolbar):not(#print-preview-toolbar):not(.chromeclass-menubar) {
   display: none;
 }
 
 #navigator-toolbox ,
 #mainPopupSet {
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2368,28 +2368,32 @@ function BrowserViewSourceOfDocument(aAr
     args = { browser, outerWindowID, URL };
   } else {
     args = aArgsOrDocument;
   }
 
   let viewInternal = () => {
     let inTab = Services.prefs.getBoolPref("view_source.tab");
     if (inTab) {
-      let viewSourceURL = `view-source:${args.URL}`;
       let tabBrowser = gBrowser;
       // In the case of sidebars and chat windows, gBrowser is defined but null,
       // because no #content element exists.  For these cases, we need to find
       // the most recent browser window.
       // In the case of popups, we need to find a non-popup browser window.
       if (!tabBrowser || !window.toolbar.visible) {
         // This returns only non-popup browser windows by default.
         let browserWindow = RecentWindow.getMostRecentBrowserWindow();
         tabBrowser = browserWindow.gBrowser;
       }
-      let tab = tabBrowser.loadOneTab(viewSourceURL, {
+      // `viewSourceInBrowser` will load the source content from the page
+      // descriptor for the tab (when possible) or fallback to the network if
+      // that fails.  Either way, the view source module will manage the tab's
+      // location, so use "about:blank" here to avoid unnecessary redundant
+      // requests.
+      let tab = tabBrowser.loadOneTab("about:blank", {
         relatedToCurrent: true,
         inBackground: false
       });
       args.viewSourceBrowser = tabBrowser.getBrowserForTab(tab);
       top.gViewSourceUtils.viewSourceInBrowser(args);
     } else {
       top.gViewSourceUtils.viewSource(args);
     }
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -384,23 +384,30 @@ file, You can obtain one at http://mozil
               addToUrlbarHistory(url);
             } catch (ex) {
               // Things may go wrong when adding url to session history,
               // but don't let that interfere with the loading of the url.
               Cu.reportError(ex);
             }
 
             let loadCurrent = () => {
-              openUILinkIn(url, "current", {
-                allowThirdPartyFixup: true,
-                disallowInheritPrincipal: !mayInheritPrincipal,
-                allowPinnedTabHostChange: true,
-                postData: postData,
-                allowPopups: url.startsWith("javascript:"),
-              });
+              try {
+                openUILinkIn(url, "current", {
+                  allowThirdPartyFixup: true,
+                  disallowInheritPrincipal: !mayInheritPrincipal,
+                  allowPinnedTabHostChange: true,
+                  postData: postData,
+                  allowPopups: url.startsWith("javascript:"),
+                });
+              } catch (ex) {
+                // This load can throw an exception in certain cases, which means
+                // we'll want to replace the URL with the loaded URL:
+                this.handleRevert();
+              }
+
               // Ensure the start of the URL is visible for UX reasons:
               this.selectionStart = this.selectionEnd = 0;
             };
 
             // Focus the content area before triggering loads, since if the load
             // occurs in a new tab, we want focus to be restored to the content
             // area when the current tab is re-selected.
             gBrowser.selectedBrowser.focus();
--- a/browser/themes/shared/devedition.inc.css
+++ b/browser/themes/shared/devedition.inc.css
@@ -263,16 +263,17 @@ window:not([chromehidden~="toolbar"]) #u
 .tab-background {
   visibility: hidden;
 }
 
 /* Tab separators */
 .tabbrowser-tab::after,
 .tabbrowser-tab::before {
   background: currentColor;
+  opacity: 0.2 !important;
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-down,
 .tabbrowser-arrowscrollbox > .scrollbutton-up {
   background-color: var(--tab-background-color);
   border-color: transparent;
 }
 
--- a/browser/themes/shared/tabs.inc.css
+++ b/browser/themes/shared/tabs.inc.css
@@ -431,37 +431,31 @@
 .tabbrowser-tab::after,
 .tabbrowser-tab::before {
   width: 1px;
   -moz-margin-start: -1px;
   background-image: linear-gradient(transparent 5px,
                                     currentColor 5px,
                                     currentColor calc(100% - 4px),
                                     transparent calc(100% - 4px));
-  opacity: 0;
+  opacity: 0.2;
   content: "";
   display: -moz-box;
+  visibility: hidden;
 }
 
-.tabbrowser-tab:hover::before,
-.tabbrowser-tab[afterhovered]::before,
-.tabbrowser-tab[last-visible-tab]:hover::after {
-  transition: opacity 100ms ease;
+#TabsToolbar[brighttext] > #tabbrowser-tabs > .tabbrowser-tab::before,
+#TabsToolbar[brighttext] > #tabbrowser-tabs > .tabbrowser-tab::after {
+  opacity: 0.4;
 }
 
 /* Also show separators beside the selected tab when dragging it. */
 #tabbrowser-tabs[movingtab] > .tabbrowser-tab[beforeselected]:not([last-visible-tab])::after,
 .tabbrowser-tab:not([visuallyselected]):not([afterselected-visible]):not([afterhovered]):not([first-visible-tab]):not(:hover)::before,
 #tabbrowser-tabs:not([overflow]) > .tabbrowser-tab[last-visible-tab]:not([visuallyselected]):not([beforehovered]):not(:hover)::after {
-  opacity: 0.2;
-}
-
-#TabsToolbar[brighttext] > #tabbrowser-tabs[movingtab] > .tabbrowser-tab[beforeselected]:not([last-visible-tab])::after,
-#TabsToolbar[brighttext] > #tabbrowser-tabs > .tabbrowser-tab:not([visuallyselected]):not([afterselected-visible]):not([afterhovered]):not([first-visible-tab]):not(:hover)::before,
-#TabsToolbar[brighttext] > #tabbrowser-tabs:not([overflow]) > .tabbrowser-tab[last-visible-tab]:not([visuallyselected]):not([beforehovered]):not(:hover)::after {
-  opacity: 0.4;
+  visibility: visible;
 }
 
 /* New tab button */
 
 .tabs-newtab-button {
   width: calc(36px + @tabCurveWidth@);
 }
--- a/docshell/base/nsAboutRedirector.cpp
+++ b/docshell/base/nsAboutRedirector.cpp
@@ -99,17 +99,18 @@ static RedirEntry kRedirMap[] = {
     nsIAboutModule::URI_MUST_LOAD_IN_CHILD |
     nsIAboutModule::ALLOW_SCRIPT
   },
   // about:srcdoc is unresolvable by specification.  It is included here
   // because the security manager would disallow srcdoc iframes otherwise.
   {
     "srcdoc", "about:blank",
     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
-      nsIAboutModule::HIDE_FROM_ABOUTABOUT
+      nsIAboutModule::HIDE_FROM_ABOUTABOUT |
+      nsIAboutModule::URI_CAN_LOAD_IN_CHILD
   },
   {
     "support", "chrome://global/content/aboutSupport.xhtml",
     nsIAboutModule::ALLOW_SCRIPT
   },
   {
     "telemetry", "chrome://global/content/aboutTelemetry.xhtml",
     nsIAboutModule::ALLOW_SCRIPT
--- a/dom/apps/AndroidUtils.jsm
+++ b/dom/apps/AndroidUtils.jsm
@@ -52,17 +52,18 @@ this.AndroidUtils = {
     return [app.android_packagename, app.android_classname];
   },
 
   buildAndroidAppData: function(aApp) {
     // Use the package and class name to get a unique origin.
     // We put the version with the normal case as part of the manifest url.
     let [origin, manifestURL] =
       this.getOriginAndManifestURL(aApp.packagename);
-    // TODO: Bug 1204557 to improve the icons support.
+    // We choose 96 as an arbitrary size since we can only get one icon
+    // from Android.
     let manifest = {
       name: aApp.name,
       icons: { "96": aApp.icon }
     }
     debug("Origin is " + origin);
     let appData = {
       app: {
         installOrigin: origin,
--- a/mfbt/tests/TestTuple.cpp
+++ b/mfbt/tests/TestTuple.cpp
@@ -22,16 +22,22 @@ using mozilla::MakeUnique;
 using mozilla::Move;
 using mozilla::Pair;
 using mozilla::Tie;
 using mozilla::Tuple;
 using mozilla::UniquePtr;
 using mozilla::unused;
 using std::pair;
 
+#if (_MSC_VER == 1800)
+// Optimizations in VS2013 on Windows 10 cause an internal compiler error
+// with this file.
+#pragma optimize("", off)
+#endif
+
 #define CHECK(c) \
   do { \
     bool cond = !!(c); \
     MOZ_RELEASE_ASSERT(cond, "Failed assertion: " #c); \
   } while (false)
 
 // The second argument is the expected type. It's variadic to allow the
 // type to contain commas.
--- a/mobile/android/b2gdroid/app/Makefile.in
+++ b/mobile/android/b2gdroid/app/Makefile.in
@@ -3,29 +3,38 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 ANDROID_MANIFEST_FILE := src/main/AndroidManifest.xml
 
 JAVAFILES := \
   src/main/java/org/mozilla/b2gdroid/Apps.java \
   src/main/java/org/mozilla/b2gdroid/Launcher.java \
   src/main/java/org/mozilla/b2gdroid/ScreenStateObserver.java \
+  src/main/java/org/mozilla/b2gdroid/SettingsMapper.java \
   $(NULL)
 
 # The GeckoView consuming APK depends on the GeckoView JAR files.  There are two
 # issues: first, the GeckoView JAR files need to be built before they are
 # consumed here.  This happens for delicate reasons.  In the (serial) libs tier,
 # base/ is traversed before b2gdroid/app.  Since base/libs builds classes.dex,
 # the underlying JAR files are built before the libs tier of b2gdroid/app is
 # processed.  Second, there is a correctness issue: the GeckoView JAR providing
 # org.mozilla.gecko.R does not have the correct resource IDs for the consuming
 # application, so we skip it.  The b2gdroid APK builds a JAR containing
 # org.mozilla.gecko.R itself.
 jars_dir := $(DEPTH)/mobile/android/base
 ANDROID_EXTRA_JARS := $(filter-out %gecko-R.jar,$(wildcard $(jars_dir)/*.jar))
+# Needed for the UpdateService
+ANDROID_EXTRA_JARS += $(ANDROID_COMPAT_LIB)
+
+ANDROID_EXTRA_JARS += \
+	$(ANDROID_SUPPORT_ANNOTATIONS_JAR_LIB) \
+	$(ANDROID_SUPPORT_V4_AAR_LIB) \
+	$(ANDROID_SUPPORT_V4_AAR_INTERNAL_LIB) \
+	$(NULL)
 
 # The GeckoView consuming APK depends on the GeckoView resources.  This hacks a
 # type of poor man's AAR support.
 .aapt.deps: .geckoview_resources.deps
 
 .geckoview_resources.deps: $(DEPTH)/mobile/android/base/geckoview_resources.zip
 	@$(TOUCH) $@
 	$(UNZIP) -u -o $< -d $(CURDIR)/geckoview_resources
--- a/mobile/android/b2gdroid/app/moz.build
+++ b/mobile/android/b2gdroid/app/moz.build
@@ -20,11 +20,15 @@ ANDROID_ASSETS_DIRS += [
 # the GeckoView classes may reference resources provided by other packages.
 # That is, the GeckoView JAR files may reference android.support.v7.appcompat.R
 # (say) at runtime.  That class is in the gecko-R.jar file which is not (and can
 # not!) be included as part of GeckoView.  To avoid this, we'd need to include
 # the transitive set of resource classes.  For now, let's assume that b2gdroid
 # will not induce accesses to other package's resources at runtime.
 ANDROID_EXTRA_PACKAGES += ['org.mozilla.gecko']
 
+if CONFIG['ANDROID_SUPPORT_V4_AAR']:
+    ANDROID_EXTRA_PACKAGES += ['android.support.v4']
+    ANDROID_EXTRA_RES_DIRS += ['%' + CONFIG['ANDROID_SUPPORT_V4_AAR_RES']]
+
 JS_PREFERENCE_FILES += [
      'b2gdroid.js',
 ]
--- a/mobile/android/b2gdroid/app/src/main/AndroidManifest.xml
+++ b/mobile/android/b2gdroid/app/src/main/AndroidManifest.xml
@@ -44,16 +44,19 @@
     <uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
 
     <!-- App requires OpenGL ES 2.0 -->
     <uses-feature android:glEsVersion="0x00020000" android:required="true" />
 
     <!-- Needed to disable the default lockscreen -->
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
 
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.SET_WALLPAPER" />
+
     <application android:label="@string/b2g"
                  android:icon="@drawable/b2g"
                  android:logo="@drawable/b2g"
                  android:hardwareAccelerated="true"
                  android:debuggable="true">
 
         <meta-data android:name="com.sec.android.support.multiwindow" android:value="true"/>
 
@@ -104,11 +107,17 @@
             </intent-filter>
 
             <!-- We will route the search intent to Gaia -->
             <intent-filter>
                 <action android:name="android.intent.action.SEARCH" />
             </intent-filter>
         </activity>
 
+        <service
+            android:exported="false"
+            android:name="org.mozilla.gecko.updater.UpdateService"
+            android:process="org.mozilla.b2gdroid.UpdateService">
+        </service>
+
     </application>
 
 </manifest>
--- a/mobile/android/b2gdroid/app/src/main/java/org/mozilla/b2gdroid/Apps.java
+++ b/mobile/android/b2gdroid/app/src/main/java/org/mozilla/b2gdroid/Apps.java
@@ -71,27 +71,17 @@ class Apps extends BroadcastReceiver
             obj.put("classname", info.name);
 
             final ApplicationInfo appInfo = info.applicationInfo;
             // Pre-installed apps can't be uninstalled.
             final boolean removable =
                 (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0;
 
             obj.put("removable", removable);
-
-            // For now, create a data: url for the icon, since we need additional
-            // android:// protocol support for icons. Once it's there we'll do
-            // something like: obj.put("icon", "android:icon/" + info.packageName);
-            Drawable d = pm.getApplicationIcon(info.packageName);
-            Bitmap bitmap = ((BitmapDrawable)d).getBitmap();
-            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-            bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
-            byte[] byteArray = byteArrayOutputStream.toByteArray();
-            String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
-            obj.put("icon", "data:image/png;base64," + encoded);
+            obj.put("icon", "android://icon/" + appInfo.packageName);
         } catch(Exception ex) {
             Log.wtf(LOGTAG, "Error building ActivityInfo JSON", ex);
         }
         return obj;
     }
 
     public void handleMessage(String event, JSONObject message) {
         Log.w(LOGTAG, "Received " + event);
--- a/mobile/android/b2gdroid/app/src/main/java/org/mozilla/b2gdroid/Launcher.java
+++ b/mobile/android/b2gdroid/app/src/main/java/org/mozilla/b2gdroid/Launcher.java
@@ -23,28 +23,31 @@ import org.mozilla.gecko.BaseGeckoInterf
 import org.mozilla.gecko.ContactService;
 import org.mozilla.gecko.ContextGetter;
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.GeckoBatteryManager;
 import org.mozilla.gecko.GeckoEvent;
 import org.mozilla.gecko.GeckoThread;
 import org.mozilla.gecko.IntentHelper;
+import org.mozilla.gecko.updater.UpdateServiceHelper;
 import org.mozilla.gecko.util.GeckoEventListener;
 
 import org.mozilla.b2gdroid.ScreenStateObserver;
 import org.mozilla.b2gdroid.Apps;
+import org.mozilla.b2gdroid.SettingsMapper;
 
 public class Launcher extends Activity
                       implements GeckoEventListener, ContextGetter {
     private static final String LOGTAG = "B2G";
 
     private ContactService      mContactService;
     private ScreenStateObserver mScreenStateObserver;
     private Apps                mApps;
+    private SettingsMapper      mSettings;
 
     /** ContextGetter */
     public Context getContext() {
         return this;
     }
 
     public SharedPreferences getSharedPreferences() {
         return null;
@@ -52,16 +55,17 @@ public class Launcher extends Activity
 
     /** Initializes Gecko APIs */
     private void initGecko() {
         GeckoAppShell.setContextGetter(this);
 
         GeckoBatteryManager.getInstance().start(this);
         mContactService = new ContactService(EventDispatcher.getInstance(), this);
         mApps = new Apps(this);
+        mSettings = new SettingsMapper(this, null);
     }
 
     private void hideSplashScreen() {
         final View splash = findViewById(R.id.splashscreen);
         runOnUiThread(new Runnable() {
             @Override public void run() {
                 splash.setVisibility(View.GONE);
             }
@@ -81,16 +85,18 @@ public class Launcher extends Activity
         KeyguardManager keyguardManager = (KeyguardManager)getSystemService(KEYGUARD_SERVICE);
         KeyguardLock lock = keyguardManager.newKeyguardLock(KEYGUARD_SERVICE);
         lock.disableKeyguard();
 
         initGecko();
 
         GeckoAppShell.setGeckoInterface(new BaseGeckoInterface(this));
 
+        UpdateServiceHelper.registerForUpdates(this);
+
         EventDispatcher.getInstance().registerGeckoThreadListener(this,
             "Launcher:Ready");
 
         setContentView(R.layout.launcher);
     }
 
     @Override
     public void onResume() {
@@ -108,16 +114,17 @@ public class Launcher extends Activity
         mScreenStateObserver.destroy(this);
         mScreenStateObserver = null;
 
         EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
             "Launcher:Ready");
 
         mContactService.destroy();
         mApps.destroy();
+        mSettings.destroy();
     }
 
     @Override
     protected void onNewIntent(Intent intent) {
         final String action = intent.getAction();
         Log.w(LOGTAG, "onNewIntent " + action);
         if (Intent.ACTION_VIEW.equals(action)) {
             Log.w(LOGTAG, "Asking gecko to view " + intent.getDataString());
new file mode 100644
--- /dev/null
+++ b/mobile/android/b2gdroid/app/src/main/java/org/mozilla/b2gdroid/SettingsMapper.java
@@ -0,0 +1,247 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.b2gdroid;
+
+import java.util.Hashtable;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.Settings.System;
+import android.util.Base64;
+import android.util.Log;
+
+import org.mozilla.gecko.EventDispatcher;
+import org.mozilla.gecko.GeckoAppShell;
+import org.mozilla.gecko.GeckoEvent;
+import org.mozilla.gecko.util.GeckoEventListener;
+
+// This class communicates back and forth with MessagesBridge.jsm to
+// map Android configuration settings and gaia settings.
+// Each setting extends the base BaseMapping class to normalize values
+// when needed.
+
+class SettingsMapper extends ContentObserver implements GeckoEventListener {
+    private static final String LOGTAG = "SettingsMapper";
+
+    private Context mContext;
+    private Hashtable<String, BaseMapping> mGeckoSettings;
+    private Hashtable<String, BaseMapping> mAndroidSettings;
+
+    abstract class BaseMapping {
+        // Returns the list of gaia settings that are managed this class.
+        abstract String[] getGeckoSettings();
+
+        // Returns the list of android settings that are managed this class.
+        abstract String[] getAndroidSettings();
+
+        // Called when we a registered gecko setting changes.
+        abstract void onGeckoChange(String setting, JSONObject message);
+
+        // Called when we a registered android setting changes.
+        abstract void onAndroidChange(Uri uri);
+
+        void sendGeckoSetting(String name, String value) {
+             JSONObject obj = new JSONObject();
+             try {
+                 obj.put(name, value);
+                 sendGeckoSetting(obj);
+             } catch(JSONException e) {
+                Log.d(LOGTAG, e.toString());
+             }
+        }
+
+        void sendGeckoSetting(String name, long value) {
+             JSONObject obj = new JSONObject();
+             try {
+                 obj.put(name, value);
+                 sendGeckoSetting(obj);
+             } catch(JSONException e) {
+                Log.d(LOGTAG, e.toString());
+             }
+        }
+
+        void sendGeckoSetting(JSONObject obj) {
+            GeckoEvent e = GeckoEvent.createBroadcastEvent("Android:Setting", obj.toString());
+            GeckoAppShell.sendEventToGecko(e);
+        }
+    }
+
+    class ScreenTimeoutMapping extends BaseMapping {
+        ScreenTimeoutMapping() {}
+
+        String[] getGeckoSettings() {
+            String props[] = {"screen.timeout"};
+            return props;
+        }
+
+        String[] getAndroidSettings() {
+            String props[] = {"content://settings/system/screen_off_timeout"};
+            return props;
+        }
+
+        void onGeckoChange(String setting, JSONObject message) {
+            try {
+                int timeout = message.getInt("value");
+                // b2g uses seconds for the timeout while Android expects ms.
+                // "never" is 0 in b2g, -1 in Android.
+                if (timeout == 0) {
+                    timeout = -1;
+                } else {
+                    timeout *= 1000;
+                }
+                System.putInt(mContext.getContentResolver(),
+                              System.SCREEN_OFF_TIMEOUT,
+                              timeout);
+            } catch(Exception ex) {
+                Log.d(LOGTAG, "Error setting screen.timeout value", ex);
+            }
+        }
+
+        void onAndroidChange(Uri uri) {
+            try {
+                int timeout = System.getInt(mContext.getContentResolver(),
+                                            System.SCREEN_OFF_TIMEOUT);
+                Log.d(LOGTAG, "Android set timeout to " + timeout);
+
+                // Convert to a gaia timeout.
+                timeout /= 1000;
+                sendGeckoSetting("screen.timeout", timeout);
+            } catch(Exception e) {}
+        }
+    }
+
+    class WallpaperMapping extends BaseMapping {
+        private Context mContext;
+
+        WallpaperMapping(Context context) {
+            mContext = context;
+        }
+
+        String[] getGeckoSettings() {
+            String props[] = {"wallpaper.image"};
+            return props;
+        }
+
+        String[] getAndroidSettings() {
+            String props[] = {};
+            return props;
+        }
+
+        void onGeckoChange(String setting, JSONObject message) {
+            try {
+                final String url = message.getString("value");
+                Log.d(LOGTAG, "wallpaper.image is now " + url);
+                WallpaperManager manager = WallpaperManager.getInstance(mContext);
+                // Remove the data:image/png;base64, prefix from the url.
+                byte[] raw = Base64.decode(url.substring(22), Base64.NO_WRAP);
+                Bitmap bitmap = BitmapFactory.decodeByteArray(raw, 0, raw.length);
+                if (bitmap == null) {
+                    Log.d(LOGTAG, "Unable to create a bitmap!");
+                }
+                manager.setBitmap(bitmap);
+            } catch(Exception ex) {
+                Log.d(LOGTAG, "Error setting wallpaper", ex);
+            }
+        }
+
+        // Android doesn't notify on wallpaper changes.
+        void onAndroidChange(Uri uri) { }
+    }
+
+    SettingsMapper(Context context, Handler handler) {
+        super(handler);
+        mContext = context;
+        EventDispatcher.getInstance()
+                       .registerGeckoThreadListener(this,
+                                                    "Settings:Change");
+
+        mContext.getContentResolver()
+                .registerContentObserver(System.CONTENT_URI,
+                                         true,
+                                         this);
+
+        mGeckoSettings = new Hashtable<String, BaseMapping>();
+        mAndroidSettings = new Hashtable<String, BaseMapping>();
+
+        // Add all the mappings.
+        addMapping(new ScreenTimeoutMapping());
+        addMapping(new WallpaperMapping(mContext));
+    }
+
+    void addMapping(BaseMapping mapping) {
+        String[] props = mapping.getGeckoSettings();
+        for (int i = 0; i < props.length; i++) {
+            mGeckoSettings.put(props[i], mapping);
+        }
+
+        props = mapping.getAndroidSettings();
+        for (int i = 0; i < props.length; i++) {
+            mAndroidSettings.put(props[i], mapping);
+        }
+    }
+
+    void destroy() {
+        EventDispatcher.getInstance()
+                       .unregisterGeckoThreadListener(this,
+                                                      "Settings:Change");
+        mGeckoSettings.clear();
+        mGeckoSettings = null;
+        mAndroidSettings.clear();
+        mAndroidSettings = null;
+        mContext.getContentResolver().unregisterContentObserver(this);
+    }
+
+    public void handleMessage(String event, JSONObject message) {
+        Log.w(LOGTAG, "Received " + event);
+
+        try {
+            String setting = message.getString("setting");
+            BaseMapping mapping = mGeckoSettings.get(setting);
+            if (mapping != null) {
+                Log.d(LOGTAG, "Changing gecko setting " + setting);
+                mapping.onGeckoChange(setting, message);
+            } else {
+                Log.d(LOGTAG, "No gecko mapping registered for " + setting);
+            }
+        } catch(Exception ex) {
+            Log.d(LOGTAG, "Error getting setting name", ex);
+        }
+    }
+
+    // ContentObserver, see
+    // http://developer.android.com/reference/android/database/ContentObserver.html
+    @Override
+    public boolean deliverSelfNotifications() {
+        return false;
+    }
+
+    @Override
+    public void onChange(boolean selfChange) {
+        onChange(selfChange, null);
+    }
+
+    @Override
+    public void onChange(boolean selfChange, Uri uri) {
+        super.onChange(selfChange);
+        Log.d(LOGTAG, "Settings change detected uri=" + uri);
+        BaseMapping mapping = mAndroidSettings.get(uri.toString());
+        if (mapping != null) {
+            Log.d(LOGTAG, "Changing android setting " + uri);
+            mapping.onAndroidChange(uri);
+        } else {
+            Log.d(LOGTAG, "No android mapping registered for " + uri);
+        }
+    }
+
+}
--- a/mobile/android/b2gdroid/components/MessagesBridge.jsm
+++ b/mobile/android/b2gdroid/components/MessagesBridge.jsm
@@ -1,45 +1,54 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 this.EXPORTED_SYMBOLS = ["MessagesBridge"];
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/SystemAppProxy.jsm");
+Cu.import("resource://gre/modules/Messaging.jsm");
+
+XPCOMUtils.defineLazyServiceGetter(this, "settings",
+                                   "@mozilla.org/settingsService;1",
+                                   "nsISettingsService");
 
 // This module receives messages from Launcher.java as observer notifications.
+// It also listens for settings changes to relay them back to Android.
 
 function debug() {
   dump("-*- MessagesBridge " + Array.slice(arguments) + "\n");
 }
 
+function getWindow() {
+  return SystemAppProxy.getFrame().contentWindow ||
+         Services.wm.getMostRecentWindow("navigator:browser");
+}
+
+// To prevent roundtrips like android -> gecko -> android we keep track of
+// in flight setting changes.
+let _blockedSettings = new Set();
+
 this.MessagesBridge = {
   init: function() {
-    Services.obs.addObserver(this, "Android:Launcher", false);
+    Services.obs.addObserver(this.onAndroidMessage, "Android:Launcher", false);
+    Services.obs.addObserver(this.onAndroidSetting, "Android:Setting", false);
+    Services.obs.addObserver(this.onSettingChange, "mozsettings-changed", false);
     Services.obs.addObserver(this, "xpcom-shutdown", false);
   },
 
-  observe: function(aSubject, aTopic, aData) {
-    if (aTopic == "xpcom-shutdown") {
-      Services.obs.removeObserver(this, "Android:Launcher");
-      Services.obs.removeObserver(this, "xpcom-shutdown");
-    }
-
-    if (aTopic != "Android:Launcher") {
-      return;
-    }
-
+  onAndroidMessage: function(aSubject, aTopic, aData) {
     let data = JSON.parse(aData);
     debug(`Got Android:Launcher message ${data.action}`);
 
-    let window = SystemAppProxy.getFrame().contentWindow;
+    let window = getWindow();
     switch (data.action) {
       case "screen_on":
       case "screen_off":
         // In both cases, make it look like pressing the power button
         // by dispatching keydown & keyup on the system app window.
         window.dispatchEvent(new window.KeyboardEvent("keydown", { key: "Power" }));
         window.dispatchEvent(new window.KeyboardEvent("keyup", { key: "Power" }));
         break;
@@ -48,12 +57,63 @@ this.MessagesBridge = {
                                          data: { type: "url",
                                                  url: data.url } });
         break;
       case "home-key":
         window.dispatchEvent(new window.KeyboardEvent("keydown", { key: "Home" }));
         window.dispatchEvent(new window.KeyboardEvent("keyup", { key: "Home" }));
         break;
     }
+  },
+
+  onAndroidSetting: function(aSubject, aTopic, aData) {
+    let data = JSON.parse(aData);
+    let lock = settings.createLock();
+    let key = Object.keys(data)[0];
+    debug(`Got Android:Setting message ${key} -> ${data[key]}`);
+    // Don't relay back to android the same setting change.
+    _blockedSettings.add(key);
+    lock.set(key, data[key], null);
+  },
+
+  onSettingChange: function(aSubject, aTopic, aData) {
+    if ("wrappedJSObject" in aSubject) {
+      aSubject = aSubject.wrappedJSObject;
+    }
+    if (aSubject) {
+      debug("Got setting change: " + aSubject.key + " -> " + aSubject.value);
+
+      if (_blockedSettings.has(aSubject.key)) {
+        _blockedSettings.delete(aSubject.key);
+        debug("Rejecting blocked setting change for " + aSubject.key);
+        return;
+      }
+
+      let window = getWindow();
+
+      if (aSubject.value instanceof window.Blob) {
+        debug(aSubject.key + " is a Blob");
+        let reader = new window.FileReader();
+        reader.readAsDataURL(aSubject.value);
+        reader.onloadend = function() {
+          Messaging.sendRequest({ type: "Settings:Change",
+                                  setting: aSubject.key,
+                                  value: reader.result });
+        }
+      } else {
+        Messaging.sendRequest({ type: "Settings:Change",
+                                setting: aSubject.key,
+                                value: aSubject.value });
+      }
+    }
+  },
+
+  observe: function(aSubject, aTopic, aData) {
+    if (aTopic == "xpcom-shutdown") {
+      Services.obs.removeObserver(this.onAndroidMessage, "Android:Launcher");
+      Services.obs.removeObserver(this.onAndroidSetting, "Android:Setting");
+      Services.obs.removeObserver(this.onSettingChange, "mozsettings-changed");
+      Services.obs.removeObserver(this, "xpcom-shutdown");
+    }
   }
 }
 
 this.MessagesBridge.init();
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -8,16 +8,19 @@ package org.mozilla.gecko;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.net.MalformedURLException;
 import java.net.Proxy;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -2587,26 +2590,92 @@ public class GeckoAppShell
         toast.show();
     }
 
     @WrapForJNI(allowMultithread = true)
     static InputStream createInputStream(URLConnection connection) throws IOException {
         return connection.getInputStream();
     }
 
+    private static class BitmapConnection extends URLConnection {
+        private Bitmap bitmap;
+
+        BitmapConnection(Bitmap b) throws MalformedURLException, IOException {
+            super(null);
+            bitmap = b;
+        }
+
+        @Override
+        public void connect() {}
+
+        @Override
+        public InputStream getInputStream() throws IOException {
+            return new BitmapInputStream();
+        }
+
+        @Override
+        public String getContentType() {
+            return "image/png";
+        }
+
+        private final class BitmapInputStream extends PipedInputStream {
+            private boolean mHaveConnected = false;
+
+            @Override
+            public synchronized int read(byte[] buffer, int byteOffset, int byteCount)
+                                    throws IOException {
+                if (mHaveConnected) {
+                    return super.read(buffer, byteOffset, byteCount);
+                }
+
+                final PipedOutputStream output = new PipedOutputStream();
+                connect(output);
+                ThreadUtils.postToBackgroundThread(
+                    new Runnable() {
+                        @Override
+                        public void run() {
+                            try {
+                                bitmap.compress(Bitmap.CompressFormat.PNG, 100, output);
+                                output.close();
+                            } catch (IOException ioe) {}
+                        }
+                    });
+                mHaveConnected = true;
+                return super.read(buffer, byteOffset, byteCount);
+            }
+        }
+    }
+
     @WrapForJNI(allowMultithread = true, narrowChars = true)
     static URLConnection getConnection(String url) {
         try {
             String spec;
             if (url.startsWith("android://")) {
                 spec = url.substring(10);
             } else {
                 spec = url.substring(8);
             }
 
+            // Check if we are loading a package icon.
+            try {
+                if (spec.startsWith("icon/")) {
+                    String[] splits = spec.split("/");
+                    if (splits.length != 2) {
+                        return null;
+                    }
+                    final String pkg = splits[1];
+                    final PackageManager pm = getContext().getPackageManager();
+                    final Drawable d = pm.getApplicationIcon(pkg);
+                    final Bitmap bitmap = BitmapUtils.getBitmapFromDrawable(d);
+                    return new BitmapConnection(bitmap);
+                }
+            } catch(Exception ex) {
+                Log.e(LOGTAG, "error", ex);
+            }
+
             // if the colon got stripped, put it back
             int colon = spec.indexOf(':');
             if (colon == -1 || colon > spec.indexOf('/')) {
                 spec = spec.replaceFirst("/", ":/");
             }
         } catch(Exception ex) {
             return null;
         }
--- a/testing/docker/phone-builder/Dockerfile
+++ b/testing/docker/phone-builder/Dockerfile
@@ -3,15 +3,15 @@ MAINTAINER    Wander Lairson Costa <wcos
 
 ENV           SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE /home/worker/socorro.token
 
 # Add utilities and configuration
 ADD           bin                   /home/worker/bin
 ADD           config                /home/worker/.aws/config
 ADD           socorro.token         /home/worker/socorro.token
 
-RUN           yum install -y bc lzop
+RUN           yum install -y bc lzop java-1.7.0-openjdk
 RUN           pip install awscli
 RUN           npm install -g bower gulp apm grunt-cli
 
 # Set a default command useful for debugging
 ENTRYPOINT ["validate_task.py"]
 
--- a/testing/docker/phone-builder/VERSION
+++ b/testing/docker/phone-builder/VERSION
@@ -1,1 +1,1 @@
-0.0.20
+0.0.21
--- a/toolkit/components/reader/AboutReader.jsm
+++ b/toolkit/components/reader/AboutReader.jsm
@@ -211,17 +211,17 @@ AboutReader.prototype = {
       // Returns requested status of current ReadingList Sidebar.
       case "ReadingList:VisibilityStatus": {
         this._updateListButtonStyle(message.data.isOpen);
         break;
       }
     }
   },
 
-  handleEvent: function Reader_handleEvent(aEvent) {
+  handleEvent: function(aEvent) {
     if (!aEvent.isTrusted)
       return;
 
     switch (aEvent.type) {
       case "click":
         let target = aEvent.target;
         while (target && target.id != "reader-popup")
           target = target.parentNode;
@@ -250,30 +250,30 @@ AboutReader.prototype = {
         this._mm.removeMessageListener("Reader:Removed", this);
         this._mm.removeMessageListener("Sidebar:VisibilityChange", this);
         this._mm.removeMessageListener("ReadingList:VisibilityStatus", this);
         this._windowUnloaded = true;
         break;
     }
   },
 
-  _updateToggleButton: function Reader_updateToggleButton() {
+  _updateToggleButton: function() {
     let button = this._doc.getElementById("toggle-button");
 
     if (this._isReadingListItem == 1) {
       button.classList.add("on");
       button.setAttribute("title", gStrings.GetStringFromName("aboutReader.toolbar.removeFromReadingList"));
     } else {
       button.classList.remove("on");
       button.setAttribute("title", gStrings.GetStringFromName("aboutReader.toolbar.addToReadingList"));
     }
     this._updateFooter();
   },
 
-  _requestReadingListStatus: function Reader_requestReadingListStatus() {
+  _requestReadingListStatus: function() {
     let handleListStatusData = (message) => {
       this._mm.removeMessageListener("Reader:ListStatusData", handleListStatusData);
 
       let args = message.data;
       if (args.url == this._article.url) {
         if (this._isReadingListItem != args.inReadingList) {
           let isInitialStateChange = (this._isReadingListItem == -1);
           this._isReadingListItem = args.inReadingList;
@@ -291,42 +291,42 @@ AboutReader.prototype = {
         }
       }
     };
 
     this._mm.addMessageListener("Reader:ListStatusData", handleListStatusData);
     this._mm.sendAsyncMessage("Reader:ListStatusRequest", { url: this._article.url });
   },
 
-  _onReaderClose: function Reader_onToggle() {
+  _onReaderClose: function() {
     this._win.location.href = this._getOriginalUrl();
   },
 
-  _onReaderToggle: function Reader_onToggle(aMethod) {
+  _onReaderToggle: function(aMethod) {
     if (!this._article)
       return;
 
     if (this._isReadingListItem == 0) {
       this._mm.sendAsyncMessage("Reader:AddToList", { article: this._article });
       UITelemetry.addEvent("save.1", aMethod, null, "reader");
     } else {
       this._mm.sendAsyncMessage("Reader:RemoveFromList", { url: this._article.url });
       UITelemetry.addEvent("unsave.1", aMethod, null, "reader");
     }
   },
 
-  _onPocketToggle: function Reader_onPocketToggle(aMethod) {
+  _onPocketToggle: function(aMethod) {
     if (!this._article)
       return;
 
     this._mm.sendAsyncMessage("Reader:AddToPocket", { article: this._article });
     UITelemetry.addEvent("pocket.1", aMethod, null, "reader");
   },
 
-  _onShare: function Reader_onShare() {
+  _onShare: function() {
     if (!this._article)
       return;
 
     this._mm.sendAsyncMessage("Reader:Share", {
       url: this._article.url,
       title: this._article.title
     });
     UITelemetry.addEvent("share.1", "list", null);
@@ -371,17 +371,17 @@ AboutReader.prototype = {
       this._setButtonTip("list-button", "aboutReader.toolbar.closeReadingList");
     } else {
       classes.remove("on");
       // When off, action tip is "open".
       this._setButtonTip("list-button", "aboutReader.toolbar.openReadingList");
     }
   },
 
-  _setFontSize: function Reader_setFontSize(newFontSize) {
+  _setFontSize: function(newFontSize) {
     let containerClasses = this._doc.getElementById("container").classList;
 
     if (this._fontSize > 0)
       containerClasses.remove("font-size" + this._fontSize);
 
     this._fontSize = newFontSize;
     containerClasses.add("font-size" + this._fontSize);
 
@@ -447,27 +447,27 @@ AboutReader.prototype = {
       }
 
       currentSize--;
       updateControls();
       this._setFontSize(currentSize);
     }, true);
   },
 
-  _updateFooter: function RupdateFooter() {
+  _updateFooter: function() {
     let footer = this._doc.getElementById("reader-footer");
     if (!this._article || this._isReadingListItem == 0 ||
         footer.getAttribute("readinglist-enabled") != "true") {
       footer.style.display = "none";
       return;
     }
     footer.style.display = null;
   },
 
-  _handleDeviceLight: function Reader_handleDeviceLight(newLux) {
+  _handleDeviceLight: function(newLux) {
     // Desired size of the this._luxValues array.
     let luxValuesSize = 10;
     // Add new lux value at the front of the array.
     this._luxValues.unshift(newLux);
     // Add new lux value to this._totalLux for averaging later.
     this._totalLux += newLux;
 
     // Don't update when length of array is less than luxValuesSize except when it is 1.
@@ -483,45 +483,45 @@ AboutReader.prototype = {
 
     this._updateColorScheme(averageLuxValue);
     // Pop the oldest value off the array.
     let oldLux = this._luxValues.pop();
     // Subtract oldLux since it has been discarded from the array.
     this._totalLux -= oldLux;
   },
 
-  _handleVisibilityChange: function Reader_handleVisibilityChange() {
+  _handleVisibilityChange: function() {
     // ReadingList / Sidebar state might change while we're not the selected tab.
     if (this._doc.visibilityState === "visible") {
       this._updateListButton();
     }
 
     let colorScheme = Services.prefs.getCharPref("reader.color_scheme");
     if (colorScheme != "auto") {
       return;
     }
 
     // Turn off the ambient light sensor if the page is hidden
     this._enableAmbientLighting(!this._doc.hidden);
   },
 
   // Setup or teardown the ambient light tracking system.
-  _enableAmbientLighting: function Reader_enableAmbientLighting(enable) {
+  _enableAmbientLighting: function(enable) {
     if (enable) {
       this._win.addEventListener("devicelight", this, false);
       this._luxValues = [];
       this._totalLux = 0;
     } else {
       this._win.removeEventListener("devicelight", this, false);
       delete this._luxValues;
       delete this._totalLux;
     }
   },
 
-  _updateColorScheme: function Reader_updateColorScheme(luxValue) {
+  _updateColorScheme: function(luxValue) {
     // Upper bound value for "dark" color scheme beyond which it changes to "light".
     let upperBoundDark = 50;
     // Lower bound value for "light" color scheme beyond which it changes to "dark".
     let lowerBoundLight = 10;
     // Threshold for color scheme change.
     let colorChangeThreshold = 20;
 
     // Ignore changes that are within a certain threshold of previous lux values.
@@ -530,43 +530,43 @@ AboutReader.prototype = {
       return;
 
     if (luxValue < colorChangeThreshold)
       this._setColorScheme("dark");
     else
       this._setColorScheme("light");
   },
 
-  _setColorScheme: function Reader_setColorScheme(newColorScheme) {
+  _setColorScheme: function(newColorScheme) {
     // "auto" is not a real color scheme
     if (this._colorScheme === newColorScheme || newColorScheme === "auto")
       return;
 
     let bodyClasses = this._doc.body.classList;
 
     if (this._colorScheme)
       bodyClasses.remove(this._colorScheme);
 
     this._colorScheme = newColorScheme;
     bodyClasses.add(this._colorScheme);
   },
 
   // Pref values include "dark", "light", and "auto", which automatically switches
   // between light and dark color schemes based on the ambient light level.
-  _setColorSchemePref: function Reader_setColorSchemePref(colorSchemePref) {
+  _setColorSchemePref: function(colorSchemePref) {
     this._enableAmbientLighting(colorSchemePref === "auto");
     this._setColorScheme(colorSchemePref);
 
     this._mm.sendAsyncMessage("Reader:SetCharPref", {
       name: "reader.color_scheme",
       value: colorSchemePref
     });
   },
 
-  _setFontType: function Reader_setFontType(newFontType) {
+  _setFontType: function(newFontType) {
     if (this._fontType === newFontType)
       return;
 
     let bodyClasses = this._doc.body.classList;
 
     if (this._fontType)
       bodyClasses.remove(this._fontType);
 
@@ -574,21 +574,21 @@ AboutReader.prototype = {
     bodyClasses.add(this._fontType);
 
     this._mm.sendAsyncMessage("Reader:SetCharPref", {
       name: "reader.font_type",
       value: this._fontType
     });
   },
 
-  _getToolbarVisibility: function Reader_getToolbarVisibility() {
+  _getToolbarVisibility: function() {
     return this._toolbarElement.hasAttribute("visible");
   },
 
-  _setToolbarVisibility: function Reader_setToolbarVisibility(visible) {
+  _setToolbarVisibility: function(visible) {
     let dropdown = this._doc.getElementById("style-dropdown");
     dropdown.classList.remove("open");
 
     if (this._getToolbarVisibility() === visible) {
       return;
     }
 
     if (visible) {
@@ -599,21 +599,21 @@ AboutReader.prototype = {
     this._setSystemUIVisibility(visible);
 
     if (!visible) {
       this._mm.sendAsyncMessage("Reader:ToolbarHidden");
     }
     this._updateFooter();
   },
 
-  _toggleToolbarVisibility: function Reader_toggleToolbarVisibility() {
+  _toggleToolbarVisibility: function() {
     this._setToolbarVisibility(!this._getToolbarVisibility());
   },
 
-  _setSystemUIVisibility: function Reader_setSystemUIVisibility(visible) {
+  _setSystemUIVisibility: function(visible) {
     this._mm.sendAsyncMessage("Reader:SystemUIVisibility", { visible: visible });
   },
 
   _setupPocketButton: Task.async(function* () {
     let pocketEnabledPromise = new Promise((resolve, reject) => {
       let listener = (message) => {
         this._mm.removeMessageListener("Reader:PocketEnabledData", listener);
         resolve(message.data.enabled);
@@ -663,40 +663,40 @@ AboutReader.prototype = {
         this._mm.removeMessageListener("Reader:ArticleData", listener);
         resolve(message.data.article);
       };
       this._mm.addMessageListener("Reader:ArticleData", listener);
       this._mm.sendAsyncMessage("Reader:ArticleGet", { url: url });
     });
   },
 
-  _requestFavicon: function Reader_requestFavicon() {
+  _requestFavicon: function() {
     let handleFaviconReturn = (message) => {
       this._mm.removeMessageListener("Reader:FaviconReturn", handleFaviconReturn);
       this._loadFavicon(message.data.url, message.data.faviconUrl);
     };
 
     this._mm.addMessageListener("Reader:FaviconReturn", handleFaviconReturn);
     this._mm.sendAsyncMessage("Reader:FaviconRequest", { url: this._article.url });
   },
 
-  _loadFavicon: function Reader_loadFavicon(url, faviconUrl) {
+  _loadFavicon: function(url, faviconUrl) {
     if (this._article.url !== url)
       return;
 
     let doc = this._doc;
 
     let link = doc.createElement('link');
     link.rel = 'shortcut icon';
     link.href = faviconUrl;
 
     doc.getElementsByTagName('head')[0].appendChild(link);
   },
 
-  _updateImageMargins: function Reader_updateImageMargins() {
+  _updateImageMargins: function() {
     let windowWidth = this._win.innerWidth;
     let bodyWidth = this._doc.body.clientWidth;
 
     let setImageMargins = function(img) {
       // If the image is at least as wide as the window, make it fill edge-to-edge on mobile.
       if (img.naturalWidth >= windowWidth) {
         img.setAttribute("moz-reader-full-width", true);
       } else {
@@ -743,33 +743,33 @@ AboutReader.prototype = {
     this._messageElement.style.display = "block";
 
     this._doc.title = errorMessage;
 
     this._error = true;
   },
 
   // This function is the JS version of Java's StringUtils.stripCommonSubdomains.
-  _stripHost: function Reader_stripHost(host) {
+  _stripHost: function(host) {
     if (!host)
       return host;
 
     let start = 0;
 
     if (host.startsWith("www."))
       start = 4;
     else if (host.startsWith("m."))
       start = 2;
     else if (host.startsWith("mobile."))
       start = 7;
 
     return host.substring(start);
   },
 
-  _showContent: function Reader_showContent(article) {
+  _showContent: function(article) {
     this._messageElement.style.display = "none";
 
     this._article = article;
 
     this._domainElement.href = article.url;
     let articleUri = Services.io.newURI(article.url, null, null);
     this._domainElement.textContent = this._stripHost(articleUri.host);
     this._creditsElement.textContent = article.byline;
@@ -793,22 +793,22 @@ AboutReader.prototype = {
 
     this._showListIntro();
     this._requestFavicon();
     this._doc.body.classList.add("loaded");
 
     Services.obs.notifyObservers(null, "AboutReader:Ready", "");
   },
 
-  _hideContent: function Reader_hideContent() {
+  _hideContent: function() {
     this._headerElement.style.display = "none";
     this._contentElement.style.display = "none";
   },
 
-  _showProgressDelayed: function Reader_showProgressDelayed() {
+  _showProgressDelayed: function() {
     this._win.setTimeout(function() {
       // No need to show progress if the article has been loaded,
       // if the window has been unloaded, or if there was an error
       // trying to load the article.
       if (this._article || this._windowUnloaded || this._error) {
         return;
       }
 
@@ -823,17 +823,17 @@ AboutReader.prototype = {
   /**
    * Returns the original article URL for this about:reader view.
    */
   _getOriginalUrl: function(win) {
     let url = win ? win.location.href : this._win.location.href;
     return ReaderMode.getOriginalUrl(url) || url;
   },
 
-  _setupSegmentedButton: function Reader_setupSegmentedButton(id, options, initialValue, callback) {
+  _setupSegmentedButton: function(id, options, initialValue, callback) {
     let doc = this._doc;
     let segmentedButton = doc.getElementById(id);
 
     for (let i = 0; i < options.length; i++) {
       let option = options[i];
 
       let item = doc.createElement("button");
 
@@ -903,17 +903,17 @@ AboutReader.prototype = {
    * and dynamically as button state changes.
    * @param   Localizable string providing UI element usage tip.
    */
   _setButtonTip: function(id, titleEntity) {
     let button = this._doc.getElementById(id);
     button.setAttribute("title", gStrings.GetStringFromName(titleEntity));
   },
 
-  _setupStyleDropdown: function Reader_setupStyleDropdown() {
+  _setupStyleDropdown: function() {
     let doc = this._doc;
     let win = this._win;
 
     let dropdown = doc.getElementById("style-dropdown");
     let dropdownToggle = dropdown.querySelector(".dropdown-toggle");
     let dropdownPopup = dropdown.querySelector(".dropdown-popup");
 
     // Helper function used to position the popup on desktop,
--- a/toolkit/components/telemetry/TelemetryStorage.jsm
+++ b/toolkit/components/telemetry/TelemetryStorage.jsm
@@ -1458,17 +1458,17 @@ var TelemetryStorageImpl = {
 
   loadAbortedSessionPing: Task.async(function*() {
     let ping = null;
     try {
       ping = yield this.loadPingFile(gAbortedSessionFilePath);
     } catch (ex if ex.becauseNoSuchFile) {
       this._log.trace("loadAbortedSessionPing - no such file");
     } catch (ex) {
-      this._log.error("loadAbortedSessionPing - error removing ping", ex)
+      this._log.error("loadAbortedSessionPing - error loading ping", ex)
     }
     return ping;
   }),
 
   removeAbortedSessionPing: function() {
     return this._abortedSessionSerializer.enqueueTask(Task.async(function*() {
       try {
         yield OS.File.remove(gAbortedSessionFilePath, { ignoreAbsent: false });
--- a/toolkit/components/viewsource/test/browser/browser.ini
+++ b/toolkit/components/viewsource/test/browser/browser.ini
@@ -2,10 +2,11 @@
 support-files = head.js
   file_bug464222.html
 
 [browser_bug464222.js]
 [browser_bug699356.js]
 [browser_bug713810.js]
 [browser_contextmenu.js]
 [browser_gotoline.js]
+[browser_srcdoc.js]
 [browser_viewsourceprefs.js]
 skip-if = e10s # Bug ?????? - obscure failure (Syntax highlighting off - Got true, expected false)
new file mode 100644
--- /dev/null
+++ b/toolkit/components/viewsource/test/browser/browser_srcdoc.js
@@ -0,0 +1,30 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+const frameSource = `<a href="about:mozilla">good</a>`;
+const source = `<html><iframe srcdoc='${frameSource}' id="f"></iframe></html>`;
+
+add_task(function*() {
+  let url = `data:text/html,${source}`;
+  yield BrowserTestUtils.withNewTab({ gBrowser, url }, checkFrameSource);
+});
+
+function* checkFrameSource() {
+  let sourceTab = yield openViewFrameSourceTab("#f");
+  registerCleanupFunction(function() {
+    gBrowser.removeTab(sourceTab);
+  });
+
+  yield waitForSourceLoaded(sourceTab);
+
+  let browser = gBrowser.selectedBrowser;
+  let textContent = yield ContentTask.spawn(browser, {}, function*() {
+    return content.document.body.textContent;
+  });
+  is(textContent, frameSource, "Correct content loaded");
+  let id = yield ContentTask.spawn(browser, {}, function*() {
+    return content.document.body.id;
+  });
+  is(id, "viewsource", "View source mode enabled")
+}
--- a/toolkit/components/viewsource/test/browser/head.js
+++ b/toolkit/components/viewsource/test/browser/head.js
@@ -44,69 +44,113 @@ function testViewSourceWindow(aURI, aTes
  * Opens a view source tab for a selection (View Selection Source) within the
  * currently selected browser in gBrowser.
  *
  * @param aCSSSelector - used to specify a node within the selection to
  *                       view the source of. It is expected that this node is
  *                       within an existing selection.
  * @returns the new tab which shows the source.
  */
-function* openViewPartialSourceWindow(aCSSSelector) {
-  var contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
-  let popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
+function* openViewPartialSourceTab(aCSSSelector) {
+  let contentAreaContextMenuPopup =
+    document.getElementById("contentAreaContextMenu");
+  let popupShownPromise =
+    BrowserTestUtils.waitForEvent(contentAreaContextMenuPopup, "popupshown");
   yield BrowserTestUtils.synthesizeMouseAtCenter(aCSSSelector,
-          { type: "contextmenu", button: 2}, gBrowser.selectedBrowser);
+          { type: "contextmenu", button: 2 }, gBrowser.selectedBrowser);
   yield popupShownPromise;
 
   let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, null);
 
-  let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
-  EventUtils.synthesizeMouseAtCenter(document.getElementById("context-viewpartialsource-selection"), {});
+  let popupHiddenPromise =
+    BrowserTestUtils.waitForEvent(contentAreaContextMenuPopup, "popuphidden");
+  let item = document.getElementById("context-viewpartialsource-selection");
+  EventUtils.synthesizeMouseAtCenter(item, {});
+  yield popupHiddenPromise;
+
+  return (yield newTabPromise);
+}
+
+/**
+ * Opens a view source tab for a frame (View Frame Source) within the
+ * currently selected browser in gBrowser.
+ *
+ * @param aCSSSelector - used to specify the frame to view the source of.
+ * @returns the new tab which shows the source.
+ */
+function* openViewFrameSourceTab(aCSSSelector) {
+  let contentAreaContextMenuPopup =
+    document.getElementById("contentAreaContextMenu");
+  let popupShownPromise =
+    BrowserTestUtils.waitForEvent(contentAreaContextMenuPopup, "popupshown");
+  yield BrowserTestUtils.synthesizeMouseAtCenter(aCSSSelector,
+          { type: "contextmenu", button: 2 }, gBrowser.selectedBrowser);
+  yield popupShownPromise;
+
+  let frameContextMenu = document.getElementById("frame");
+  popupShownPromise =
+    BrowserTestUtils.waitForEvent(frameContextMenu, "popupshown");
+  EventUtils.synthesizeMouseAtCenter(frameContextMenu, {});
+  yield popupShownPromise;
+
+  let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, null);
+
+  let popupHiddenPromise =
+    BrowserTestUtils.waitForEvent(frameContextMenu, "popuphidden");
+  let item = document.getElementById("context-viewframesource");
+  EventUtils.synthesizeMouseAtCenter(item, {});
   yield popupHiddenPromise;
 
   return (yield newTabPromise);
 }
 
 registerCleanupFunction(function() {
   var windows = Services.wm.getEnumerator("navigator:view-source");
   ok(!windows.hasMoreElements(), "No remaining view source windows still open");
   while (windows.hasMoreElements())
     windows.getNext().close();
 });
 
 /**
+ * For a given view source tab, wait for the source loading step to complete.
+ */
+function waitForSourceLoaded(tab) {
+  return new Promise(resolve => {
+    let mm = tab.linkedBrowser.messageManager;
+    mm.addMessageListener("ViewSource:SourceLoaded", function sourceLoaded() {
+      mm.removeMessageListener("ViewSource:SourceLoaded", sourceLoaded);
+      setTimeout(resolve, 0);
+    });
+  });
+}
+
+/**
  * Open a new document in a new tab, select part of it, and view the source of
  * that selection. The document is not closed afterwards.
  *
  * @param aURI - url to load
  * @param aCSSSelector - used to specify a node to select. All of this node's
  *                       children will be selected.
  * @returns the new tab which shows the source.
- */ 
+ */
 function* openDocumentSelect(aURI, aCSSSelector) {
   let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, aURI);
   registerCleanupFunction(function() {
     gBrowser.removeTab(tab);
   });
 
   yield ContentTask.spawn(gBrowser.selectedBrowser, { selector: aCSSSelector }, function* (arg) {
     let element = content.document.querySelector(arg.selector);
     content.getSelection().selectAllChildren(element);
   });
 
-  let newtab = yield openViewPartialSourceWindow(aCSSSelector);
+  let newtab = yield openViewPartialSourceTab(aCSSSelector);
 
   // Wait until the source has been loaded.
-  yield new Promise(resolve => {
-    let mm = newtab.linkedBrowser.messageManager;
-    mm.addMessageListener("ViewSource:SourceLoaded", function selectionDrawn() {
-      mm.removeMessageListener("ViewSource:SourceLoaded", selectionDrawn);
-      setTimeout(resolve, 0);
-    });
-  });
+  yield waitForSourceLoaded(newtab);
 
   return newtab;
 }
 
 function waitForPrefChange(pref) {
   let deferred = PromiseUtils.defer();
   let observer = () => {
     Preferences.ignore(pref, observer);
--- a/toolkit/modules/Sqlite.jsm
+++ b/toolkit/modules/Sqlite.jsm
@@ -33,16 +33,19 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyServiceGetter(this, "FinalizationWitnessService",
                                    "@mozilla.org/toolkit/finalizationwitness;1",
                                    "nsIFinalizationWitnessService");
 XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils",
                                   "resource://gre/modules/PromiseUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "console",
                                   "resource://gre/modules/devtools/shared/Console.jsm");
 
+// Regular expression used by isInvalidBoundLikeQuery
+var likeSqlRegex = /\bLIKE\b\s(?![@:?])/i;
+
 // Counts the number of created connections per database basename(). This is
 // used for logging to distinguish connection instances.
 var connectionCounters = new Map();
 
 // Tracks identifiers of wrapped connections, that are Storage connections
 // opened through mozStorage and then wrapped by Sqlite.jsm to use its syntactic
 // sugar API.  Since these connections have an unknown origin, we use this set
 // to differentiate their behavior.
@@ -55,16 +58,27 @@ var isClosed = false;
 
 var Debugging = {
   // Tests should fail if a connection auto closes.  The exception is
   // when finalization itself is tested, in which case this flag
   // should be set to false.
   failTestsOnAutoClose: true
 };
 
+/**
+ * Helper function to check whether LIKE is implemented using proper bindings.
+ *
+ * @param sql
+ *        (string) The SQL query to be verified.
+ * @return boolean value telling us whether query was correct or not
+*/
+function isInvalidBoundLikeQuery(sql) {
+  return likeSqlRegex.test(sql);
+}
+
 // Displays a script error message
 function logScriptError(message) {
   let consoleMessage = Cc["@mozilla.org/scripterror;1"].
                        createInstance(Ci.nsIScriptError);
   let stack = new Error();
   consoleMessage.init(message, stack.fileName, null, stack.lineNumber, 0,
                       Ci.nsIScriptError.errorFlag, "component javascript");
   Services.console.logMessage(consoleMessage);
@@ -1268,16 +1282,19 @@ OpenedConnection.prototype = Object.free
    * @param name
    *        (string) The name of the registered statement to execute.
    * @param params optional
    *        (Array or object) Parameters to bind.
    * @param onRow optional
    *        (function) Callback to receive each row from result.
    */
   executeCached: function (sql, params=null, onRow=null) {
+    if (isInvalidBoundLikeQuery(sql)) {
+      throw new Error("Please enter a LIKE clause with bindings");
+    }
     return this._connectionData.executeCached(sql, params, onRow);
   },
 
   /**
    * Execute a one-shot SQL statement.
    *
    * If you find yourself feeding the same SQL string in this function, you
    * should *not* use this function and instead use `executeCached`.
@@ -1287,16 +1304,19 @@ OpenedConnection.prototype = Object.free
    * @param sql
    *        (string) SQL to execute.
    * @param params optional
    *        (Array or Object) Parameters to bind to the statement.
    * @param onRow optional
    *        (function) Callback to receive result of a single row.
    */
   execute: function (sql, params=null, onRow=null) {
+    if (isInvalidBoundLikeQuery(sql)) {
+      throw new Error("Please enter a LIKE clause with bindings");
+    }
     return this._connectionData.execute(sql, params, onRow);
   },
 
   /**
    * Whether a transaction is currently in progress.
    */
   get transactionInProgress() {
     return this._connectionData.transactionInProgress;
--- a/toolkit/modules/tests/xpcshell/test_sqlite.js
+++ b/toolkit/modules/tests/xpcshell/test_sqlite.js
@@ -270,16 +270,25 @@ add_task(function* test_execute_invalid_
   yield deferred.promise;
 
   // Ensure we don't leak the statement instance.
   do_check_eq(c._connectionData._anonymousStatements.size, 0);
 
   yield c.close();
 });
 
+add_task(function* test_incorrect_like_bindings() {
+  let c = yield getDummyDatabase("incorrect_like_bindings");
+
+  let sql = "select * from dirs where path LIKE 'non%'";
+  Assert.throws(() => c.execute(sql), /Please enter a LIKE clause/);
+  Assert.throws(() => c.executeCached(sql), /Please enter a LIKE clause/);
+
+  yield c.close();
+});
 add_task(function* test_on_row_exception_ignored() {
   let c = yield getDummyDatabase("on_row_exception_ignored");
 
   let sql = "INSERT INTO dirs (path) VALUES (?)";
   for (let i = 0; i < 10; i++) {
     yield c.executeCached(sql, ["dir" + i]);
   }
 
--- a/toolkit/themes/shared/in-content/common.inc.css
+++ b/toolkit/themes/shared/in-content/common.inc.css
@@ -290,16 +290,17 @@ xul|*.help-button > xul|*.button-box > x
   height: 18px;
 }
 
 xul|*.help-button > xul|*.button-box > xul|*.button-text {
   display: none;
 }
 
 xul|*.spinbuttons-button {
+  min-height: initial;
   -moz-margin-start: 10px !important;
   -moz-margin-end: 2px !important;
 }
 
 xul|*.spinbuttons-up {
   margin-top: 2px !important;
   border-radius: 1px 1px 0 0;
 }
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -2082,17 +2082,17 @@ void
 AndroidBridge::SetPresentationSurface(EGLSurface aPresentationSurface)
 {
     mPresentationSurface = aPresentationSurface;
 }
 
 Object::LocalRef AndroidBridge::ChannelCreate(Object::Param stream) {
     JNIEnv* const env = GetEnvForThread();
     auto rv = Object::LocalRef::Adopt(env, env->CallStaticObjectMethod(
-            sBridge->jReadableByteChannel, sBridge->jChannelCreate, stream.Get()));
+            sBridge->jChannels, sBridge->jChannelCreate, stream.Get()));
     HandleUncaughtException(env);
     return rv;
 }
 
 void AndroidBridge::InputStreamClose(Object::Param obj) {
     JNIEnv* const env = GetEnvForThread();
     env->CallVoidMethod(obj.Get(), sBridge->jClose);
     HandleUncaughtException(env);