merge b2g-inbound to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Mon, 12 Jan 2015 14:59:45 +0100
changeset 250771 ee55ebb9d533fb55aa588a8966b63bd8e812a920
parent 250736 a41cce2dd4081306e06bb93b9c80bb125c9d1265 (current diff)
parent 250770 6ca62d59687c430e1e32df3118dc9c784ebf3739 (diff)
child 250772 cac64af410a11b92d6d091c38e4ffe0b750b0273
child 250809 0e9765732906250f27e59f014fadd38d8f69b32e
child 250820 ade0a9f9e4873bf61009c4987baedf250c01f897
child 250877 a44152aabff48952b4fb78db68d53ce84d323fc3
push id698
push userjlund@mozilla.com
push dateMon, 23 Mar 2015 22:08:11 +0000
treeherdermozilla-release@b0c0ae7b02a3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge b2g-inbound to mozilla-central a=merge
configure.in
dom/ipc/TabParent.cpp
--- 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="e0c735ec89df011ea7dd435087a9045ecff9ff9e">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
--- 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="df362ace56338da8173d30d3e09e08c42c1accfa">
     <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="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <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="0e94c080bee081a50aa2097527b0b40852f9143f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e0c735ec89df011ea7dd435087a9045ecff9ff9e">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
--- 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="df362ace56338da8173d30d3e09e08c42c1accfa">
     <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="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <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="e0c735ec89df011ea7dd435087a9045ecff9ff9e">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="0e94c080bee081a50aa2097527b0b40852f9143f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
         "git_revision": "", 
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "3bf54932bcae08eb6cab2453a2be007835423cbd", 
+    "revision": "4f9b71ccf0770ad99ba7f802d951f569e10b1021", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="df362ace56338da8173d30d3e09e08c42c1accfa">
     <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="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform_bionic" path="bionic" remote="b2g" revision="1a2a32eda22ef2cd18f57f423a5e7b22a105a6f8"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="746bc48f34f5060f90801925dcdd964030c1ab6d"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="df362ace56338da8173d30d3e09e08c42c1accfa">
     <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="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform_bionic" path="bionic" remote="b2g" revision="1a2a32eda22ef2cd18f57f423a5e7b22a105a6f8"/>
--- 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="0e94c080bee081a50aa2097527b0b40852f9143f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="df362ace56338da8173d30d3e09e08c42c1accfa">
     <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="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/configure.in
+++ b/configure.in
@@ -285,16 +285,17 @@ if test -n "$gonkdir" ; then
         ;;
     21)
         GONK_INCLUDES="-I$gonkdir/frameworks/native/include -I$gonkdir/frameworks/av/include -I$gonkdir/frameworks/av/include/media -I$gonkdir/frameworks/av/include/camera -I$gonkdir/frameworks/native/include/media/openmax -I$gonkdir/frameworks/av/media/libstagefright/include"
         MOZ_AUDIO_OFFLOAD=1
         MOZ_OMX_DECODER=1
         AC_SUBST(MOZ_AUDIO_OFFLOAD)
         AC_DEFINE(MOZ_AUDIO_OFFLOAD)
         MOZ_FMP4=
+        MOZ_B2G_CAMERA=1
         MOZ_B2G_BT=1
         MOZ_B2G_BT_BLUEDROID=1
         if test -d "$gonkdir/system/bluetoothd"; then
             MOZ_B2G_BT_DAEMON=1
         fi
         ;;
     *)
         AC_MSG_ERROR([Unsupported platform version: $ANDROID_VERSION])
--- a/dom/camera/GonkCameraControl.cpp
+++ b/dom/camera/GonkCameraControl.cpp
@@ -35,16 +35,17 @@
 #include <media/mediaplayer.h>
 #include "nsPrintfCString.h"
 #include "nsIObserverService.h"
 #include "nsIVolume.h"
 #include "nsIVolumeService.h"
 #include "AutoRwLock.h"
 #include "GonkCameraHwMgr.h"
 #include "GonkRecorderProfiles.h"
+#include "GrallocImages.h"
 #include "CameraCommon.h"
 #include "GonkCameraParameters.h"
 #include "DeviceStorageFileDescriptor.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::gfx;
 using namespace mozilla::ipc;
--- a/dom/camera/GonkCameraHwMgr.cpp
+++ b/dom/camera/GonkCameraHwMgr.cpp
@@ -178,17 +178,23 @@ GonkCameraHardware::Init()
   }
   DOM_CAMERA_LOGI("Sensor orientation: base=%d, offset=%d, final=%d\n", info.orientation, offset, mSensorOrientation);
 
   // Disable shutter sound in android CameraService because gaia camera app will play it
   mCamera->sendCommand(CAMERA_CMD_ENABLE_SHUTTER_SOUND, 0, 0);
 
 #if defined(MOZ_WIDGET_GONK)
 
-#if ANDROID_VERSION >= 19
+#if ANDROID_VERSION >= 21
+  sp<IGraphicBufferProducer> producer;
+  sp<IGonkGraphicBufferConsumer> consumer;
+  GonkBufferQueue::createBufferQueue(&producer, &consumer);
+  mNativeWindow = new GonkNativeWindow(consumer, GonkCameraHardware::MIN_UNDEQUEUED_BUFFERS);
+  mCamera->setPreviewTarget(producer);
+#elif ANDROID_VERSION >= 19
   mNativeWindow = new GonkNativeWindow(GonkCameraHardware::MIN_UNDEQUEUED_BUFFERS);
   sp<GonkBufferQueue> bq = mNativeWindow->getBufferQueue();
   bq->setSynchronousMode(false);
   mCamera->setPreviewTarget(mNativeWindow->getBufferQueue());
 #elif ANDROID_VERSION >= 17
   mNativeWindow = new GonkNativeWindow(GonkCameraHardware::MIN_UNDEQUEUED_BUFFERS);
   sp<GonkBufferQueue> bq = mNativeWindow->getBufferQueue();
   bq->setSynchronousMode(false);
--- a/dom/camera/GonkRecorder.cpp
+++ b/dom/camera/GonkRecorder.cpp
@@ -1149,17 +1149,21 @@ status_t GonkRecorder::setupMediaSource(
     if (mVideoSource == VIDEO_SOURCE_DEFAULT
             || mVideoSource == VIDEO_SOURCE_CAMERA) {
         sp<GonkCameraSource> cameraSource;
         status_t err = setupCameraSource(&cameraSource);
         if (err != OK) {
             return err;
         }
         *mediaSource = cameraSource;
+#if ANDROID_VERSION >= 21
+    } else if (mVideoSource == VIDEO_SOURCE_SURFACE) {
+#else
     } else if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) {
+#endif
         return BAD_VALUE;
     } else {
         return INVALID_OPERATION;
     }
     return OK;
 }
 
 status_t GonkRecorder::setupCameraSource(
--- a/dom/events/KeyNameList.h
+++ b/dom/events/KeyNameList.h
@@ -24,16 +24,17 @@
  * Special Key Values
  *****************************************************************************/
 DEFINE_KEYNAME_WITH_SAME_NAME(Unidentified)
 
 /******************************************************************************
  * Our Internal Key Values (must have "Moz" prefix)
  *****************************************************************************/
 DEFINE_KEYNAME_INTERNAL(PrintableKey, "MozPrintableKey")
+DEFINE_KEYNAME_INTERNAL(HomeScreen, "MozHomeScreen")
 
 /******************************************************************************
  * Modifier Keys
  *****************************************************************************/
 DEFINE_KEYNAME_WITH_SAME_NAME(Alt)
 DEFINE_KEYNAME_WITH_SAME_NAME(AltGraph)
 DEFINE_KEYNAME_WITH_SAME_NAME(CapsLock)
 DEFINE_KEYNAME_WITH_SAME_NAME(Control)
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -2190,17 +2190,21 @@ TabParent::UseAsyncPanZoom()
           GetScrollingBehavior() == ASYNC_PAN_ZOOM);
 }
 
 nsEventStatus
 TabParent::MaybeForwardEventToRenderFrame(WidgetInputEvent& aEvent,
                                           ScrollableLayerGuid* aOutTargetGuid,
                                           uint64_t* aOutInputBlockId)
 {
-  if (aEvent.mClass == eWheelEventClass) {
+  if (aEvent.mClass == eWheelEventClass
+#ifdef MOZ_WIDGET_GONK
+      || aEvent.mClass == eTouchEventClass
+#endif
+     ) {
     // Wheel events must be sent to APZ directly from the widget. New APZ-
     // aware events should follow suit and move there as well. However, we
     // do need to inform the child process of the correct target and block
     // id.
     if (aOutTargetGuid) {
       *aOutTargetGuid = InputAPZContext::GetTargetLayerGuid();
     }
     if (aOutInputBlockId) {
--- a/dom/system/gonk/AutoMounter.cpp
+++ b/dom/system/gonk/AutoMounter.cpp
@@ -1054,25 +1054,26 @@ AutoMounter::UpdateState()
           }
 
           // Volume is mounted, we need to unmount before
           // we can share.
           LOG("UpdateState: Unmounting %s", vol->NameStr());
           vol->StartUnmount(mResponseCallback);
           return; // UpdateState will be called again when the Unmount command completes
         }
-        case nsIVolume::STATE_IDLE: {
-          LOG("UpdateState: Volume %s is nsIVolume::STATE_IDLE", vol->NameStr());
+        case nsIVolume::STATE_IDLE:
+        case nsIVolume::STATE_MOUNT_FAIL: {
+          LOG("UpdateState: Volume %s is %s", vol->NameStr(), vol->StateStr());
           if (vol->IsFormatting() && !vol->IsFormatRequested()) {
             vol->SetFormatRequested(false);
             LOG("UpdateState: Mounting %s", vol->NameStr());
             vol->StartMount(mResponseCallback);
             break;
           }
-          if (tryToShare && vol->IsSharingEnabled()) {
+          if (tryToShare && vol->IsSharingEnabled() && volState == nsIVolume::STATE_IDLE) {
             // Volume is unmounted. We can go ahead and share.
             LOG("UpdateState: Sharing %s", vol->NameStr());
             vol->StartShare(mResponseCallback);
           } else if (vol->IsFormatRequested()){
             // Volume is unmounted. We can go ahead and format.
             LOG("UpdateState: Formatting %s", vol->NameStr());
             vol->StartFormat(mResponseCallback);
           }
--- a/dom/system/gonk/Volume.cpp
+++ b/dom/system/gonk/Volume.cpp
@@ -332,21 +332,23 @@ Volume::SetState(Volume::STATE aNewState
        mMediaPresent = false;
        mIsSharing = false;
        mUnmountRequested = false;
        mMountRequested = false;
        mIsUnmounting = false;
        break;
 
      case nsIVolume::STATE_MOUNTED:
+     case nsIVolume::STATE_MOUNT_FAIL:
        mMountRequested = false;
        mIsFormatting = false;
        mIsSharing = false;
        mIsUnmounting = false;
        break;
+
      case nsIVolume::STATE_FORMATTING:
        mFormatRequested = false;
        mIsFormatting = true;
        mIsSharing = false;
        mIsUnmounting = false;
        break;
 
      case nsIVolume::STATE_SHARED:
@@ -536,17 +538,22 @@ Volume::HandleVoldResponse(int aResponse
           token = aTokenizer.nextToken();
           STATE newState = (STATE)(token.ToInteger(&errCode));
           if (newState == nsIVolume::STATE_MOUNTED) {
             // We set the state to STATE_CHECKMNT here, and the once the
             // AutoMounter detects that the volume is actually accessible
             // then the AutoMounter will set the volume as STATE_MOUNTED.
             SetState(nsIVolume::STATE_CHECKMNT);
           } else {
-            SetState(newState);
+            if (State() == nsIVolume::STATE_CHECKING && newState == nsIVolume::STATE_IDLE) {
+              LOG("Mount of volume '%s' failed", NameStr());
+              SetState(nsIVolume::STATE_MOUNT_FAIL);
+            } else {
+              SetState(newState);
+            }
           }
           break;
         }
       }
       break;
     }
 
     case ::ResponseCode::VolumeDiskInserted:
--- a/dom/system/gonk/nsIVolume.idl
+++ b/dom/system/gonk/nsIVolume.idl
@@ -1,30 +1,33 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 #include "nsIVolumeStat.idl"
 
-[scriptable, uuid(946B5334-6EC9-11E4-8689-F3061E5D46B0)]
+[scriptable, uuid(EE752CB8-8FD7-11E4-A602-70221D5D46B0)]
 interface nsIVolume : nsISupports
 {
   // These MUST match the states from android's system/vold/Volume.h header
+  // Note: Changes made to the STATE_xxx names should also be reflected in the
+  //       NS_VolumeStateStr function found in Volume.cpp
   const long STATE_INIT        = -1;
   const long STATE_NOMEDIA     = 0;
   const long STATE_IDLE        = 1;
   const long STATE_PENDING     = 2;
   const long STATE_CHECKING    = 3;
   const long STATE_MOUNTED     = 4;
   const long STATE_UNMOUNTING  = 5;
   const long STATE_FORMATTING  = 6;
   const long STATE_SHARED      = 7;
   const long STATE_SHAREDMNT   = 8;
   const long STATE_CHECKMNT    = 100;
+  const long STATE_MOUNT_FAIL  = 101;
 
   // The name of the volume. Often there is only one volume, called sdcard.
   // But some phones support multiple volumes.
   readonly attribute DOMString name;
 
   // The mount point is the path on the system where the volume is mounted
   // and is only valid when state == STATE_MOUNTED.
   readonly attribute DOMString mountPoint;
--- a/dom/system/gonk/nsVolume.cpp
+++ b/dom/system/gonk/nsVolume.cpp
@@ -33,16 +33,17 @@ NS_VolumeStateStr(int32_t aState)
     case nsIVolume::STATE_PENDING:    return "Pending";
     case nsIVolume::STATE_CHECKING:   return "Checking";
     case nsIVolume::STATE_MOUNTED:    return "Mounted";
     case nsIVolume::STATE_UNMOUNTING: return "Unmounting";
     case nsIVolume::STATE_FORMATTING: return "Formatting";
     case nsIVolume::STATE_SHARED:     return "Shared";
     case nsIVolume::STATE_SHAREDMNT:  return "Shared-Mounted";
     case nsIVolume::STATE_CHECKMNT:   return "Check-Mounted";
+    case nsIVolume::STATE_MOUNT_FAIL: return "Mount-Fail";
   }
   return "???";
 }
 
 // While nsVolumes can only be used on the main thread, in the
 // UpdateVolumeRunnable constructor (which is called from IOThread) we
 // allocate an nsVolume which is then passed to MainThread. Since we
 // have a situation where we allocate on one thread and free on another
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -84,17 +84,17 @@ APZCTreeManager::CalculatePendingDisplay
 {
   return AsyncPanZoomController::CalculatePendingDisplayPort(
     aFrameMetrics, aVelocity, aEstimatedPaintDuration);
 }
 
 APZCTreeManager::APZCTreeManager()
     : mInputQueue(new InputQueue()),
       mTreeLock("APZCTreeLock"),
-      mHitResultForInputBlock(NoApzcHit),
+      mHitResultForInputBlock(HitNothing),
       mRetainedTouchIdentifier(-1),
       mTouchCount(0),
       mApzcTreeLog("apzctree")
 {
   MOZ_ASSERT(NS_IsMainThread());
   AsyncPanZoomController::InitializeGlobalState();
   mApzcTreeLog.ConditionOnPrefFunction(gfxPrefs::APZPrintTree);
 }
@@ -556,114 +556,114 @@ APZCTreeManager::ReceiveInputEvent(Input
 {
   // Initialize aOutInputBlockId to a sane value, and then later we overwrite
   // it if the input event goes into a block.
   if (aOutInputBlockId) {
     *aOutInputBlockId = InputBlockState::NO_BLOCK_ID;
   }
   nsEventStatus result = nsEventStatus_eIgnore;
   Matrix4x4 transformToApzc;
-  HitTestResult hitResult = NoApzcHit;
+  HitTestResult hitResult = HitNothing;
   switch (aEvent.mInputType) {
     case MULTITOUCH_INPUT: {
       MultiTouchInput& touchInput = aEvent.AsMultiTouchInput();
       result = ProcessTouchInput(touchInput, aOutTargetGuid, aOutInputBlockId);
       break;
     } case SCROLLWHEEL_INPUT: {
       ScrollWheelInput& wheelInput = aEvent.AsScrollWheelInput();
       nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(wheelInput.mOrigin,
                                                             &hitResult);
       if (apzc) {
-        MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
+        MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion);
 
         transformToApzc = GetScreenToApzcTransform(apzc);
         wheelInput.mLocalOrigin =
           TransformTo<ParentLayerPixel>(transformToApzc, wheelInput.mOrigin);
 
         result = mInputQueue->ReceiveInputEvent(
           apzc,
-          /* aTargetConfirmed = */ hitResult == ApzcHitRegion,
+          /* aTargetConfirmed = */ hitResult == HitLayer,
           wheelInput, aOutInputBlockId);
 
         // Update the out-parameters so they are what the caller expects.
         apzc->GetGuid(aOutTargetGuid);
         Matrix4x4 transformToGecko = transformToApzc * GetApzcToGeckoTransform(apzc);
         wheelInput.mOrigin =
           TransformTo<ScreenPixel>(transformToGecko, wheelInput.mOrigin);
       }
       break;
     } case PANGESTURE_INPUT: {
       PanGestureInput& panInput = aEvent.AsPanGestureInput();
       nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(panInput.mPanStartPoint,
                                                             &hitResult);
       if (apzc) {
-        MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
+        MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion);
         transformToApzc = GetScreenToApzcTransform(apzc);
         panInput.mLocalPanStartPoint = TransformTo<ParentLayerPixel>(
             transformToApzc, panInput.mPanStartPoint);
         panInput.mLocalPanDisplacement = TransformVector<ParentLayerPixel>(
             transformToApzc, panInput.mPanDisplacement, panInput.mPanStartPoint);
         result = mInputQueue->ReceiveInputEvent(
             apzc,
-            /* aTargetConfirmed = */ hitResult == ApzcHitRegion,
+            /* aTargetConfirmed = */ hitResult == HitLayer,
             panInput, aOutInputBlockId);
 
         // Update the out-parameters so they are what the caller expects.
         apzc->GetGuid(aOutTargetGuid);
         Matrix4x4 transformToGecko = transformToApzc * GetApzcToGeckoTransform(apzc);
         panInput.mPanStartPoint = TransformTo<ScreenPixel>(
             transformToGecko, panInput.mPanStartPoint);
         panInput.mPanDisplacement = TransformVector<ScreenPixel>(
             transformToGecko, panInput.mPanDisplacement, panInput.mPanStartPoint);
       }
       break;
     } case PINCHGESTURE_INPUT: {  // note: no one currently sends these
       PinchGestureInput& pinchInput = aEvent.AsPinchGestureInput();
       nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(pinchInput.mFocusPoint,
                                                             &hitResult);
       if (apzc) {
-        MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
+        MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion);
         transformToApzc = GetScreenToApzcTransform(apzc);
         pinchInput.mLocalFocusPoint = TransformTo<ParentLayerPixel>(
             transformToApzc, pinchInput.mFocusPoint);
         result = mInputQueue->ReceiveInputEvent(
             apzc,
-            /* aTargetConfirmed = */ hitResult == ApzcHitRegion,
+            /* aTargetConfirmed = */ hitResult == HitLayer,
             pinchInput, aOutInputBlockId);
 
         // Update the out-parameters so they are what the caller expects.
         apzc->GetGuid(aOutTargetGuid);
         Matrix4x4 outTransform = transformToApzc * GetApzcToGeckoTransform(apzc);
         pinchInput.mFocusPoint = TransformTo<ScreenPixel>(
             outTransform, pinchInput.mFocusPoint);
       }
       break;
     } case TAPGESTURE_INPUT: {  // note: no one currently sends these
       TapGestureInput& tapInput = aEvent.AsTapGestureInput();
       nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(tapInput.mPoint,
                                                             &hitResult);
       if (apzc) {
-        MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
+        MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion);
         transformToApzc = GetScreenToApzcTransform(apzc);
         tapInput.mLocalPoint = TransformTo<ParentLayerPixel>(
             transformToApzc, tapInput.mPoint);
         result = mInputQueue->ReceiveInputEvent(
             apzc,
-            /* aTargetConfirmed = */ hitResult == ApzcHitRegion,
+            /* aTargetConfirmed = */ hitResult == HitLayer,
             tapInput, aOutInputBlockId);
 
         // Update the out-parameters so they are what the caller expects.
         apzc->GetGuid(aOutTargetGuid);
         Matrix4x4 outTransform = transformToApzc * GetApzcToGeckoTransform(apzc);
         tapInput.mPoint = TransformTo<ScreenPixel>(outTransform, tapInput.mPoint);
       }
       break;
     }
   }
-  if (hitResult == OverscrolledApzc) {
+  if (hitResult == HitOverscrolledApzc) {
     result = nsEventStatus_eConsumeNoDefault;
   }
   return result;
 }
 
 already_AddRefed<AsyncPanZoomController>
 APZCTreeManager::GetTouchInputBlockAPZC(const MultiTouchInput& aEvent,
                                         HitTestResult* aOutHitResult)
@@ -710,19 +710,19 @@ APZCTreeManager::ProcessTouchInput(Multi
         mRetainedTouchIdentifier = mApzcForInputBlock->GetLastTouchIdentifier();
       }
       return nsEventStatus_eConsumeNoDefault;
     }
 
     // NS_TOUCH_START event contains all active touches of the current
     // session thus resetting mTouchCount.
     mTouchCount = aInput.mTouches.Length();
-    mHitResultForInputBlock = NoApzcHit;
+    mHitResultForInputBlock = HitNothing;
     nsRefPtr<AsyncPanZoomController> apzc = GetTouchInputBlockAPZC(aInput, &mHitResultForInputBlock);
-    // XXX the following check assumes mHitResultForInputBlock == ApzcHitRegion
+    // XXX the following check assumes mHitResultForInputBlock == HitLayer
     // (and that mApzcForInputBlock was the confirmed target of the previous
     // input block). Eventually it would be better to move this into InputQueue
     // and have it auto-generated when we start processing events in a new
     // event block.
     if (apzc != mApzcForInputBlock) {
       // If we're moving to a different APZC as our input target, then send a cancel event
       // to the old one so that it clears its internal state. Otherwise it could get left
       // in the middle of a panning touch block (for example) and not clean up properly.
@@ -764,45 +764,45 @@ APZCTreeManager::ProcessTouchInput(Multi
     }
     if (aInput.mTouches.IsEmpty()) {
       return nsEventStatus_eConsumeNoDefault;
     }
   }
 
   nsEventStatus result = nsEventStatus_eIgnore;
   if (mApzcForInputBlock) {
-    MOZ_ASSERT(mHitResultForInputBlock == ApzcHitRegion || mHitResultForInputBlock == ApzcContentRegion);
+    MOZ_ASSERT(mHitResultForInputBlock == HitLayer || mHitResultForInputBlock == HitDispatchToContentRegion);
 
     mApzcForInputBlock->GetGuid(aOutTargetGuid);
     // For computing the input for the APZC, used the cached transform.
     // This ensures that the sequence of touch points an APZC sees in an
     // input block are all in the same coordinate space.
     Matrix4x4 transformToApzc = mCachedTransformToApzcForInputBlock;
     for (size_t i = 0; i < aInput.mTouches.Length(); i++) {
       SingleTouchData& touchData = aInput.mTouches[i];
       touchData.mLocalScreenPoint = TransformTo<ParentLayerPixel>(
           transformToApzc, ScreenPoint(touchData.mScreenPoint));
     }
     result = mInputQueue->ReceiveInputEvent(mApzcForInputBlock,
-        /* aTargetConfirmed = */ mHitResultForInputBlock == ApzcHitRegion,
+        /* aTargetConfirmed = */ mHitResultForInputBlock == HitLayer,
         aInput, aOutInputBlockId);
 
     // For computing the event to pass back to Gecko, use the up-to-date transforms.
     // This ensures that transformToApzc and transformToGecko are in sync
     // (note that transformToGecko isn't cached).
     transformToApzc = GetScreenToApzcTransform(mApzcForInputBlock);
     Matrix4x4 transformToGecko = GetApzcToGeckoTransform(mApzcForInputBlock);
     Matrix4x4 outTransform = transformToApzc * transformToGecko;
     for (size_t i = 0; i < aInput.mTouches.Length(); i++) {
       SingleTouchData& touchData = aInput.mTouches[i];
       touchData.mScreenPoint = TransformTo<ScreenPixel>(
           outTransform, touchData.mScreenPoint);
     }
   }
-  if (mHitResultForInputBlock == OverscrolledApzc) {
+  if (mHitResultForInputBlock == HitOverscrolledApzc) {
     result = nsEventStatus_eConsumeNoDefault;
   }
 
   if (aInput.mType == MultiTouchInput::MULTITOUCH_END) {
     if (mTouchCount >= aInput.mTouches.Length()) {
       // NS_TOUCH_END event contains only released touches thus decrementing.
       mTouchCount -= aInput.mTouches.Length();
     } else {
@@ -812,17 +812,17 @@ APZCTreeManager::ProcessTouchInput(Multi
   } else if (aInput.mType == MultiTouchInput::MULTITOUCH_CANCEL) {
     mTouchCount = 0;
   }
 
   // If it's the end of the touch sequence then clear out variables so we
   // don't keep dangling references and leak things.
   if (mTouchCount == 0) {
     mApzcForInputBlock = nullptr;
-    mHitResultForInputBlock = NoApzcHit;
+    mHitResultForInputBlock = HitNothing;
     mRetainedTouchIdentifier = -1;
   }
 
   return result;
 }
 
 void
 APZCTreeManager::TransformCoordinateToGecko(const ScreenIntPoint& aPoint,
@@ -843,28 +843,28 @@ APZCTreeManager::ProcessEvent(WidgetInpu
                               ScrollableLayerGuid* aOutTargetGuid,
                               uint64_t* aOutInputBlockId)
 {
   MOZ_ASSERT(NS_IsMainThread());
   nsEventStatus result = nsEventStatus_eIgnore;
 
   // Transform the refPoint.
   // If the event hits an overscrolled APZC, instruct the caller to ignore it.
-  HitTestResult hitResult = NoApzcHit;
+  HitTestResult hitResult = HitNothing;
   nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(ScreenPoint(aEvent.refPoint.x, aEvent.refPoint.y),
                                                         &hitResult);
   if (apzc) {
-    MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
+    MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion);
     apzc->GetGuid(aOutTargetGuid);
     Matrix4x4 transformToApzc = GetScreenToApzcTransform(apzc);
     Matrix4x4 transformToGecko = GetApzcToGeckoTransform(apzc);
     Matrix4x4 outTransform = transformToApzc * transformToGecko;
     aEvent.refPoint = TransformTo<LayoutDevicePixel>(outTransform, aEvent.refPoint);
   }
-  if (hitResult == OverscrolledApzc) {
+  if (hitResult == HitOverscrolledApzc) {
     result = nsEventStatus_eConsumeNoDefault;
   }
   return result;
 }
 
 nsEventStatus
 APZCTreeManager::ProcessWheelEvent(WidgetWheelEvent& aEvent,
                                    ScrollableLayerGuid* aOutTargetGuid,
@@ -1210,23 +1210,23 @@ APZCTreeManager::GetTargetNode(const Scr
   nsRefPtr<HitTestingTreeNode> target = FindTargetNode(mRootNode, aGuid, aComparator);
   return target.forget();
 }
 
 already_AddRefed<AsyncPanZoomController>
 APZCTreeManager::GetTargetAPZC(const ScreenPoint& aPoint, HitTestResult* aOutHitResult)
 {
   MonitorAutoLock lock(mTreeLock);
-  HitTestResult hitResult = NoApzcHit;
+  HitTestResult hitResult = HitNothing;
   ParentLayerPoint point = ViewAs<ParentLayerPixel>(aPoint,
     PixelCastJustification::ScreenIsParentLayerForRoot);
   nsRefPtr<AsyncPanZoomController> target = GetAPZCAtPoint(mRootNode, point, &hitResult);
 
   // If we are in an overscrolled APZC, we should be returning nullptr.
-  MOZ_ASSERT(!(target && (hitResult == OverscrolledApzc)));
+  MOZ_ASSERT(!(target && (hitResult == HitOverscrolledApzc)));
   if (aOutHitResult) {
     *aOutHitResult = hitResult;
   }
   return target.forget();
 }
 
 static bool
 GuidComparatorIgnoringPresShell(const ScrollableLayerGuid& aOne, const ScrollableLayerGuid& aTwo)
@@ -1361,50 +1361,50 @@ APZCTreeManager::GetAPZCAtPoint(HitTesti
 
     // First check the subtree rooted at this node, because deeper nodes
     // are more "in front".
     Maybe<LayerPoint> hitTestPointForChildLayers = node->Untransform(aHitTestPoint);
     if (hitTestPointForChildLayers) {
       ParentLayerPoint childPoint = ViewAs<ParentLayerPixel>(hitTestPointForChildLayers.ref(),
         PixelCastJustification::MovingDownToChildren);
       result = GetAPZCAtPoint(node->GetLastChild(), childPoint, aOutHitResult);
-      if (*aOutHitResult == OverscrolledApzc) {
+      if (*aOutHitResult == HitOverscrolledApzc) {
         // We matched an overscrolled APZC, abort.
         return nullptr;
       }
     }
 
     // If we didn't match anything in the subtree, check |node|.
-    if (!result) {
+    if (*aOutHitResult == HitNothing) {
       APZCTM_LOG("Testing ParentLayer point %s (Layer %s) against node %p\n",
           Stringify(aHitTestPoint).c_str(),
           hitTestPointForChildLayers ? Stringify(hitTestPointForChildLayers.ref()).c_str() : "nil",
           node);
       HitTestResult hitResult = node->HitTest(aHitTestPoint);
-      if (hitResult != HitTestResult::NoApzcHit) {
+      if (hitResult != HitTestResult::HitNothing) {
         result = node->GetNearestContainingApzc();
         APZCTM_LOG("Successfully matched APZC %p via node %p (hit result %d)\n",
              result, node, hitResult);
-        MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
-        // If event regions are disabled, *aOutHitResult will be ApzcHitRegion
+        MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion);
+        // If event regions are disabled, *aOutHitResult will be HitLayer
         *aOutHitResult = hitResult;
       }
     }
 
     // If we are overscrolled, and the point matches us or one of our children,
     // the result is inside an overscrolled APZC, inform our caller of this
     // (callers typically ignore events targeted at overscrolled APZCs).
-    if (result && apzc && apzc->IsOverscrolled()) {
+    if (*aOutHitResult != HitNothing && apzc && apzc->IsOverscrolled()) {
       APZCTM_LOG("Result is inside overscrolled APZC %p\n", apzc);
-      *aOutHitResult = OverscrolledApzc;
+      *aOutHitResult = HitOverscrolledApzc;
       return nullptr;
     }
 
-    if (result) {
-      if (!gfxPrefs::LayoutEventRegionsEnabled()) {
+    if (*aOutHitResult != HitNothing) {
+      if (result && !gfxPrefs::LayoutEventRegionsEnabled()) {
         // When event-regions are disabled, we treat scrollinfo layers as
         // regular scrollable layers. Unfortunately, their "hit region" (which
         // we create from the composition bounds) is their full area, and they
         // sit on top of their non-scrollinfo siblings. This means they will get
         // a HitTestingTreeNode with a hit region that will aggressively match
         // any input events that might be directed to sub-APZCs of their non-
         // scrollinfo siblings. Therefore, we need to keep looping through to
         // see if there are any other non-scrollinfo siblings that have children
--- a/gfx/layers/apz/src/APZUtils.h
+++ b/gfx/layers/apz/src/APZUtils.h
@@ -6,18 +6,18 @@
 
 #ifndef mozilla_layers_APZUtils_h
 #define mozilla_layers_APZUtils_h
 
 namespace mozilla {
 namespace layers {
 
 enum HitTestResult {
-  NoApzcHit,
-  ApzcHitRegion,
-  ApzcContentRegion,
-  OverscrolledApzc,
+  HitNothing,
+  HitLayer,
+  HitDispatchToContentRegion,
+  HitOverscrolledApzc,
 };
 
 }
 }
 
 #endif // mozilla_layers_APZUtils_h
--- a/gfx/layers/apz/src/HitTestingTreeNode.cpp
+++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp
@@ -190,34 +190,34 @@ HitTestingTreeNode::HitTest(const Parent
   MOZ_ASSERT(!IsOutsideClip(aPoint));
 
   // When event regions are disabled and we have an APZC on this node, we are
   // actually storing the touch-sensitive section of the composition bounds in
   // the clip region, and we don't need to check against the mEventRegions.
   // If there's no APZC, then we do need to check against the mEventRegions
   // (which contains the layer's visible region) for obscuration purposes.
   if (!gfxPrefs::LayoutEventRegionsEnabled() && GetApzc()) {
-    return HitTestResult::ApzcHitRegion;
+    return HitTestResult::HitLayer;
   }
 
   // convert into Layer coordinate space
   Maybe<LayerPoint> pointInLayerPixels = Untransform(aPoint);
   if (!pointInLayerPixels) {
-    return HitTestResult::NoApzcHit;
+    return HitTestResult::HitNothing;
   }
   LayerIntPoint point = RoundedToInt(pointInLayerPixels.ref());
 
   // test against event regions in Layer coordinate space
   if (!mEventRegions.mHitRegion.Contains(point.x, point.y)) {
-    return HitTestResult::NoApzcHit;
+    return HitTestResult::HitNothing;
   }
   if (mEventRegions.mDispatchToContentHitRegion.Contains(point.x, point.y)) {
-    return HitTestResult::ApzcContentRegion;
+    return HitTestResult::HitDispatchToContentRegion;
   }
-  return HitTestResult::ApzcHitRegion;
+  return HitTestResult::HitLayer;
 }
 
 void
 HitTestingTreeNode::Dump(const char* aPrefix) const
 {
   if (mPrevSibling) {
     mPrevSibling->Dump(aPrefix);
   }
--- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp
@@ -2546,16 +2546,35 @@ protected:
     layers[1]->SetEventRegions(regions);
     regions.mHitRegion = nsIntRegion(nsIntRect(0, 100, 200, 100));
     layers[2]->SetEventRegions(regions);
 
     registration = MakeUnique<ScopedLayerTreeRegistration>(0, root, mcc);
     manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
     rootApzc = ApzcOf(root);
   }
+
+  void CreateBug1119497LayerTree() {
+    const char* layerTreeSyntax = "c(tt)";
+    // LayerID                     0 12
+    // 0 is the root and doesn't have an APZC
+    // 1 is behind 2 and does have an APZC
+    // 2 entirely covers 1 and should take all the input events
+    nsIntRegion layerVisibleRegions[] = {
+      nsIntRegion(nsIntRect(0, 0, 100, 100)),
+      nsIntRegion(nsIntRect(0, 0, 100, 100)),
+      nsIntRegion(nsIntRect(0, 0, 100, 100)),
+    };
+    root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, nullptr, lm, layers);
+
+    SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1);
+
+    registration = MakeUnique<ScopedLayerTreeRegistration>(0, root, mcc);
+    manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
+  }
 };
 
 TEST_F(APZEventRegionsTester, HitRegionImmediateResponse) {
   SCOPED_GFX_PREF(LayoutEventRegionsEnabled, bool, true);
 
   CreateEventRegionsLayerTree1();
 
   TestAsyncPanZoomController* root = ApzcOf(layers[0]);
@@ -2635,17 +2654,30 @@ TEST_F(APZEventRegionsTester, Obscuratio
   TestAsyncPanZoomController* child = ApzcOf(layers[2]);
 
   int time = 0;
   ApzcPanNoFling(parent, time, 75, 25);
 
   HitTestResult result;
   nsRefPtr<AsyncPanZoomController> hit = manager->GetTargetAPZC(ScreenPoint(50, 75), &result);
   EXPECT_EQ(child, hit.get());
-  EXPECT_EQ(HitTestResult::ApzcHitRegion, result);
+  EXPECT_EQ(HitTestResult::HitLayer, result);
+}
+
+TEST_F(APZEventRegionsTester, Bug1119497) {
+  SCOPED_GFX_PREF(LayoutEventRegionsEnabled, bool, true);
+
+  CreateBug1119497LayerTree();
+
+  HitTestResult result;
+  nsRefPtr<AsyncPanZoomController> hit = manager->GetTargetAPZC(ScreenPoint(50, 50), &result);
+  // We should hit layers[2], so |result| will be HitLayer but there's no
+  // actual APZC in that parent chain, so |hit| should be nullptr.
+  EXPECT_EQ(nullptr, hit.get());
+  EXPECT_EQ(HitTestResult::HitLayer, result);
 }
 
 class TaskRunMetrics {
 public:
   TaskRunMetrics()
     : mRunCount(0)
     , mCancelCount(0)
   {}
--- a/widget/InputData.cpp
+++ b/widget/InputData.cpp
@@ -110,16 +110,58 @@ MultiTouchInput::ToWidgetTouchEvent(nsIW
 
   for (size_t i = 0; i < mTouches.Length(); i++) {
     *event.touches.AppendElement() = mTouches[i].ToNewDOMTouch();
   }
 
   return event;
 }
 
+WidgetMouseEvent
+MultiTouchInput::ToWidgetMouseEvent(nsIWidget* aWidget) const
+{
+  NS_ABORT_IF_FALSE(NS_IsMainThread(),
+                    "Can only convert To WidgetMouseEvent on main thread");
+
+  uint32_t mouseEventType = NS_EVENT_NULL;
+  switch (mType) {
+    case MultiTouchInput::MULTITOUCH_START:
+      mouseEventType = NS_MOUSE_BUTTON_DOWN;
+      break;
+    case MultiTouchInput::MULTITOUCH_MOVE:
+      mouseEventType = NS_MOUSE_MOVE;
+      break;
+    case MultiTouchInput::MULTITOUCH_CANCEL:
+    case MultiTouchInput::MULTITOUCH_END:
+      mouseEventType = NS_MOUSE_BUTTON_UP;
+      break;
+    default:
+      MOZ_ASSERT_UNREACHABLE("Did not assign a type to WidgetMouseEvent");
+      break;
+  }
+
+  WidgetMouseEvent event(true, mouseEventType, aWidget,
+                         WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
+
+  const SingleTouchData& firstTouch = mTouches[0];
+  event.refPoint.x = firstTouch.mScreenPoint.x;
+  event.refPoint.y = firstTouch.mScreenPoint.y;
+
+  event.time = mTime;
+  event.button = WidgetMouseEvent::eLeftButton;
+  event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
+  event.modifiers = modifiers;
+
+  if (mouseEventType != NS_MOUSE_MOVE) {
+    event.clickCount = 1;
+  }
+
+  return event;
+}
+
 // This conversion from WidgetMouseEvent to MultiTouchInput is needed because on
 // the B2G emulator we can only receive mouse events, but we need to be able
 // to pan correctly. To do this, we convert the events into a format that the
 // panning code can handle. This code is very limited and only supports
 // SingleTouchData. It also sends garbage for the identifier, radius, force
 // and rotation angle.
 MultiTouchInput::MultiTouchInput(const WidgetMouseEvent& aMouseEvent)
   : InputData(MULTITOUCH_INPUT, aMouseEvent.time, aMouseEvent.timeStamp,
--- a/widget/InputData.h
+++ b/widget/InputData.h
@@ -211,16 +211,17 @@ public:
                 aOther.mTimeStamp, aOther.modifiers)
     , mType(aOther.mType)
   {
     mTouches.AppendElements(aOther.mTouches);
   }
 
   explicit MultiTouchInput(const WidgetTouchEvent& aTouchEvent);
   WidgetTouchEvent ToWidgetTouchEvent(nsIWidget* aWidget) const;
+  WidgetMouseEvent ToWidgetMouseEvent(nsIWidget* aWidget) const;
 
   // This conversion from WidgetMouseEvent to MultiTouchInput is needed because
   // on the B2G emulator we can only receive mouse events, but we need to be
   // able to pan correctly. To do this, we convert the events into a format that
   // the panning code can handle. This code is very limited and only supports
   // SingleTouchData. It also sends garbage for the identifier, radius, force
   // and rotation angle.
   explicit MultiTouchInput(const WidgetMouseEvent& aMouseEvent);
--- a/widget/NativeKeyToDOMKeyName.h
+++ b/widget/NativeKeyToDOMKeyName.h
@@ -1284,16 +1284,23 @@ KEY_MAP_ANDROID (TVPower, AKEYCODE_TV_PO
 
 // VideoModeNext
 KEY_MAP_GTK     (VideoModeNext, GDK_Next_VMode)
 
 // ZoomToggle
 KEY_MAP_WIN     (ZoomToggle, VK_ZOOM)
 KEY_MAP_QT      (ZoomToggle, Qt::Key_Zoom)
 
+/******************************************************************************
+ * Keys not defined by any standards
+ ******************************************************************************/
+
+// HomeScreen
+KEY_MAP_ANDROID (HomeScreen, AKEYCODE_HOME)
+
 #undef KEY_MAP_WIN
 #undef KEY_MAP_WIN_JPN
 #undef KEY_MAP_WIN_KOR
 #undef KEY_MAP_WIN_OTH
 #undef KEY_MAP_WIN_CMD
 #undef KEY_MAP_COCOA
 #undef KEY_MAP_GTK
 #undef KEY_MAP_QT
--- a/widget/gonk/GeckoTouchDispatcher.cpp
+++ b/widget/gonk/GeckoTouchDispatcher.cpp
@@ -19,17 +19,16 @@
 #include "GeckoProfiler.h"
 #include "GeckoTouchDispatcher.h"
 #include "InputData.h"
 #include "ProfilerMarkers.h"
 #include "base/basictypes.h"
 #include "gfxPrefs.h"
 #include "libui/Input.h"
 #include "mozilla/ClearOnShutdown.h"
-#include "mozilla/MouseEvents.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/TouchEvents.h"
 #include "mozilla/dom/Touch.h"
 #include "mozilla/layers/CompositorParent.h"
 #include "nsAppShell.h"
 #include "nsDebug.h"
 #include "nsThreadUtils.h"
@@ -328,31 +327,16 @@ GeckoTouchDispatcher::ResampleTouchMoves
 
   // Both mTimeStamp and mTime are being updated to sampleTime here.
   // mTime needs to be updated using a delta since TimeStamp doesn't
   // provide a way to obtain a raw value.
   aOutTouch.mTime += (sampleTime - aOutTouch.mTimeStamp).ToMilliseconds();
   aOutTouch.mTimeStamp = sampleTime;
 }
 
-// Some touch events get sent as mouse events. If APZ doesn't capture the event
-// and if a touch only has 1 touch input, we can send a mouse event.
-void
-GeckoTouchDispatcher::DispatchMouseEvent(MultiTouchInput& aMultiTouch,
-                                         bool aForwardToChildren)
-{
-  WidgetMouseEvent mouseEvent = ToWidgetMouseEvent(aMultiTouch, nullptr);
-  if (mouseEvent.message == NS_EVENT_NULL) {
-    return;
-  }
-
-  mouseEvent.mFlags.mNoCrossProcessBoundaryForwarding = !aForwardToChildren;
-  nsWindow::DispatchInputEvent(mouseEvent);
-}
-
 static bool
 IsExpired(const MultiTouchInput& aTouch)
 {
   // No pending events, the filter state can be updated.
   uint64_t timeNowMs = systemTime(SYSTEM_TIME_MONOTONIC) / 1000000;
   return (timeNowMs - aTouch.mTime) > kInputExpirationThresholdMs;
 }
 void
@@ -367,19 +351,17 @@ GeckoTouchDispatcher::DispatchTouchEvent
              aMultiTouch.mTouches.Length() == 1) {
     mTouchEventsFiltered = IsExpired(aMultiTouch);
   }
 
   if (mTouchEventsFiltered) {
     return;
   }
 
-  bool captured = false;
-  WidgetTouchEvent event = aMultiTouch.ToWidgetTouchEvent(nullptr);
-  nsEventStatus status = nsWindow::DispatchInputEvent(event, &captured);
+  nsWindow::DispatchTouchInput(aMultiTouch);
 
   if (mEnabledUniformityInfo && profiler_is_active()) {
     const char* touchAction = "Invalid";
     switch (aMultiTouch.mType) {
       case MultiTouchInput::MULTITOUCH_START:
         touchAction = "Touch_Event_Down";
         break;
       case MultiTouchInput::MULTITOUCH_MOVE:
@@ -390,59 +372,11 @@ GeckoTouchDispatcher::DispatchTouchEvent
         touchAction = "Touch_Event_Up";
         break;
     }
 
     const ScreenIntPoint& touchPoint = aMultiTouch.mTouches[0].mScreenPoint;
     TouchDataPayload* payload = new TouchDataPayload(touchPoint);
     PROFILER_MARKER_PAYLOAD(touchAction, payload);
   }
-
-  if (!captured && (aMultiTouch.mTouches.Length() == 1)) {
-    bool forwardToChildren = status != nsEventStatus_eConsumeNoDefault;
-    DispatchMouseEvent(aMultiTouch, forwardToChildren);
-  }
-}
-
-WidgetMouseEvent
-GeckoTouchDispatcher::ToWidgetMouseEvent(const MultiTouchInput& aMultiTouch,
-                                         nsIWidget* aWidget) const
-{
-  NS_ABORT_IF_FALSE(NS_IsMainThread(),
-                    "Can only convert To WidgetMouseEvent on main thread");
-
-  uint32_t mouseEventType = NS_EVENT_NULL;
-  switch (aMultiTouch.mType) {
-    case MultiTouchInput::MULTITOUCH_START:
-      mouseEventType = NS_MOUSE_BUTTON_DOWN;
-      break;
-    case MultiTouchInput::MULTITOUCH_MOVE:
-      mouseEventType = NS_MOUSE_MOVE;
-      break;
-    case MultiTouchInput::MULTITOUCH_CANCEL:
-    case MultiTouchInput::MULTITOUCH_END:
-      mouseEventType = NS_MOUSE_BUTTON_UP;
-      break;
-    default:
-      MOZ_ASSERT_UNREACHABLE("Did not assign a type to WidgetMouseEvent");
-      break;
-  }
-
-  WidgetMouseEvent event(true, mouseEventType, aWidget,
-                         WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
-
-  const SingleTouchData& firstTouch = aMultiTouch.mTouches[0];
-  event.refPoint.x = firstTouch.mScreenPoint.x;
-  event.refPoint.y = firstTouch.mScreenPoint.y;
-
-  event.time = aMultiTouch.mTime;
-  event.button = WidgetMouseEvent::eLeftButton;
-  event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
-  event.modifiers = aMultiTouch.modifiers;
-
-  if (mouseEventType != NS_MOUSE_MOVE) {
-    event.clickCount = 1;
-  }
-
-  return event;
 }
 
 } // namespace mozilla
--- a/widget/gonk/GeckoTouchDispatcher.h
+++ b/widget/gonk/GeckoTouchDispatcher.h
@@ -55,17 +55,16 @@ public:
   static bool NotifyVsync(TimeStamp aVsyncTimestamp);
   static void SetCompositorVsyncObserver(layers::CompositorVsyncObserver* aObserver);
 
 private:
   void ResampleTouchMoves(MultiTouchInput& aOutTouch, TimeStamp vsyncTime);
   void SendTouchEvent(MultiTouchInput& aData);
   void DispatchMouseEvent(MultiTouchInput& aMultiTouch,
                           bool aForwardToChildren);
-  WidgetMouseEvent ToWidgetMouseEvent(const MultiTouchInput& aData, nsIWidget* aWidget) const;
 
   // mTouchQueueLock are used to protect the vector below
   // as it is accessed on the vsync thread and main thread
   Mutex mTouchQueueLock;
   std::vector<MultiTouchInput> mTouchMoveEvents;
 
   bool mResamplingEnabled;
   bool mTouchEventsFiltered;
--- a/widget/gonk/nsWindow.cpp
+++ b/widget/gonk/nsWindow.cpp
@@ -42,16 +42,19 @@
 #include "ClientLayerManager.h"
 #include "BasicLayers.h"
 #include "libdisplay/GonkDisplay.h"
 #include "pixelflinger/format.h"
 #include "mozilla/BasicEvents.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/layers/APZCTreeManager.h"
 #include "mozilla/layers/CompositorParent.h"
+#include "mozilla/layers/InputAPZContext.h"
+#include "mozilla/MouseEvents.h"
+#include "mozilla/TouchEvents.h"
 #include "nsThreadUtils.h"
 #include "HwcComposer2D.h"
 
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
 #define LOGW(args...) __android_log_print(ANDROID_LOG_WARN, "Gonk", ## args)
 #define LOGE(args...) __android_log_print(ANDROID_LOG_ERROR, "Gonk", ## args)
 
 #define IS_TOPLEVEL() (mWindowType == eWindowType_toplevel || mWindowType == eWindowType_dialog)
@@ -222,43 +225,99 @@ nsWindow::NotifyVsync(TimeStamp aVsyncTi
     CompositorVsyncDispatcher* vsyncDispatcher = gFocusedWindow->GetCompositorVsyncDispatcher();
     // During bootup, there is a delay between when the nsWindow is created
     // and when the Compositor is created, but vsync is already turned on
     if (vsyncDispatcher) {
       vsyncDispatcher->NotifyVsync(aVsyncTimestamp);
     }
 }
 
-nsEventStatus
-nsWindow::DispatchInputEvent(WidgetGUIEvent& aEvent, bool* aWasCaptured)
+/*static*/ nsEventStatus
+nsWindow::DispatchInputEvent(WidgetGUIEvent& aEvent)
 {
-    if (aWasCaptured) {
-        *aWasCaptured = false;
-    }
     if (!gFocusedWindow) {
         return nsEventStatus_eIgnore;
     }
 
     gFocusedWindow->UserActivity();
 
+    nsEventStatus status;
     aEvent.widget = gFocusedWindow;
+    gFocusedWindow->DispatchEvent(&aEvent, status);
+    return status;
+}
 
+/*static*/ void
+nsWindow::DispatchTouchInput(MultiTouchInput& aInput)
+{
+    if (!gFocusedWindow) {
+        return;
+    }
+
+    gFocusedWindow->UserActivity();
+    gFocusedWindow->DispatchTouchInputViaAPZ(aInput);
+}
+
+void
+nsWindow::DispatchTouchInputViaAPZ(MultiTouchInput& aInput)
+{
+    if (!mAPZC) {
+        // In general mAPZC should not be null, but during initial setup
+        // it might be, so we handle that case by ignoring touch input there.
+        return;
+    }
+
+    // First send it through the APZ code
+    mozilla::layers::ScrollableLayerGuid guid;
+    uint64_t inputBlockId;
+    nsEventStatus rv = mAPZC->ReceiveInputEvent(aInput, &guid, &inputBlockId);
+    // If the APZ says to drop it, then we drop it
+    if (rv == nsEventStatus_eConsumeNoDefault) {
+        return;
+    }
+
+    // Convert it to an event we can send to Gecko
+    WidgetTouchEvent event = aInput.ToWidgetTouchEvent(this);
+
+    // If there is an event capturing child process, send it directly there.
+    // This happens if we already sent a touchstart event through the root
+    // process hit test and it ended up going to a child process. The event
+    // capturing process should get all subsequent touch events in the same
+    // event block. In this case the TryCapture call below will return true,
+    // and the child process will take care of responding to the event as needed
+    // so we don't need to do anything else here.
     if (TabParent* capturer = TabParent::GetEventCapturer()) {
-        bool captured = capturer->TryCapture(aEvent);
-        if (aWasCaptured) {
-            *aWasCaptured = captured;
-        }
-        if (captured) {
-            return nsEventStatus_eConsumeNoDefault;
+        InputAPZContext context(guid, inputBlockId);
+        if (capturer->TryCapture(event)) {
+            return;
         }
     }
 
-    nsEventStatus status;
-    gFocusedWindow->DispatchEvent(&aEvent, status);
-    return status;
+    // If it didn't get captured, dispatch the event into the gecko root process
+    // for "normal" flow. The event might get sent to the child process still,
+    // but if it doesn't we need to notify the APZ of various things. All of
+    // that happens in DispatchEventForAPZ
+    rv = DispatchEventForAPZ(&event, guid, inputBlockId);
+
+    // Finally, if the touch event had only one touch point, generate a mouse
+    // event for it and send it through the gecko root process.
+    // Technically we should not need to do this if the touch event was routed
+    // to the child process, but that seems to expose a bug in B2G where the
+    // keyboard doesn't go away in some cases.
+    // Also for now we're dispatching mouse events from all touch events because
+    // we need this for click events to work in the chrome process. Once we have
+    // APZ and ChromeProcessController::HandleSingleTap working for the chrome
+    // process we shouldn't need to do this at all.
+    if (event.touches.Length() == 1) {
+        WidgetMouseEvent mouseEvent = aInput.ToWidgetMouseEvent(this);
+        if (mouseEvent.message != NS_EVENT_NULL) {
+            mouseEvent.mFlags.mNoCrossProcessBoundaryForwarding = (rv == nsEventStatus_eConsumeNoDefault);
+            DispatchEvent(&mouseEvent, rv);
+        }
+    }
 }
 
 NS_IMETHODIMP
 nsWindow::Create(nsIWidget *aParent,
                  void *aNativeParent,
                  const nsIntRect &aRect,
                  nsDeviceContext *aContext,
                  nsWidgetInitData *aInitData)
--- a/widget/gonk/nsWindow.h
+++ b/widget/gonk/nsWindow.h
@@ -11,16 +11,17 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 #ifndef nsWindow_h
 #define nsWindow_h
 
+#include "InputData.h"
 #include "nsBaseWidget.h"
 #include "nsRegion.h"
 #include "nsIIdleServiceInternal.h"
 #include "Units.h"
 
 extern nsIntRect gScreenBounds;
 
 namespace mozilla {
@@ -46,18 +47,18 @@ struct InputContextAction;
 class nsWindow : public nsBaseWidget
 {
 public:
     nsWindow();
     virtual ~nsWindow();
 
     static void NotifyVsync(mozilla::TimeStamp aVsyncTimestamp);
     static void DoDraw(void);
-    static nsEventStatus DispatchInputEvent(mozilla::WidgetGUIEvent& aEvent,
-                                            bool* aWasCaptured = nullptr);
+    static nsEventStatus DispatchInputEvent(mozilla::WidgetGUIEvent& aEvent);
+    static void DispatchTouchInput(mozilla::MultiTouchInput& aInput);
 
     NS_IMETHOD Create(nsIWidget *aParent,
                       void *aNativeParent,
                       const nsIntRect &aRect,
                       nsDeviceContext *aContext,
                       nsWidgetInitData *aInitData);
     NS_IMETHOD Destroy(void);
 
@@ -82,16 +83,17 @@ public:
     NS_IMETHOD ConfigureChildren(const nsTArray<nsIWidget::Configuration>&);
     NS_IMETHOD Invalidate(const nsIntRect &aRect);
     virtual void* GetNativeData(uint32_t aDataType);
     NS_IMETHOD SetTitle(const nsAString& aTitle)
     {
         return NS_OK;
     }
     virtual nsIntPoint WidgetToScreenOffset();
+    void DispatchTouchInputViaAPZ(mozilla::MultiTouchInput& aInput);
     NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
                              nsEventStatus& aStatus);
     NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener,
                                    bool aDoCapture)
     {
         return NS_ERROR_NOT_IMPLEMENTED;
     }
     NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent);