Merge b2ginbound to m-c a=merge CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Thu, 07 May 2015 15:23:42 -0700
changeset 274169 5e02da1141d24cb2bd35e64df6bc9ee767fc9693
parent 274150 70a21ed63d188fb70a812e3095bef2750bbdd8f9 (current diff)
parent 274168 e9f75be97c2d359072b740f4d3aac22461f783a3 (diff)
child 274170 c50a3514dd867be190feb8e2cbc196781d3ecc18
child 274251 fa8214db7c8218aae36818821a0e5fba9bc8f5dc
child 274318 b9d40b34df465e4ee068476310c8ce8428509235
child 274350 fd962b9ed5705fdaf618a3f4a24d02580548c771
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone40.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 b2ginbound to m-c a=merge CLOSED TREE
--- 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="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="83b27f522642ea573c57e882657ab5c73d4b07f4"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bc5bfa18f795919b56b952bbf3637c235d0e13dc"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>
@@ -129,16 +129,16 @@
   <project name="platform/external/icu4c" path="external/icu4c" revision="2bb01561780583cc37bc667f0ea79f48a122d8a2"/>
   <!-- dolphin specific things -->
   <project name="device/sprd" path="device/sprd" revision="a26ba0ab998133ad590102be1e5950818b86ce82"/>
   <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="39a5b5bcadad745df3e6882316fce426f98b1669"/>
   <project name="platform/frameworks/av" path="frameworks/av" revision="8bb69db127112fc66da75f8ca7a1158614b919f6"/>
   <project name="platform/hardware/akm" path="hardware/akm" revision="6d3be412647b0eab0adff8a2768736cf4eb68039"/>
   <project groups="invensense" name="platform/hardware/invensense" path="hardware/invensense" revision="e6d9ab28b4f4e7684f6c07874ee819c9ea0002a2"/>
   <project name="platform/hardware/ril" path="hardware/ril" revision="865ce3b4a2ba0b3a31421ca671f4d6c5595f8690"/>
-  <project name="kernel/common" path="kernel" revision="a2977758950865feb5980996d8e889677dea3bd4"/>
+  <project name="kernel/common" path="kernel" revision="8696b132455224412a6725022acf672be80a0641"/>
   <project name="platform/system/core" path="system/core" revision="7992618bd4ee33ce96897675a5c0a9b619122f13"/>
   <project name="u-boot" path="u-boot" revision="f1502910977ac88f43da7bf9277c3523ad4b0b2f"/>
   <project name="vendor/sprd/gps" path="vendor/sprd/gps" revision="7d6e1269be7186b2073fa568958b357826692c4b"/>
   <project name="vendor/sprd/open-source" path="vendor/sprd/open-source" revision="e503b1d14d7fdee532b8f391407299da193c1b2d"/>
   <project name="vendor/sprd/partner" path="vendor/sprd/partner" revision="8649c7145972251af11b0639997edfecabfc7c2e"/>
   <project name="vendor/sprd/proprietories" path="vendor/sprd/proprietories" revision="d2466593022f7078aaaf69026adf3367c2adb7bb"/>
 </manifest>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="83b27f522642ea573c57e882657ab5c73d4b07f4"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bc5bfa18f795919b56b952bbf3637c235d0e13dc"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="8c2d32bccc7061e9ca0165135457c3fd53e7107e"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="83b27f522642ea573c57e882657ab5c73d4b07f4"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bc5bfa18f795919b56b952bbf3637c235d0e13dc"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>
   <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="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="83b27f522642ea573c57e882657ab5c73d4b07f4"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bc5bfa18f795919b56b952bbf3637c235d0e13dc"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>
--- 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="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="83b27f522642ea573c57e882657ab5c73d4b07f4"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bc5bfa18f795919b56b952bbf3637c235d0e13dc"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="83b27f522642ea573c57e882657ab5c73d4b07f4"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bc5bfa18f795919b56b952bbf3637c235d0e13dc"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="8c2d32bccc7061e9ca0165135457c3fd53e7107e"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
   <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="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="83b27f522642ea573c57e882657ab5c73d4b07f4"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bc5bfa18f795919b56b952bbf3637c235d0e13dc"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="83b27f522642ea573c57e882657ab5c73d4b07f4"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bc5bfa18f795919b56b952bbf3637c235d0e13dc"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>
   <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": "83b27f522642ea573c57e882657ab5c73d4b07f4", 
+        "git_revision": "bc5bfa18f795919b56b952bbf3637c235d0e13dc", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "6f889f462ec6387626570bab40a0f032a205edf6", 
+    "revision": "12e33f70aeccca27a275b3fa172876a07b891fe8", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="83b27f522642ea573c57e882657ab5c73d4b07f4"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bc5bfa18f795919b56b952bbf3637c235d0e13dc"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="83b27f522642ea573c57e882657ab5c73d4b07f4"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bc5bfa18f795919b56b952bbf3637c235d0e13dc"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>
--- a/dom/system/gonk/NetworkManager.js
+++ b/dom/system/gonk/NetworkManager.js
@@ -80,16 +80,56 @@ updateDebug();
 
 function defineLazyRegExp(obj, name, pattern) {
   obj.__defineGetter__(name, function() {
     delete obj[name];
     return obj[name] = new RegExp(pattern);
   });
 }
 
+function NetworkInterface(aNetwork) {
+  let ips = {};
+  let prefixLengths = {};
+  aNetwork.getAddresses(ips, prefixLengths);
+
+  this.state = aNetwork.state;
+  this.type = aNetwork.type;
+  this.name = aNetwork.name;
+  this.ips = ips.value;
+  this.prefixLengths = prefixLengths.value;
+  this.gateways = aNetwork.getGateways();
+  this.dnses = aNetwork.getDnses();
+  this.httpProxyHost = aNetwork.httpProxyHost;
+  this.httpProxyPort = aNetwork.httpProxyPort;
+}
+NetworkInterface.prototype = {
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface]),
+
+  getAddresses: function(aIps, aPrefixLengths) {
+    aIps.value = this.ips.slice();
+    aPrefixLengths.value = this.prefixLengths.slice();
+
+    return this.ips.length;
+  },
+
+  getGateways: function(aCount) {
+    if (aCount) {
+      aCount.value = this.gateways.length;
+    }
+    return this.gateways.slice();
+  },
+
+  getDnses: function(aCount) {
+    if (aCount) {
+      aCount.value = this.dnses.length;
+    }
+    return this.dnses.slice();
+  }
+};
+
 function NetworkInterfaceLinks()
 {
   this.resetLinks();
 }
 NetworkInterfaceLinks.prototype = {
   linkRoutes: null,
   gateways: null,
   interfaceName: null,
@@ -249,134 +289,170 @@ NetworkManager.prototype = {
     Services.obs.notifyObservers(network, TOPIC_INTERFACE_REGISTERED, null);
     debug("Network '" + networkId + "' registered.");
   },
 
   _addSubnetRoutes: function(network) {
     let ips = {};
     let prefixLengths = {};
     let length = network.getAddresses(ips, prefixLengths);
+    let promises = [];
+
     for (let i = 0; i < length; i++) {
       debug('Adding subnet routes: ' + ips.value[i] + '/' + prefixLengths.value[i]);
-      gNetworkService.modifyRoute(Ci.nsINetworkService.MODIFY_ROUTE_ADD,
-                                  network.name, ips.value[i], prefixLengths.value[i])
-        .catch((aError) => {
+      promises.push(
+        gNetworkService.modifyRoute(Ci.nsINetworkService.MODIFY_ROUTE_ADD,
+                                    network.name, ips.value[i], prefixLengths.value[i])
+        .catch(aError => {
           debug("_addSubnetRoutes error: " + aError);
-        });
+        }));
     }
+
+    return Promise.all(promises);
   },
 
   updateNetworkInterface: function(network) {
     if (!(network instanceof Ci.nsINetworkInterface)) {
       throw Components.Exception("Argument must be nsINetworkInterface.",
                                  Cr.NS_ERROR_INVALID_ARG);
     }
     let networkId = this.getNetworkId(network);
     if (!(networkId in this.networkInterfaces)) {
       throw Components.Exception("No network with that type registered.",
                                  Cr.NS_ERROR_INVALID_ARG);
     }
     debug("Network " + network.type + "/" + network.name +
           " changed state to " + network.state);
 
+    // Keep a copy of network in case it is modified while we are updating.
+    let networkInterface = new NetworkInterface(network);
+
     // Note that since Lollipop we need to allocate and initialize
     // something through netd, so we add createNetwork/destroyNetwork
     // to deal with that explicitly.
 
-    switch (network.state) {
+    switch (networkInterface.state) {
       case Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED:
-        gNetworkService.createNetwork(network.name, () => {
 
+        this._createNetwork(networkInterface.name)
           // Remove pre-created default route and let setAndConfigureActive()
           // to set default route only on preferred network
-          gNetworkService.removeDefaultRoute(network);
-
+          .then(() => this._removeDefaultRoute(networkInterface))
           // Set DNS server as early as possible to prevent from
           // premature domain name lookup.
-          gNetworkService.setDNS(network, () => {
+          .then(() => this._setDNS(networkInterface))
+          .then(() => {
             // Add host route for data calls
-            if (this.isNetworkTypeMobile(network.type)) {
-              let currentInterfaceLinks = this.networkInterfaceLinks[networkId];
-              let newLinkRoutes = network.getDnses().concat(network.httpProxyHost);
-              // If gateways have changed, remove all old routes first.
-              this._handleGateways(networkId, network.getGateways())
-                .then(() => this._updateRoutes(currentInterfaceLinks.linkRoutes,
-                                               newLinkRoutes,
-                                               network.getGateways(), network.name))
-                .then(() => currentInterfaceLinks.setLinks(newLinkRoutes,
-                                                           network.getGateways(),
-                                                           network.name));
+            if (!this.isNetworkTypeMobile(networkInterface.type)) {
+              return;
             }
 
+            let currentInterfaceLinks = this.networkInterfaceLinks[networkId];
+            let newLinkRoutes = networkInterface.getDnses().concat(
+              networkInterface.httpProxyHost);
+            // If gateways have changed, remove all old routes first.
+            return this._handleGateways(networkId, networkInterface.getGateways())
+              .then(() => this._updateRoutes(currentInterfaceLinks.linkRoutes,
+                                             newLinkRoutes,
+                                             networkInterface.getGateways(),
+                                             networkInterface.name))
+              .then(() => currentInterfaceLinks.setLinks(newLinkRoutes,
+                                                         networkInterface.getGateways(),
+                                                         networkInterface.name));
+          })
+          .then(() => {
+            if (networkInterface.type !=
+                Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
+              return;
+            }
             // Dun type is a special case where we add the default route to a
             // secondary table.
-            if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
-              this.setSecondaryDefaultRoute(network);
-            }
-
-            this._addSubnetRoutes(network);
-            this.setAndConfigureActive();
-
+            return this.setSecondaryDefaultRoute(networkInterface);
+          })
+          .then(() => this._addSubnetRoutes(networkInterface))
+          .then(() => this.setAndConfigureActive())
+          .then(() => {
             // Update data connection when Wifi connected/disconnected
-            if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI && this.mRil) {
+            if (networkInterface.type ==
+                Ci.nsINetworkInterface.NETWORK_TYPE_WIFI && this.mRil) {
               for (let i = 0; i < this.mRil.numRadioInterfaces; i++) {
                 this.mRil.getRadioInterface(i).updateRILNetworkInterface();
               }
             }
 
             // Probing the public network accessibility after routing table is ready
             CaptivePortalDetectionHelper
               .notify(CaptivePortalDetectionHelper.EVENT_CONNECT, this.active);
-
+          })
+          .then(() => {
             // Notify outer modules like MmsService to start the transaction after
             // the configuration of the network interface is done.
             Services.obs.notifyObservers(network, TOPIC_CONNECTION_STATE_CHANGED,
                                          this.convertConnectionType(network));
+          })
+          .catch(aError => {
+            debug("updateNetworkInterface error: " + aError);
           });
-        });
-
         break;
       case Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED:
-        // Remove host route for data calls
-        if (this.isNetworkTypeMobile(network.type)) {
-          this._cleanupAllHostRoutes(networkId);
-        }
-        // Remove secondary default route for dun.
-        if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
-          this.removeSecondaryDefaultRoute(network);
-        }
-        // Remove routing table in /proc/net/route
-        if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
-          gNetworkService.resetRoutingTable(network);
-        } else if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE) {
-          gNetworkService.removeDefaultRoute(network);
-        }
-        // Clear http proxy on active network.
-        if (this.active && network.type == this.active.type) {
-          this.clearNetworkProxy();
-        }
+        Promise.resolve()
+          .then(() => {
+            if (!this.isNetworkTypeMobile(networkInterface.type)) {
+              return;
+            }
+            // Remove host route for data calls
+            return this._cleanupAllHostRoutes(networkId);
+          })
+          .then(() => {
+            if (networkInterface.type !=
+                Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
+              return;
+            }
+            // Remove secondary default route for dun.
+            return this.removeSecondaryDefaultRoute(networkInterface);
+          })
+          .then(() => {
+            if (networkInterface.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
+              // Remove routing table in /proc/net/route
+              return this._resetRoutingTable(networkInterface);
+            }
+            if (networkInterface.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE) {
+              return this._removeDefaultRoute(networkInterface)
+            }
+          })
+          .then(() => {
+            // Clear http proxy on active network.
+            if (this.active && networkInterface.type == this.active.type) {
+              this.clearNetworkProxy();
+            }
 
-        // Abort ongoing captive portal detection on the wifi interface
-        CaptivePortalDetectionHelper
-          .notify(CaptivePortalDetectionHelper.EVENT_DISCONNECT, network);
-        this.setAndConfigureActive();
-
-        // Update data connection when Wifi connected/disconnected
-        if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI && this.mRil) {
-          for (let i = 0; i < this.mRil.numRadioInterfaces; i++) {
-            this.mRil.getRadioInterface(i).updateRILNetworkInterface();
-          }
-        }
-
-        gNetworkService.destroyNetwork(network.name, () => {
-          // Notify outer modules like MmsService to start the transaction after
-          // the configuration of the network interface is done.
-          Services.obs.notifyObservers(network, TOPIC_CONNECTION_STATE_CHANGED,
-                                       this.convertConnectionType(network));
-        });
+            // Abort ongoing captive portal detection on the wifi interface
+            CaptivePortalDetectionHelper
+              .notify(CaptivePortalDetectionHelper.EVENT_DISCONNECT, networkInterface);
+          })
+          .then(() => this.setAndConfigureActive())
+          .then(() => {
+            // Update data connection when Wifi connected/disconnected
+            if (networkInterface.type ==
+                Ci.nsINetworkInterface.NETWORK_TYPE_WIFI && this.mRil) {
+              for (let i = 0; i < this.mRil.numRadioInterfaces; i++) {
+                this.mRil.getRadioInterface(i).updateRILNetworkInterface();
+              }
+            }
+          })
+          .then(() => this._destroyNetwork(networkInterface.name))
+          .then(() => {
+            // Notify outer modules like MmsService to start the transaction after
+            // the configuration of the network interface is done.
+            Services.obs.notifyObservers(network, TOPIC_CONNECTION_STATE_CHANGED,
+                                         this.convertConnectionType(network));
+          })
+          .catch(aError => {
+            debug("updateNetworkInterface error: " + aError);
+          });
         break;
     }
   },
 
   unregisterNetworkInterface: function(network) {
     if (!(network instanceof Ci.nsINetworkInterface)) {
       throw Components.Exception("Argument must be nsINetworkInterface.",
                                  Cr.NS_ERROR_INVALID_ARG);
@@ -594,55 +670,96 @@ NetworkManager.prototype = {
       if (gateway.match(this.REGEXP_IPV4) && host.match(this.REGEXP_IPV4) ||
           gateway.indexOf(":") != -1 && host.indexOf(":") != -1) {
         return gateway;
       }
     }
     return null;
   },
 
+  _setSecondaryRoute: function(aDoAdd, aInterfaceName, aRoute) {
+    return new Promise((aResolve, aReject) => {
+      if (aDoAdd) {
+        gNetworkService.addSecondaryRoute(aInterfaceName, aRoute,
+          (aSuccess) => {
+            if (!aSuccess) {
+              aReject("addSecondaryRoute failed");
+              return;
+            }
+            aResolve();
+        });
+      } else {
+        gNetworkService.removeSecondaryRoute(aInterfaceName, aRoute,
+          (aSuccess) => {
+            if (!aSuccess) {
+              debug("removeSecondaryRoute failed")
+            }
+            // Always resolve.
+            aResolve();
+        });
+      }
+    });
+  },
+
   setSecondaryDefaultRoute: function(network) {
     let gateways = network.getGateways();
+    let promises = [];
+
     for (let i = 0; i < gateways.length; i++) {
       let isIPv6 = (gateways[i].indexOf(":") != -1) ? true : false;
       // First, we need to add a host route to the gateway in the secondary
       // routing table to make the gateway reachable. Host route takes the max
       // prefix and gateway address 'any'.
-      let route = {
+      let hostRoute = {
         ip: gateways[i],
         prefix: isIPv6 ? IPV6_MAX_PREFIX_LENGTH : IPV4_MAX_PREFIX_LENGTH,
         gateway: isIPv6 ? IPV6_ADDRESS_ANY : IPV4_ADDRESS_ANY
       };
-      gNetworkService.addSecondaryRoute(network.name, route);
       // Now we can add the default route through gateway. Default route takes the
       // min prefix and destination ip 'any'.
-      route.ip = isIPv6 ? IPV6_ADDRESS_ANY : IPV4_ADDRESS_ANY;
-      route.prefix = 0;
-      route.gateway = gateways[i];
-      gNetworkService.addSecondaryRoute(network.name, route);
+      let defaultRoute = {
+        ip: isIPv6 ? IPV6_ADDRESS_ANY : IPV4_ADDRESS_ANY,
+        prefix: 0,
+        gateway: gateways[i]
+      };
+
+      let promise = this._setSecondaryRoute(true, network.name, hostRoute)
+        .then(() => this._setSecondaryRoute(true, network.name, defaultRoute));
+
+      promises.push(promise);
     }
+
+    return Promise.all(promises);
   },
 
   removeSecondaryDefaultRoute: function(network) {
     let gateways = network.getGateways();
+    let promises = [];
+
     for (let i = 0; i < gateways.length; i++) {
       let isIPv6 = (gateways[i].indexOf(":") != -1) ? true : false;
       // Remove both default route and host route.
-      let route = {
+      let defaultRoute = {
         ip: isIPv6 ? IPV6_ADDRESS_ANY : IPV4_ADDRESS_ANY,
         prefix: 0,
         gateway: gateways[i]
       };
-      gNetworkService.removeSecondaryRoute(network.name, route);
+      let hostRoute = {
+        ip: gateways[i],
+        prefix: isIPv6 ? IPV6_MAX_PREFIX_LENGTH : IPV4_MAX_PREFIX_LENGTH,
+        gateway: isIPv6 ? IPV6_ADDRESS_ANY : IPV4_ADDRESS_ANY
+      };
 
-      route.ip = gateways[i];
-      route.prefix = isIPv6 ? IPV6_MAX_PREFIX_LENGTH : IPV4_MAX_PREFIX_LENGTH;
-      route.gateway = isIPv6 ? IPV6_ADDRESS_ANY : IPV4_ADDRESS_ANY;
-      gNetworkService.removeSecondaryRoute(network.name, route);
+      let promise = this._setSecondaryRoute(false, network.name, defaultRoute)
+        .then(() => this._setSecondaryRoute(false, network.name, hostRoute));
+
+      promises.push(promise);
     }
+
+    return Promise.all(promises);
   },
 
   /**
    * Determine the active interface and configure it.
    */
   setAndConfigureActive: function() {
     debug("Evaluating whether active network needs to be changed.");
     let oldActive = this.active;
@@ -659,18 +776,17 @@ NetworkManager.prototype = {
       return;
     }
 
     // The active network is already our preferred type.
     if (this.active &&
         this.active.state == Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED &&
         this.active.type == this._preferredNetworkType) {
       debug("Active network is already our preferred type.");
-      this._setDefaultRouteAndProxy(this.active, oldActive);
-      return;
+      return this._setDefaultRouteAndProxy(this.active, oldActive);
     }
 
     // Find a suitable network interface to activate.
     this.active = null;
 
     let defaultDataNetwork;
     for each (let network in this.networkInterfaces) {
       if (network.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
@@ -683,38 +799,43 @@ NetworkManager.prototype = {
 
       this.active = network;
       if (network.type == this.preferredNetworkType) {
         debug("Found our preferred type of network: " + network.name);
         break;
       }
     }
 
-    if (this.active) {
-      // Give higher priority to default data APN than secondary APN.
-      // If default data APN is not connected, we still set default route
-      // and DNS on secondary APN.
-      if (defaultDataNetwork &&
-          this.isNetworkTypeSecondaryMobile(this.active.type) &&
-          this.active.type != this.preferredNetworkType) {
-        this.active = defaultDataNetwork;
-      }
-      // Don't set default route on secondary APN
-      if (!this.isNetworkTypeSecondaryMobile(this.active.type)) {
-        this._setDefaultRouteAndProxy(this.active, oldActive);
-      }
+    // Give higher priority to default data APN than secondary APN.
+    // If default data APN is not connected, we still set default route
+    // and DNS on secondary APN.
+    if (this.active && defaultDataNetwork &&
+        this.isNetworkTypeSecondaryMobile(this.active.type) &&
+        this.active.type != this.preferredNetworkType) {
+      this.active = defaultDataNetwork;
     }
 
-    if (this.active != oldActive) {
-      Services.obs.notifyObservers(this.active, TOPIC_ACTIVE_CHANGED, null);
-    }
+    return Promise.resolve()
+      .then(() => {
+        // Don't set default route on secondary APN
+        if (!this.active || this.isNetworkTypeSecondaryMobile(this.active.type)) {
+          return Promise.resolve();
+        }
 
-    if (this._manageOfflineStatus) {
-      Services.io.offline = !this.active;
-    }
+        return this._setDefaultRouteAndProxy(this.active, oldActive);
+      })
+      .then(() => {
+        if (this.active != oldActive) {
+          Services.obs.notifyObservers(this.active, TOPIC_ACTIVE_CHANGED, null);
+        }
+
+        if (this._manageOfflineStatus) {
+          Services.io.offline = !this.active;
+        }
+      });
   },
 
   resolveHostname: function(network, hostname) {
     // Sanity check for null, undefined and empty string... etc.
     if (!hostname) {
       return Promise.reject(new Error("hostname is empty: " + hostname));
     }
 
@@ -783,23 +904,88 @@ NetworkManager.prototype = {
     switch (network.type) {
       case Ci.nsINetworkInterface.NETWORK_TYPE_WIFI:
         return CONNECTION_TYPE_WIFI;
       case Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE:
         return CONNECTION_TYPE_CELLULAR;
     }
   },
 
-  _setDefaultRouteAndProxy: function(network, oldInterface) {
-    gNetworkService.setDefaultRoute(network, oldInterface, (success) => {
-      if (!success) {
-        gNetworkService.destroyNetwork(network, function() {});
-        return;
-      }
-      this.setNetworkProxy(network);
+  _setDNS: function(aNetwork) {
+    return new Promise((aResolve, aReject) => {
+      gNetworkService.setDNS(aNetwork, (aError) => {
+        if (aError) {
+          aReject("setDNS failed");
+          return;
+        }
+        aResolve();
+      });
+    });
+  },
+
+  _createNetwork: function(aInterfaceName) {
+    return new Promise((aResolve, aReject) => {
+      gNetworkService.createNetwork(aInterfaceName, (aSuccess) => {
+        if (!aSuccess) {
+          aReject("createNetwork failed");
+          return;
+        }
+        aResolve();
+      });
+    });
+  },
+
+  _destroyNetwork: function(aInterfaceName) {
+    return new Promise((aResolve, aReject) => {
+      gNetworkService.destroyNetwork(aInterfaceName, (aSuccess) => {
+        if (!aSuccess) {
+          debug("destroyNetwork failed")
+        }
+        // Always resolve.
+        aResolve();
+      });
+    });
+  },
+
+  _resetRoutingTable: function(aNetwork) {
+    return new Promise((aResolve, aReject) => {
+      gNetworkService.resetRoutingTable(aNetwork, (aSuccess) => {
+        if (!aSuccess) {
+          debug("resetRoutingTable failed");
+        }
+        // Always resolve.
+        aResolve();
+      });
+    });
+  },
+
+  _removeDefaultRoute: function(aNetwork) {
+    return new Promise((aResolve, aReject) => {
+      gNetworkService.removeDefaultRoute(aNetwork, (aSuccess) => {
+        if (!aSuccess) {
+          debug("removeDefaultRoute failed");
+        }
+        // Always resolve.
+        aResolve();
+      });
+    });
+  },
+
+  _setDefaultRouteAndProxy: function(aNetwork, aOldInterface) {
+    return new Promise((aResolve, aReject) => {
+      gNetworkService.setDefaultRoute(aNetwork, aOldInterface, (aSuccess) => {
+        if (!aSuccess) {
+          gNetworkService.destroyNetwork(aNetwork, function() {
+            aReject("setDefaultRoute failed");
+          });
+          return;
+        }
+        this.setNetworkProxy(aNetwork);
+        aResolve();
+      });
     });
   },
 
   setNetworkProxy: function(network) {
     try {
       if (!network.httpProxyHost || network.httpProxyHost === "") {
         // Sets direct connection to internet.
         this.clearNetworkProxy();
--- a/dom/system/gonk/NetworkService.js
+++ b/dom/system/gonk/NetworkService.js
@@ -363,23 +363,25 @@ NetworkService.prototype = {
       if (isError(result.resultCode)) {
         callback.wifiOperationModeResult("netd command error");
       } else {
         callback.wifiOperationModeResult(null);
       }
     });
   },
 
-  resetRoutingTable: function(network) {
+  resetRoutingTable: function(network, callback) {
     let options = {
       cmd: "removeNetworkRoute",
       ifname: network.name
     };
 
-    this.controlMessage(options);
+    this.controlMessage(options, function(result) {
+      callback.nativeCommandResult(!result.error);
+    });
   },
 
   setDNS: function(networkInterface, callback) {
     debug("Going DNS to " + networkInterface.name);
     let dnses = networkInterface.getDnses();
     let options = {
       cmd: "setDNS",
       ifname: networkInterface.name,
@@ -401,25 +403,27 @@ NetworkService.prototype = {
       oldIfname: (oldInterface && oldInterface !== network) ? oldInterface.name : null,
       gateways: gateways
     };
     this.controlMessage(options, function(result) {
       callback.nativeCommandResult(!result.error);
     });
   },
 
-  removeDefaultRoute: function(network) {
+  removeDefaultRoute: function(network, callback) {
     debug("Remove default route for " + network.name);
     let gateways = network.getGateways();
     let options = {
       cmd: "removeDefaultRoute",
       ifname: network.name,
       gateways: gateways
     };
-    this.controlMessage(options);
+    this.controlMessage(options, function(result) {
+      callback.nativeCommandResult(!result.error);
+    });
   },
 
   _routeToString: function(interfaceName, host, prefixLength, gateway) {
     return host + "-" + prefixLength + "-" + gateway + "-" + interfaceName;
   },
 
   modifyRoute: function(action, interfaceName, host, prefixLength, gateway) {
     let command;
@@ -482,38 +486,42 @@ NetworkService.prototype = {
           this.addedRoutes.set(route, count ? count + 1 : 1);
         }
 
         aResolve();
       }, setupFunc);
     });
   },
 
-  addSecondaryRoute: function(ifname, route) {
+  addSecondaryRoute: function(ifname, route, callback) {
     debug("Going to add route to secondary table on " + ifname);
     let options = {
       cmd: "addSecondaryRoute",
       ifname: ifname,
       ip: route.ip,
       prefix: route.prefix,
       gateway: route.gateway
     };
-    this.controlMessage(options);
+    this.controlMessage(options, function(result) {
+      callback.nativeCommandResult(!result.error);
+    });
   },
 
-  removeSecondaryRoute: function(ifname, route) {
+  removeSecondaryRoute: function(ifname, route, callback) {
     debug("Going to remove route from secondary table on " + ifname);
     let options = {
       cmd: "removeSecondaryRoute",
       ifname: ifname,
       ip: route.ip,
       prefix: route.prefix,
       gateway: route.gateway
     };
-    this.controlMessage(options);
+    this.controlMessage(options, function(result) {
+      callback.nativeCommandResult(!result.error);
+    });
   },
 
   // Enable/Disable DHCP server.
   setDhcpServer: function(enabled, config, callback) {
     if (null === config) {
       config = {};
     }
 
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -2698,23 +2698,23 @@ DataCall.prototype = {
 
     if (this.state == RIL.GECKO_NETWORK_STATE_CONNECTING ||
         this.state == RIL.GECKO_NETWORK_STATE_DISCONNECTING) {
       return;
     }
     if (this.state == RIL.GECKO_NETWORK_STATE_CONNECTED) {
       // This needs to run asynchronously, to behave the same way as the case of
       // non-shared apn, see bug 1059110.
-      Services.tm.currentThread.dispatch(function(state) {
+      Services.tm.currentThread.dispatch(() => {
         // Do not notify if state changed while this event was being dispatched,
         // the state probably was notified already or need not to be notified.
-        if (networkInterface.state == state) {
+        if (networkInterface.state == RIL.GECKO_NETWORK_STATE_CONNECTED) {
           networkInterface.notifyRILNetworkInterface();
         }
-      }.bind(null, RIL.GECKO_NETWORK_STATE_CONNECTED), Ci.nsIEventTarget.DISPATCH_NORMAL);
+      }, Ci.nsIEventTarget.DISPATCH_NORMAL);
       return;
     }
 
     // If retry mechanism is running on background, stop it since we are going
     // to setup data call now.
     if (this.timer) {
       this.timer.cancel();
     }
@@ -2824,23 +2824,25 @@ DataCall.prototype = {
         }
         this.reset();
         return;
       }
 
       // Notify the DISCONNECTED event immediately after network interface is
       // removed from requestedNetworkIfaces, to make the DataCall, shared or
       // not, to have the same behavior.
-      Services.tm.currentThread.dispatch(function(state) {
+      Services.tm.currentThread.dispatch(() => {
         // Do not notify if state changed while this event was being dispatched,
         // the state probably was notified already or need not to be notified.
-        if (networkInterface.state == state) {
+        if (networkInterface.state == RIL.GECKO_NETWORK_STATE_DISCONNECTED) {
           networkInterface.notifyRILNetworkInterface();
+          // Clear link info after notifying NetworkManager.
+          this.resetLinkInfo();
         }
-      }.bind(null, RIL.GECKO_NETWORK_STATE_DISCONNECTED), Ci.nsIEventTarget.DISPATCH_NORMAL);
+      }, Ci.nsIEventTarget.DISPATCH_NORMAL);
     }
 
     // Only deactivate data call if no more network interface needs this
     // DataCall and if state is CONNECTED, for other states, we simply remove
     // the network interface from requestedNetworkIfaces.
     if (this.requestedNetworkIfaces.length > 0 ||
         this.state != RIL.GECKO_NETWORK_STATE_CONNECTED) {
       return;
@@ -2856,17 +2858,16 @@ DataCall.prototype = {
     }
     let radioInterface = this.gRIL.getRadioInterface(this.clientId);
     radioInterface.sendWorkerMessage("deactivateDataCall", {
       cid: this.linkInfo.cid,
       reason: reason
     }, this.onDeactivateDataCallResult.bind(this));
 
     this.state = RIL.GECKO_NETWORK_STATE_DISCONNECTING;
-    this.resetLinkInfo();
   },
 
   // Entry method for timer events. Used to reconnect to a failed APN
   notify: function(timer) {
     this.setup();
   },
 
   shutdown: function() {
--- a/dom/system/gonk/nsINetworkService.idl
+++ b/dom/system/gonk/nsINetworkService.idl
@@ -154,17 +154,17 @@ interface nsIDhcpRequestCallback : nsISu
    */
   void dhcpRequestResult(in boolean success, in jsval dhcpInfo);
 };
 
 
 /**
  * Provide network services.
  */
-[scriptable, uuid(2e030f00-8b74-4800-8add-5862ab183503)]
+[scriptable, uuid(8216224c-a4e0-43fa-9662-3f2446b500c6)]
 interface nsINetworkService : nsISupports
 {
   const long MODIFY_ROUTE_ADD    = 0;
   const long MODIFY_ROUTE_REMOVE = 1;
 
   /**
    * Enable or disable Wifi Tethering
    *
@@ -266,17 +266,18 @@ interface nsINetworkService : nsISupport
                        in nsIUsbTetheringCallback callback);
 
   /**
    * Reset routing table.
    *
    * @param networkInterface
    *        The network interface we want remove from the routing table.
    */
-  void resetRoutingTable(in nsINetworkInterface networkInterface);
+  void resetRoutingTable(in nsINetworkInterface networkInterface,
+                         in nsINativeCommandCallback callback);
 
   /**
    * Set DNS.
    *
    * @param networkInterface
    *        The network interface which contains the DNS we want to set.
    *
    * @param callback
@@ -300,17 +301,18 @@ interface nsINetworkService : nsISupport
                        in nsINativeCommandCallback callback);
 
   /**
    * Remove default route.
    *
    * @param networkInterface
    *        The network interface we want remove from the default route.
    */
-  void removeDefaultRoute(in nsINetworkInterface networkInterface);
+  void removeDefaultRoute(in nsINetworkInterface networkInterface,
+                          in nsINativeCommandCallback callback);
 
   /**
    * Modify route.
    *
    * @param action
    *        nsINetworkService.MODIFY_ROUTE_ADD to add route and
    *        nsINetworkService.MODIFY_ROUTE_REMOVE to remove.
    * @param interfaceName
@@ -337,30 +339,32 @@ interface nsINetworkService : nsISupport
    * @param interfaceName
    *        The network interface for this route.
    * @param route
    *        The route info should have the following fields:
    *        .ip: destination ip address
    *        .prefix: destination prefix
    *        .gateway: gateway ip address
    */
-  void addSecondaryRoute(in DOMString interfaceName, in jsval route);
+  void addSecondaryRoute(in DOMString interfaceName, in jsval route,
+                         in nsINativeCommandCallback callback);
 
   /**
    * Remove route from secondary routing table.
    *
    * @param interfaceName
    *        The network interface for the route we want to remove.
    * @param route
    *        The route info should have the following fields:
    *        .ip: destination ip address
    *        .prefix: destination prefix
    *        .gateway: gateway ip address
    */
-  void removeSecondaryRoute(in DOMString interfaceName, in jsval route);
+  void removeSecondaryRoute(in DOMString interfaceName, in jsval route,
+                            in nsINativeCommandCallback callback);
 
   /**
    * Enable or disable usb rndis.
    *
    * @param enable
    *        Boolean to indicate we want enable or disable usb rndis.
    * @param callback
    *        Callback function to report the result.
--- a/widget/gonk/nsScreenManagerGonk.h
+++ b/widget/gonk/nsScreenManagerGonk.h
@@ -26,65 +26,88 @@
 class nsRunnable;
 class nsWindow;
 
 class nsScreenGonk : public nsBaseScreen
 {
     typedef mozilla::hal::ScreenConfiguration ScreenConfiguration;
 
 public:
-    nsScreenGonk();
+    nsScreenGonk(uint32_t aId, ANativeWindow* aNativeWindow);
+
     ~nsScreenGonk();
 
     NS_IMETHOD GetId(uint32_t* aId);
     NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
     NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
     NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth);
     NS_IMETHOD GetColorDepth(int32_t* aColorDepth);
     NS_IMETHOD GetRotation(uint32_t* aRotation);
     NS_IMETHOD SetRotation(uint32_t  aRotation);
 
+    uint32_t GetId();
+    nsIntRect GetRect();
+    float GetDpi();
+    ANativeWindow* GetNativeWindow();
     nsIntRect GetNaturalBounds();
     uint32_t EffectiveScreenRotation();
     ScreenConfiguration GetConfiguration();
+    bool IsPrimaryScreen();
 
     void RegisterWindow(nsWindow* aWindow);
     void UnregisterWindow(nsWindow* aWindow);
     void BringToTop(nsWindow* aWindow);
 
     const nsTArray<nsWindow*>& GetTopWindows() const
     {
         return mTopWindows;
     }
 
 protected:
-    nsIntRect mScreenBounds;
-    nsIntRect mVirtualBounds;
+    uint32_t mId;
+    int32_t mColorDepth;
+    android::sp<ANativeWindow> mNativeWindow;
+    float mDpi;
+    nsIntRect mNaturalBounds; // Screen bounds w/o rotation taken into account.
+    nsIntRect mVirtualBounds; // Screen bounds w/ rotation taken into account.
     uint32_t mScreenRotation;
     uint32_t mPhysicalScreenRotation;
     nsTArray<nsWindow*> mTopWindows;
 };
 
 class nsScreenManagerGonk final : public nsIScreenManager
 {
 public:
+    enum {
+        // TODO: Bug 1138287 will define more screen/display types.
+        PRIMARY_SCREEN_TYPE = 0,
+
+        // TODO: Maintain a mapping from type to id dynamically.
+        PRIMARY_SCREEN_ID = 0,
+    };
+
+public:
     nsScreenManagerGonk();
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSISCREENMANAGER
 
     static already_AddRefed<nsScreenManagerGonk> GetInstance();
     static already_AddRefed<nsScreenGonk> GetPrimaryScreen();
 
     void Initialize();
     void DisplayEnabled(bool aEnabled);
 
+    void AddScreen(uint32_t aDisplayType);
+    void RemoveScreen(uint32_t aDisplayType);
+
 protected:
     ~nsScreenManagerGonk();
     void VsyncControl(bool aEnabled);
+    uint32_t GetIdFromType(uint32_t aDisplayType);
 
     bool mInitialized;
-    nsCOMPtr<nsIScreen> mOneScreen;
+    nsTArray<nsRefPtr<nsScreenGonk>> mScreens;
     nsRefPtr<nsRunnable> mScreenOnEvent;
     nsRefPtr<nsRunnable> mScreenOffEvent;
 };
 
 #endif /* nsScreenManagerGonk_h___ */
--- a/widget/gonk/nsWindow.cpp
+++ b/widget/gonk/nsWindow.cpp
@@ -129,33 +129,34 @@ displayEnabledCallback(bool enabled)
 NS_IMPL_ISUPPORTS_INHERITED0(nsWindow, nsBaseWidget)
 
 nsWindow::nsWindow()
 {
     mFramebuffer = nullptr;
 
     nsRefPtr<nsScreenManagerGonk> screenManager = nsScreenManagerGonk::GetInstance();
     screenManager->Initialize();
-    mScreen = nsScreenManagerGonk::GetPrimaryScreen();
 
     // This is a hack to force initialization of the compositor
     // resources, if we're going to use omtc.
     //
     // NB: GetPlatform() will create the gfxPlatform, which wants
     // to know the color depth, which asks our native window.
     // This has to happen after other init has finished.
     gfxPlatform::GetPlatform();
     if (!ShouldUseOffMainThreadCompositing()) {
         MOZ_CRASH("How can we render apps, then?");
     }
 }
 
 nsWindow::~nsWindow()
 {
-    HwcComposer2D::GetInstance()->SetCompositorParent(nullptr);
+    if (mScreen->IsPrimaryScreen()) {
+        HwcComposer2D::GetInstance()->SetCompositorParent(nullptr);
+    }
 }
 
 void
 nsWindow::DoDraw(void)
 {
     if (!hal::GetScreenEnabled()) {
         gDrawRequest = true;
         return;
@@ -392,38 +393,45 @@ nsWindow::SynthesizeNativeTouchPoint(uin
 }
 
 NS_IMETHODIMP
 nsWindow::Create(nsIWidget *aParent,
                  void *aNativeParent,
                  const nsIntRect &aRect,
                  nsWidgetInitData *aInitData)
 {
-    nsIntRect virtualBounds;
-    mScreen->GetRect(&virtualBounds.x, &virtualBounds.y,
-                     &virtualBounds.width, &virtualBounds.height);
-    BaseCreate(aParent, IS_TOPLEVEL() ? virtualBounds : aRect,
-               aInitData);
+    BaseCreate(aParent, aRect, aInitData);
+
+    nsCOMPtr<nsIScreen> screen;
+
+    uint32_t screenId = aParent ? ((nsWindow*)aParent)->mScreen->GetId() :
+                                  aInitData->mScreenId;
+
+    nsRefPtr<nsScreenManagerGonk> screenManager = nsScreenManagerGonk::GetInstance();
+    screenManager->ScreenForId(screenId, getter_AddRefs(screen));
+
+    mScreen = static_cast<nsScreenGonk*>(screen.get());
 
     mBounds = aRect;
 
     mParent = (nsWindow *)aParent;
     mVisible = false;
 
     if (!aParent) {
-        mBounds = virtualBounds;
+        mBounds = mScreen->GetRect();
     }
 
     if (!IS_TOPLEVEL()) {
         return NS_OK;
     }
 
     mScreen->RegisterWindow(this);
 
-    Resize(0, 0, virtualBounds.width, virtualBounds.height, false);
+    Resize(0, 0, mBounds.width, mBounds.height, false);
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::Destroy(void)
 {
     mOnDestroyCalled = true;
     mScreen->UnregisterWindow(this);
@@ -506,20 +514,17 @@ nsWindow::Resize(double aX,
 {
     mBounds = nsIntRect(NSToIntRound(aX), NSToIntRound(aY),
                         NSToIntRound(aWidth), NSToIntRound(aHeight));
     if (mWidgetListener) {
         mWidgetListener->WindowResized(this, mBounds.width, mBounds.height);
     }
 
     if (aRepaint) {
-        nsIntRect virtualBounds;
-        mScreen->GetRect(&virtualBounds.x, &virtualBounds.y,
-                         &virtualBounds.width, &virtualBounds.height);
-        Invalidate(virtualBounds);
+        Invalidate(mBounds);
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::Enable(bool aState)
 {
@@ -533,17 +538,22 @@ nsWindow::IsEnabled() const
 }
 
 NS_IMETHODIMP
 nsWindow::SetFocus(bool aRaise)
 {
     if (aRaise) {
         BringToTop();
     }
-    gFocusedWindow = this;
+
+    if (!IS_TOPLEVEL() && mScreen->IsPrimaryScreen()) {
+        // We should only set focused window on non-toplevel primary window.
+        gFocusedWindow = this;
+    }
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::ConfigureChildren(const nsTArray<nsIWidget::Configuration>&)
 {
     return NS_OK;
 }
@@ -582,17 +592,17 @@ nsWindow::WidgetToScreenOffset()
 }
 
 void*
 nsWindow::GetNativeData(uint32_t aDataType)
 {
     switch (aDataType) {
     case NS_NATIVE_WINDOW:
         // Called before primary display's EGLSurface creation.
-        return GetGonkDisplay()->GetNativeWindow();
+        return mScreen->GetNativeWindow();
     }
     return nullptr;
 }
 
 void
 nsWindow::SetNativeData(uint32_t aDataType, uintptr_t aVal)
 {
     switch (aDataType) {
@@ -743,17 +753,17 @@ nsWindow::EndRemoteDrawing()
     }
     mFramebuffer = nullptr;
     mFramebufferTarget = nullptr;
 }
 
 float
 nsWindow::GetDPI()
 {
-    return GetGonkDisplay()->xdpi;
+    return mScreen->GetDpi();
 }
 
 double
 nsWindow::GetDefaultScaleInternal()
 {
     float dpi = GetDPI();
     // The mean pixel density for mdpi devices is 160dpi, 240dpi for hdpi,
     // and 320dpi for xhdpi, respectively.
@@ -798,17 +808,17 @@ nsWindow::GetLayerManager(PLayerTransact
     nsWindow *topWindow = windows[0];
 
     if (!topWindow) {
         LOGW(" -- no topwindow\n");
         return nullptr;
     }
 
     CreateCompositor();
-    if (mCompositorParent) {
+    if (mCompositorParent && mScreen->IsPrimaryScreen()) {
         HwcComposer2D::GetInstance()->SetCompositorParent(mCompositorParent);
     }
     MOZ_ASSERT(mLayerManager);
     return mLayerManager;
 }
 
 void
 nsWindow::BringToTop()
@@ -821,20 +831,17 @@ nsWindow::BringToTop()
     }
 
     mScreen->BringToTop(this);
 
     if (mWidgetListener) {
         mWidgetListener->WindowActivated();
     }
 
-    nsIntRect virtualBounds;
-    mScreen->GetRect(&virtualBounds.x, &virtualBounds.y,
-                     &virtualBounds.width, &virtualBounds.height);
-    Invalidate(virtualBounds);
+    Invalidate(mBounds);
 }
 
 void
 nsWindow::UserActivity()
 {
     if (!mIdleService) {
         mIdleService = do_GetService("@mozilla.org/widget/idleservice;1");
     }
@@ -869,143 +876,183 @@ nsWindow::NeedsPaint()
     return false;
   }
   return nsIWidget::NeedsPaint();
 }
 
 Composer2D*
 nsWindow::GetComposer2D()
 {
+    if (!mScreen->IsPrimaryScreen()) {
+        return nullptr;
+    }
+
     return HwcComposer2D::GetInstance();
 }
 
+static uint32_t
+SurfaceFormatToColorDepth(int32_t aSurfaceFormat)
+{
+    switch (aSurfaceFormat) {
+    case GGL_PIXEL_FORMAT_RGB_565:
+        return 16;
+    case GGL_PIXEL_FORMAT_RGBA_8888:
+        return 32;
+    }
+    return 24; // GGL_PIXEL_FORMAT_RGBX_8888
+}
+
 // nsScreenGonk.cpp
 
-nsScreenGonk::nsScreenGonk()
-    : mScreenRotation(nsIScreen::ROTATION_0_DEG)
+nsScreenGonk::nsScreenGonk(uint32_t aId, ANativeWindow* aNativeWindow)
+    : mId(aId)
+    , mNativeWindow(aNativeWindow)
+    , mScreenRotation(nsIScreen::ROTATION_0_DEG)
     , mPhysicalScreenRotation(nsIScreen::ROTATION_0_DEG)
 {
-    nsIntSize screenSize;
-
-    ANativeWindow *win = GetGonkDisplay()->GetNativeWindow();
-    if (win->query(win, NATIVE_WINDOW_WIDTH, &screenSize.width) ||
-        win->query(win, NATIVE_WINDOW_HEIGHT, &screenSize.height)) {
+    int surfaceFormat;
+    if (mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_WIDTH, &mVirtualBounds.width) ||
+        mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_HEIGHT, &mVirtualBounds.height) ||
+        mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_FORMAT, &surfaceFormat)) {
         NS_RUNTIMEABORT("Failed to get native window size, aborting...");
     }
-    mScreenBounds = gfx::IntRect(gfx::IntPoint(0, 0), screenSize);
+
+    mNaturalBounds = mVirtualBounds;
 
-    char propValue[PROPERTY_VALUE_MAX];
-    property_get("ro.sf.hwrotation", propValue, "0");
-    mPhysicalScreenRotation = atoi(propValue) / 90;
+    if (IsPrimaryScreen()) {
+        char propValue[PROPERTY_VALUE_MAX];
+        property_get("ro.sf.hwrotation", propValue, "0");
+        mPhysicalScreenRotation = atoi(propValue) / 90;
+    }
 
-    mVirtualBounds = mScreenBounds;
+    mDpi = GetGonkDisplay()->xdpi;
+    mColorDepth = SurfaceFormatToColorDepth(surfaceFormat);
 }
 
 nsScreenGonk::~nsScreenGonk()
 {
 }
 
+bool
+nsScreenGonk::IsPrimaryScreen()
+{
+    return nsScreenManagerGonk::PRIMARY_SCREEN_ID == mId;
+}
+
 NS_IMETHODIMP
 nsScreenGonk::GetId(uint32_t *outId)
 {
-    *outId = 1;
+    *outId = mId;
     return NS_OK;
 }
 
+uint32_t
+nsScreenGonk::GetId()
+{
+    return mId;
+}
+
 NS_IMETHODIMP
 nsScreenGonk::GetRect(int32_t *outLeft,  int32_t *outTop,
                       int32_t *outWidth, int32_t *outHeight)
 {
     *outLeft = mVirtualBounds.x;
     *outTop = mVirtualBounds.y;
 
     *outWidth = mVirtualBounds.width;
     *outHeight = mVirtualBounds.height;
 
     return NS_OK;
 }
 
+nsIntRect
+nsScreenGonk::GetRect()
+{
+    return mVirtualBounds;
+}
+
 NS_IMETHODIMP
 nsScreenGonk::GetAvailRect(int32_t *outLeft,  int32_t *outTop,
                            int32_t *outWidth, int32_t *outHeight)
 {
     return GetRect(outLeft, outTop, outWidth, outHeight);
 }
 
-static uint32_t
-ColorDepth()
-{
-    switch (GetGonkDisplay()->surfaceformat) {
-    case GGL_PIXEL_FORMAT_RGB_565:
-        return 16;
-    case GGL_PIXEL_FORMAT_RGBA_8888:
-        return 32;
-    }
-    return 24; // GGL_PIXEL_FORMAT_RGBX_8888
-}
-
 NS_IMETHODIMP
 nsScreenGonk::GetPixelDepth(int32_t *aPixelDepth)
 {
     // XXX: this should actually return 32 when we're using 24-bit
     // color, because we use RGBX.
-    *aPixelDepth = ColorDepth();
+    *aPixelDepth = mColorDepth;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScreenGonk::GetColorDepth(int32_t *aColorDepth)
 {
-    return GetPixelDepth(aColorDepth);
+    *aColorDepth = mColorDepth;
+    return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScreenGonk::GetRotation(uint32_t* aRotation)
 {
     *aRotation = mScreenRotation;
     return NS_OK;
 }
 
+float
+nsScreenGonk::GetDpi()
+{
+    return mDpi;
+}
+
+ANativeWindow*
+nsScreenGonk::GetNativeWindow()
+{
+    return mNativeWindow.get();
+}
+
 NS_IMETHODIMP
 nsScreenGonk::SetRotation(uint32_t aRotation)
 {
     if (!(aRotation <= ROTATION_270_DEG)) {
         return NS_ERROR_ILLEGAL_VALUE;
     }
 
     if (mScreenRotation == aRotation) {
         return NS_OK;
     }
 
     mScreenRotation = aRotation;
     uint32_t rotation = EffectiveScreenRotation();
     if (rotation == nsIScreen::ROTATION_90_DEG ||
         rotation == nsIScreen::ROTATION_270_DEG) {
         mVirtualBounds = nsIntRect(0, 0,
-                                   mScreenBounds.height,
-                                   mScreenBounds.width);
+                                   mNaturalBounds.height,
+                                   mNaturalBounds.width);
     } else {
-        mVirtualBounds = mScreenBounds;
+        mVirtualBounds = mNaturalBounds;
     }
 
     nsAppShell::NotifyScreenRotation();
 
     for (unsigned int i = 0; i < mTopWindows.Length(); i++) {
         mTopWindows[i]->Resize(mVirtualBounds.width,
                             mVirtualBounds.height,
                             true);
     }
 
     return NS_OK;
 }
 
 nsIntRect
 nsScreenGonk::GetNaturalBounds()
 {
-    return mScreenBounds;
+    return mNaturalBounds;
 }
 
 uint32_t
 nsScreenGonk::EffectiveScreenRotation()
 {
     return (mScreenRotation + mPhysicalScreenRotation) % (360 / 90);
 }
 
@@ -1034,22 +1081,22 @@ ComputeOrientation(uint32_t aRotation, c
         MOZ_CRASH("Gonk screen must always have a known rotation");
     }
 }
 
 ScreenConfiguration
 nsScreenGonk::GetConfiguration()
 {
     ScreenOrientation orientation = ComputeOrientation(mScreenRotation,
-                                                       mScreenBounds.Size());
-    uint32_t colorDepth = ColorDepth();
+                                                       mNaturalBounds.Size());
+
     // NB: perpetuating colorDepth == pixelDepth illusion here, for
     // consistency.
     return ScreenConfiguration(mVirtualBounds, orientation,
-                               colorDepth, colorDepth);
+                               mColorDepth, mColorDepth);
 }
 
 void
 nsScreenGonk::RegisterWindow(nsWindow* aWindow)
 {
     mTopWindows.AppendElement(aWindow);
 }
 
@@ -1066,17 +1113,16 @@ nsScreenGonk::BringToTop(nsWindow* aWind
     mTopWindows.InsertElementAt(0, aWindow);
 }
 
 NS_IMPL_ISUPPORTS(nsScreenManagerGonk, nsIScreenManager)
 
 nsScreenManagerGonk::nsScreenManagerGonk()
     : mInitialized(false)
 {
-    mOneScreen = new nsScreenGonk();
 }
 
 nsScreenManagerGonk::~nsScreenManagerGonk()
 {
 }
 
 /* static */ already_AddRefed<nsScreenManagerGonk>
 nsScreenManagerGonk::GetInstance()
@@ -1105,16 +1151,18 @@ nsScreenManagerGonk::Initialize()
     if (mInitialized) {
         return;
     }
 
     mScreenOnEvent = new ScreenOnOffEvent(true);
     mScreenOffEvent = new ScreenOnOffEvent(false);
     GetGonkDisplay()->OnEnabled(displayEnabledCallback);
 
+    AddScreen(PRIMARY_SCREEN_TYPE);
+
     nsAppShell::NotifyScreenInitialized();
     mInitialized = true;
 }
 
 void
 nsScreenManagerGonk::DisplayEnabled(bool aEnabled)
 {
     if (gfxPrefs::HardwareVsyncEnabled()) {
@@ -1122,47 +1170,65 @@ nsScreenManagerGonk::DisplayEnabled(bool
     }
 
     NS_DispatchToMainThread(aEnabled ? mScreenOnEvent : mScreenOffEvent);
 }
 
 NS_IMETHODIMP
 nsScreenManagerGonk::GetPrimaryScreen(nsIScreen **outScreen)
 {
-    NS_IF_ADDREF(*outScreen = mOneScreen.get());
+    NS_IF_ADDREF(*outScreen = mScreens[0].get());
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScreenManagerGonk::ScreenForId(uint32_t aId,
                                  nsIScreen **outScreen)
 {
-    return GetPrimaryScreen(outScreen);
+    for (size_t i = 0; i < mScreens.Length(); i++) {
+        if (mScreens[i]->GetId() == aId) {
+            NS_IF_ADDREF(*outScreen = mScreens[i].get());
+            return NS_OK;
+        }
+    }
+
+    *outScreen = nullptr;
+    return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScreenManagerGonk::ScreenForRect(int32_t inLeft,
                                    int32_t inTop,
                                    int32_t inWidth,
                                    int32_t inHeight,
                                    nsIScreen **outScreen)
 {
+    // Since all screens have independent coordinate system, we could
+    // only return the primary screen no matter what rect is given.
     return GetPrimaryScreen(outScreen);
 }
 
 NS_IMETHODIMP
 nsScreenManagerGonk::ScreenForNativeWidget(void *aWidget, nsIScreen **outScreen)
 {
-    return GetPrimaryScreen(outScreen);
+    for (size_t i = 0; i < mScreens.Length(); i++) {
+        if (aWidget == mScreens[i]->GetNativeWindow()) {
+            NS_IF_ADDREF(*outScreen = mScreens[i].get());
+            return NS_OK;
+        }
+    }
+
+    *outScreen = nullptr;
+    return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScreenManagerGonk::GetNumberOfScreens(uint32_t *aNumberOfScreens)
 {
-    *aNumberOfScreens = 1;
+    *aNumberOfScreens = mScreens.Length();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScreenManagerGonk::GetSystemDefaultScale(float *aDefaultScale)
 {
     *aDefaultScale = 1.0f;
     return NS_OK;
@@ -1184,8 +1250,44 @@ nsScreenManagerGonk::VsyncControl(bool a
     MOZ_ASSERT(NS_IsMainThread());
     VsyncSource::Display &display = gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay();
     if (aEnabled) {
         display.EnableVsync();
     } else {
         display.DisableVsync();
     }
 }
+
+uint32_t
+nsScreenManagerGonk::GetIdFromType(uint32_t aDisplayType)
+{
+    // This is the only place where we make the assumption that
+    // display type is equivalent to screen id.
+
+    // Bug 1138287 will address the conversion from type to id.
+    return aDisplayType;
+}
+
+void
+nsScreenManagerGonk::AddScreen(uint32_t aDisplayType)
+{
+    // We currently only support adding primary screen.
+    MOZ_ASSERT(PRIMARY_SCREEN_TYPE == aDisplayType);
+
+    uint32_t id = GetIdFromType(aDisplayType);
+
+    ANativeWindow* win = GetGonkDisplay()->GetNativeWindow();
+    nsScreenGonk* screen = new nsScreenGonk(id, win);
+
+    mScreens.AppendElement(screen);
+}
+
+void
+nsScreenManagerGonk::RemoveScreen(uint32_t aDisplayType)
+{
+    uint32_t screenId = GetIdFromType(aDisplayType);
+    for (size_t i = 0; i < mScreens.Length(); i++) {
+        if (mScreens[i]->GetId() == screenId) {
+            mScreens.RemoveElementAt(i);
+            break;
+        }
+    }
+}