Merge the last PGO-green inbound changeset to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 01 Aug 2012 17:51:23 -0400
changeset 101110 7fe96a690596e484b1c4c0ebed350b1b69cc177f
parent 101090 a2cac33cda2a19cceb25ec901f528a681eecab1e (current diff)
parent 101109 24e4580308429d908d19321c050732062890a11e (diff)
child 101161 61d7f15ea6a760def8b09109848a6dd2e6481941
push id23216
push userryanvm@gmail.com
push dateWed, 01 Aug 2012 21:51:28 +0000
treeherdermozilla-central@7fe96a690596 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone17.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 the last PGO-green inbound changeset to m-c.
mobile/android/base/gfx/LayerController.java
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -60,24 +60,17 @@ SettingsListener.observe('audio.volume.m
 // =================== Languages ====================
 SettingsListener.observe('language.current', 'en-US', function(value) {
   Services.prefs.setCharPref('intl.accept_languages', value);
 });
 
 
 // =================== RIL ====================
 (function RILSettingsToPrefs() {
-  ['ril.data.enabled', 'ril.data.roaming.enabled'].forEach(function(key) {
-    SettingsListener.observe(key, false, function(value) {
-      Services.prefs.setBoolPref(key, value);
-    });
-  });
-
-  let strPrefs = ['ril.data.apn', 'ril.data.user', 'ril.data.passwd',
-                  'ril.data.mmsc', 'ril.data.mmsproxy'];
+  let strPrefs = ['ril.data.mmsc', 'ril.data.mmsproxy'];
   strPrefs.forEach(function(key) {
     SettingsListener.observe(key, "", function(value) {
       Services.prefs.setCharPref(key, value);
     });
   });
 
   ['ril.data.mmsport'].forEach(function(key) {
     SettingsListener.observe(key, null, function(value) {
--- a/browser/config/tooltool-manifests/linux32/clang.manifest
+++ b/browser/config/tooltool-manifests/linux32/clang.manifest
@@ -1,17 +1,17 @@
 [
 {
-"clang_version": "r160364"
+"clang_version": "r161022"
 },
 {
 "size": 47,
 "digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
 "algorithm": "sha512",
 "filename": "setup.sh"
 },
 {
-"size": 65680370,
-"digest": "5d343ea80cb0ace0f2a1683466015679dfacd0ae5584a89f001710c6d665f9fbd757edef5b1bd440f234553f9dbad06c8d1eed74b71a3d11e04e7f4e2c929628",
+"size": 65670083,
+"digest": "681a8f14d9e44e4220ac69f8c545406a40962472ee8fb342b619e04e1a316ddc8802f29f39765cbc06603cc9d4774ac5c2e2d320bf3ec6bc0c7502a5abdd080e",
 "algorithm": "sha512",
 "filename": "clang.tar.bz2"
 }
 ]
--- a/browser/config/tooltool-manifests/linux64/clang.manifest
+++ b/browser/config/tooltool-manifests/linux64/clang.manifest
@@ -1,17 +1,17 @@
 [
 {
-"clang_version": "r160364"
+"clang_version": "r161022"
 },
 {
 "size": 47,
 "digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
 "algorithm": "sha512",
 "filename": "setup.sh"
 },
 {
-"size": 61020656,
-"digest": "822dc6f076309b1e45ef0ea77f88b9f5b73c8f1d0bb9c52147a2f99c4bdb67272442c9e89ab88bdadc94e2dead5e5cafc5ccea8211f42919b5ff9242bf2844d5",
+"size": 61189616,
+"digest": "ec5d4787a11f5feff8ecfa2ec91f313cc7a6968ef419c74c25200ed7df92362d566142d405269ee2f0a14d291a834d39cd5dca826d819d6599426470e80bd2c8",
 "algorithm": "sha512",
 "filename": "clang.tar.bz2"
 }
 ]
--- a/browser/config/tooltool-manifests/macosx32/clang.manifest
+++ b/browser/config/tooltool-manifests/macosx32/clang.manifest
@@ -1,17 +1,17 @@
 [
 {
-"clang_version": "r160364"
+"clang_version": "r161022"
 },
 {
 "size": 47,
 "digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
 "algorithm": "sha512",
 "filename": "setup.sh"
 },
 {
-"size": 54422251,
-"digest": "8208645d24ac87975a091ff66a90c20589ff8945936ed9b16ca81976c59bf1166ed9f79709698d435480774fba8ed9f9f178dc189305c86162acac8fda19830e",
+"size": 54405078,
+"digest": "940f02ee8e4a760f52d6fe9cd1dc8dec01abc61b8086d46b4aa7d7292cf7c353a2cec1c9687491ade756ba2654b9e93986123155cb931bd18431fbbfdef671a9",
 "algorithm": "sha512",
 "filename": "clang.tar.bz2"
 }
 ]
--- a/browser/config/tooltool-manifests/macosx32/releng.manifest
+++ b/browser/config/tooltool-manifests/macosx32/releng.manifest
@@ -1,17 +1,17 @@
 [
 {
-"clang_version": "r160364"
+"clang_version": "r161022"
 },
 {
 "size": 47,
 "digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
 "algorithm": "sha512",
 "filename": "setup.sh"
 },
 {
-"size": 54422251,
-"digest": "8208645d24ac87975a091ff66a90c20589ff8945936ed9b16ca81976c59bf1166ed9f79709698d435480774fba8ed9f9f178dc189305c86162acac8fda19830e",
+"size": 54405078,
+"digest": "940f02ee8e4a760f52d6fe9cd1dc8dec01abc61b8086d46b4aa7d7292cf7c353a2cec1c9687491ade756ba2654b9e93986123155cb931bd18431fbbfdef671a9",
 "algorithm": "sha512",
 "filename": "clang.tar.bz2"
 }
 ]
--- a/browser/config/tooltool-manifests/macosx64/clang.manifest
+++ b/browser/config/tooltool-manifests/macosx64/clang.manifest
@@ -1,17 +1,17 @@
 [
 {
-"clang_version": "r160364"
+"clang_version": "r161022"
 },
 {
 "size": 47,
 "digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
 "algorithm": "sha512",
 "filename": "setup.sh"
 },
 {
-"size": 54422251,
-"digest": "8208645d24ac87975a091ff66a90c20589ff8945936ed9b16ca81976c59bf1166ed9f79709698d435480774fba8ed9f9f178dc189305c86162acac8fda19830e",
+"size": 54405078,
+"digest": "940f02ee8e4a760f52d6fe9cd1dc8dec01abc61b8086d46b4aa7d7292cf7c353a2cec1c9687491ade756ba2654b9e93986123155cb931bd18431fbbfdef671a9",
 "algorithm": "sha512",
 "filename": "clang.tar.bz2"
 }
 ]
--- a/browser/config/tooltool-manifests/macosx64/releng.manifest
+++ b/browser/config/tooltool-manifests/macosx64/releng.manifest
@@ -1,17 +1,17 @@
 [
 {
-"clang_version": "r160364"
+"clang_version": "r161022"
 },
 {
 "size": 47,
 "digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
 "algorithm": "sha512",
 "filename": "setup.sh"
 },
 {
-"size": 54422251,
-"digest": "8208645d24ac87975a091ff66a90c20589ff8945936ed9b16ca81976c59bf1166ed9f79709698d435480774fba8ed9f9f178dc189305c86162acac8fda19830e",
+"size": 54405078,
+"digest": "940f02ee8e4a760f52d6fe9cd1dc8dec01abc61b8086d46b4aa7d7292cf7c353a2cec1c9687491ade756ba2654b9e93986123155cb931bd18431fbbfdef671a9",
 "algorithm": "sha512",
 "filename": "clang.tar.bz2"
 }
 ]
--- a/build/unix/build-clang/build-clang.py
+++ b/build/unix/build-clang/build-clang.py
@@ -1,14 +1,14 @@
 #!/usr/bin/python
 # 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/.
 
-llvm_revision = "160364"
+llvm_revision = "161022"
 moz_version = "moz0"
 
 ##############################################
 
 import os
 import os.path
 import shutil
 import tarfile
@@ -81,16 +81,18 @@ def build_one_stage_aux(stage_dir, is_st
                       "--prefix=%s" % inst_dir,
                       "--with-gcc-toolchain=/tools/gcc-4.5-0moz3"]
     if is_stage_one:
         configure_opts.append("--with-optimize-option=-O0")
 
     build_package(llvm_source_dir, build_dir, configure_opts)
 
 isDarwin = platform.system() == "Darwin"
+if isDarwin:
+    os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.7'
 
 if not os.path.exists(source_dir):
     os.makedirs(source_dir)
     svn_co("http://llvm.org/svn/llvm-project/llvm/trunk",
            llvm_source_dir, llvm_revision)
     svn_co("http://llvm.org/svn/llvm-project/cfe/trunk",
            clang_source_dir, llvm_revision)
     svn_co("http://llvm.org/svn/llvm-project/compiler-rt/trunk",
--- a/dom/system/gonk/NetworkManager.js
+++ b/dom/system/gonk/NetworkManager.js
@@ -18,16 +18,18 @@ const NETWORKINTERFACE_CID =
 
 const DEFAULT_PREFERRED_NETWORK_TYPE = Ci.nsINetworkInterface.NETWORK_TYPE_WIFI;
 
 const TOPIC_INTERFACE_STATE_CHANGED  = "network-interface-state-changed";
 const TOPIC_INTERFACE_REGISTERED     = "network-interface-registered";
 const TOPIC_INTERFACE_UNREGISTERED   = "network-interface-unregistered";
 const TOPIC_DEFAULT_ROUTE_CHANGED    = "network-default-route-changed";
 
+const MANUAL_PROXY_CONFIGURATION = 1;
+
 const DEBUG = false;
 
 /**
  * This component watches for network interfaces changing state and then
  * adjusts routes etc. accordingly.
  */
 function NetworkManager() {
   this.networkInterfaces = {};
@@ -183,18 +185,45 @@ NetworkManager.prototype = {
   setDefaultRouteAndDNS: function setDefaultRouteAndDNS(oldInterface) {
     debug("Going to change route and DNS to " + this.active.name);
     let options = {
       cmd: this.active.dhcp ? "runDHCPAndSetDefaultRouteAndDNS" : "setDefaultRouteAndDNS",
       ifname: this.active.name,
       oldIfname: (oldInterface && oldInterface != this.active) ? oldInterface.name : null
     };
     this.worker.postMessage(options);
+    this.setNetworkProxy();
   },
 
+  setNetworkProxy: function setNetworkProxy() {
+    try {
+      if (!this.active.httpProxyHost || this.active.httpProxyHost == "") {
+        // Sets direct connection to internet.
+        Services.prefs.clearUserPref("network.proxy.type");
+        Services.prefs.clearUserPref("network.proxy.share_proxy_settings");
+        Services.prefs.clearUserPref("network.proxy.http");
+        Services.prefs.clearUserPref("network.proxy.http_port");
+        debug("No proxy support for " + this.active.name + " network interface.");
+        return;
+      }
+
+      debug("Going to set proxy settings for " + this.active.name + " network interface.");
+      // Sets manual proxy configuration.
+      Services.prefs.setIntPref("network.proxy.type", MANUAL_PROXY_CONFIGURATION);
+      // Do not use this proxy server for all protocols.
+      Services.prefs.setBoolPref("network.proxy.share_proxy_settings", false);
+      Services.prefs.setCharPref("network.proxy.http", this.active.httpProxyHost);
+      let port = this.active.httpProxyPort == "" ? 8080 : this.active.httpProxyPort;
+      Services.prefs.setIntPref("network.proxy.http_port", port);
+    } catch (ex) {
+       debug("Exception " + ex + ". Unable to set proxy setting for "
+             + this.active.name + " network interface.");
+       return;
+    }
+  },
 };
 
 const NSGetFactory = XPCOMUtils.generateNSGetFactory([NetworkManager]);
 
 
 let debug;
 if (DEBUG) {
   debug = function (s) {
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -170,16 +170,32 @@ function RadioInterfaceLayer() {
                      signalStrength: null,
                      relSignalStrength: null},
   };
 
   // Read the 'ril.radio.disabled' setting in order to start with a known
   // value at boot time.
   gSettingsService.getLock().get("ril.radio.disabled", this);
 
+  // Read the APN data form the setting DB.
+  gSettingsService.getLock().get("ril.data.apn", this);
+  gSettingsService.getLock().get("ril.data.user", this);
+  gSettingsService.getLock().get("ril.data.passwd", this);
+  gSettingsService.getLock().get("ril.data.httpProxyHost", this);
+  gSettingsService.getLock().get("ril.data.httpProxyPort", this);
+  gSettingsService.getLock().get("ril.data.roaming_enabled", this);
+  gSettingsService.getLock().get("ril.data.enabled", this);
+  this._dataCallSettingsToRead = ["ril.data.enabled",
+                                  "ril.data.roaming_enabled",
+                                  "ril.data.apn",
+                                  "ril.data.user",
+                                  "ril.data.passwd",
+                                  "ril.data.httpProxyHost",
+                                  "ril.data.httpProxyPort"];
+
   for each (let msgname in RIL_IPC_MSG_NAMES) {
     ppmm.addMessageListener(msgname, this);
   }
   Services.obs.addObserver(this, "xpcom-shutdown", false);
   Services.obs.addObserver(this, kMozSettingsChangedObserverTopic, false);
 
   this._sentSmsEnvelopes = {};
 
@@ -327,17 +343,17 @@ RadioInterfaceLayer.prototype = {
         this.updateVoiceConnection(message);
         break;
       case "dataregistrationstatechange":
         this.updateDataConnection(message);
         break;
       case "datacallerror":
         // 3G Network revoked the data connection, possible unavailable APN
         debug("Received data registration error message. Failed APN " +
-              Services.prefs.getCharPref("ril.data.apn"));
+              this.dataCallSettings["apn"]);
         RILNetworkInterface.reset();
         break;
       case "signalstrengthchange":
         this.handleSignalStrengthChange(message);
         break;
       case "operatorchange":
         this.handleOperatorChange(message);
         break;
@@ -511,32 +527,16 @@ RadioInterfaceLayer.prototype = {
       if (!state.batch) {
         ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", voiceInfo);
       }
       return true;
     }
     return false;
   },
 
-  _isDataEnabled: function _isDataEnabled() {
-    try {
-      return Services.prefs.getBoolPref("ril.data.enabled");
-    } catch(ex) {
-      return false;
-    }
-  },
-
-  _isDataRoamingEnabled: function _isDataRoamingEnabled() {
-    try {
-      return Services.prefs.getBoolPref("ril.data.roaming.enabled");
-    } catch(ex) {
-      return false;
-    }
-  },
-
   updateDataConnection: function updateDataConnection(state) {
     let data = this.rilContext.data;
     if (!state || state.regState == RIL.NETWORK_CREG_STATE_UNKNOWN) {
       data.connected = false;
       data.emergencyCallsOnly = false;
       data.roaming = false;
       data.network = null;
       data.type = null;
@@ -545,31 +545,30 @@ RadioInterfaceLayer.prototype = {
       ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);
       return false;
     }
     data.roaming =
       (state.regState == RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING);
     data.type = RIL.GECKO_RADIO_TECH[state.radioTech] || null;
     ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);
 
-    if (!this._isDataEnabled()) {
+    if (!this.dataCallSettings["enabled"]) {
       return false;
     }
 
     let isRegistered =
       state.regState == RIL.NETWORK_CREG_STATE_REGISTERED_HOME ||
-        (this._isDataRoamingEnabled() &&
+        (this.dataCallSettings["roaming_enabled"] &&
          state.regState == RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING);
     let haveDataConnection =
       state.radioTech != RIL.NETWORK_CREG_TECH_UNKNOWN;
 
     if (isRegistered && haveDataConnection) {
       debug("Radio is ready for data connection.");
-      // RILNetworkInterface will ignore this if it's already connected.
-      RILNetworkInterface.connect();
+      this.updateRILNetworkInterface();
     }
     return false;
   },
 
   handleSignalStrengthChange: function handleSignalStrengthChange(message) {
     // TODO CDMA, EVDO, LTE, etc. (see bug 726098)
     this.rilContext.voice.signalStrength = message.gsmDBM;
     this.rilContext.voice.relSignalStrength = message.gsmRelative;
@@ -633,16 +632,49 @@ RadioInterfaceLayer.prototype = {
       this.setRadioEnabled(true);
     }
     if (this.rilContext.radioState == RIL.GECKO_RADIOSTATE_READY &&
         !this._radioEnabled) {
       this.setRadioEnabled(false);
     }
   },
 
+  updateRILNetworkInterface: function updateRILNetworkInterface() {
+    if (this._dataCallSettingsToRead.length) {
+      debug("We haven't read completely the APN data from the " +
+            "settings DB yet. Wait for that.");
+      return;
+    } 
+
+    // This check avoids data call connection if the radio is not ready 
+    // yet after toggling off airplane mode. 
+    if (this.rilContext.radioState != RIL.GECKO_RADIOSTATE_READY) {
+      return; 
+    }
+
+    // We only watch at "ril.data.enabled" flag changes for connecting or
+    // disconnecting the data call. If the value of "ril.data.enabled" is
+    // true and any of the remaining flags change the setting application
+    // should turn this flag to false and then to true in order to reload
+    // the new values and reconnect the data call.
+    if (this._oldRilDataEnabledState == this.dataCallSettings["enabled"]) {
+      debug("No changes for ril.data.enabled flag. Nothing to do.");
+      return;
+    }
+
+    if (!this.dataCallSettings["enabled"] && RILNetworkInterface.connected) {
+      debug("Data call settings: disconnect data call.");
+      RILNetworkInterface.disconnect();
+    }
+    if (this.dataCallSettings["enabled"] && !RILNetworkInterface.connected) {
+      debug("Data call settings connect data call.");
+      RILNetworkInterface.connect(this.dataCallSettings);
+    }
+  },
+
   /**
    * Track the active call and update the audio system as its state changes.
    */
   _activeCall: null,
   updateCallAudioState: function updateCallAudioState() {
     if (!this._activeCall) {
       // Disable audio.
       gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL;
@@ -919,43 +951,16 @@ RadioInterfaceLayer.prototype = {
   /**
    * Handle data call list.
    */
   handleDataCallList: function handleDataCallList(message) {
     this._deliverDataCallCallback("receiveDataCallList",
                                   [message.datacalls, message.datacalls.length]);
   },
 
-  /**
-   * Handle setting changes.
-   */
-  handleMozSettingsChanged: function handleMozSettingsChanged(setting) {
-    switch (setting.key) {
-      case "ril.radio.disabled":
-        this._radioEnabled = !setting.value;
-        this._ensureRadioState();
-        break;
-      case "ril.data.enabled":
-        // We only watch at "ril.data.enabled" flag changes for connecting or
-        // disconnecting the data call. If the value of "ril.data.enabled" is
-        // true and any of the remaining flags change the setting application
-        // should turn this flag to false and then to true in order to reload
-        // the new values and reconnect the data call.
-        if (!setting.value && RILNetworkInterface.connected) {
-          debug("Data call settings: disconnect data call.");
-          RILNetworkInterface.disconnect();
-        }
-        if (setting.value && !RILNetworkInterface.connected) {
-          debug("Data call settings connect data call.");
-          RILNetworkInterface.connect();
-        }
-        break;
-    }
-  },
-
   handleICCGetCardLock: function handleICCGetCardLock(message) {
     ppmm.sendAsyncMessage("RIL:GetCardLock:Return:OK", message);
   },
 
   handleICCSetCardLock: function handleICCSetCardLock(message) {
     ppmm.sendAsyncMessage("RIL:SetCardLock:Return:OK", message);
   },
 
@@ -983,17 +988,17 @@ RadioInterfaceLayer.prototype = {
   },
 
   // nsIObserver
 
   observe: function observe(subject, topic, data) {
     switch (topic) {
       case kMozSettingsChangedObserverTopic:
         let setting = JSON.parse(data);
-        this.handleMozSettingsChanged(setting);
+        this.handle(setting.key, setting.value);
         break;
       case "xpcom-shutdown":
         for each (let msgname in RIL_IPC_MSG_NAMES) {
           ppmm.removeMessageListener(msgname, this);
         }
         RILNetworkInterface.shutdown();
         ppmm = null;
         Services.obs.removeObserver(this, "xpcom-shutdown");
@@ -1003,29 +1008,59 @@ RadioInterfaceLayer.prototype = {
   },
 
   // nsISettingsServiceCallback
 
   // Flag to determine the radio state to start with when we boot up. It
   // corresponds to the 'ril.radio.disabled' setting from the UI.
   _radioEnabled: null,
 
+  // APN data for making data calls.
+  dataCallSettings: {},
+  _dataCallSettingsToRead: [],
+  _oldRilDataEnabledState: null,
+  
   handle: function handle(aName, aResult) {
-    if (aName == "ril.radio.disabled") {
-      debug("'ril.radio.disabled' is " + aResult);
-      this._radioEnabled = !aResult;
-      this._ensureRadioState();
-    }
+    switch(aName) {
+      case "ril.radio.disabled":
+        debug("'ril.radio.disabled' is now " + aResult);
+        this._radioEnabled = !aResult;
+        this._ensureRadioState();
+        break;
+      case "ril.data.enabled":
+        this._oldRilDataEnabledState = this.dataCallSettings["enabled"];
+        // Fall through!
+      case "ril.data.roaming_enabled":
+      case "ril.data.apn":
+      case "ril.data.user":
+      case "ril.data.passwd":
+      case "ril.data.httpProxyHost":
+      case "ril.data.httpProxyPort":
+        let key = aName.slice(9);
+        this.dataCallSettings[key] = aResult;
+        debug("'" + aName + "'" + " is now " + this.dataCallSettings[key]);
+        let index = this._dataCallSettingsToRead.indexOf(aName);
+        if (index != -1) {
+          this._dataCallSettingsToRead.splice(index, 1);
+        }
+        this.updateRILNetworkInterface();
+        break;
+    };
   },
-
+    
   handleError: function handleError(aErrorMessage) {
-    debug("There was an error reading the 'ril.radio.disabled' setting., " +
-          "default to radio on.");
+    debug("There was an error while reading RIL settings.");
+
+    // Default radio to on.
     this._radioEnabled = true;
     this._ensureRadioState();
+
+    // Clean data call setting. 
+    this.dataCallSettings = {};
+    this.dataCallSettings["enabled"] = false; 
   },
 
   // nsIRadioWorker
 
   worker: null,
 
   // nsIRadioInterfaceLayer
 
@@ -1723,16 +1758,20 @@ let RILNetworkInterface = {
   timer: null,
 
   type: Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE,
 
   name: null,
 
   dhcp: false,
 
+  httpProxyHost: null,
+
+  httpProxyPort: null,
+
   // nsIRILDataCallback
 
   dataCallStateChanged: function dataCallStateChanged(datacall) {
     debug("Data call ID: " + datacall.cid + ", interface name: " + datacall.ifname);
     if (this.connecting &&
         (datacall.state == RIL.GECKO_NETWORK_STATE_CONNECTING ||
          datacall.state == RIL.GECKO_NETWORK_STATE_CONNECTED)) {
       this.connecting = false;
@@ -1762,56 +1801,57 @@ let RILNetworkInterface = {
   },
 
   // Helpers
 
   cid: null,
   registeredAsDataCallCallback: false,
   registeredAsNetworkInterface: false,
   connecting: false,
+  dataCallSettings: {},
 
   // APN failed connections. Retry counter
   apnRetryCounter: 0,
 
   get mRIL() {
     delete this.mRIL;
     return this.mRIL = Cc["@mozilla.org/telephony/system-worker-manager;1"]
                          .getService(Ci.nsIInterfaceRequestor)
                          .getInterface(Ci.nsIRadioInterfaceLayer);
   },
 
   get connected() {
     return this.state == RIL.GECKO_NETWORK_STATE_CONNECTED;
   },
 
-  connect: function connect() {
+  connect: function connect(options) {
     if (this.connecting ||
         this.state == RIL.GECKO_NETWORK_STATE_CONNECTED ||
         this.state == RIL.GECKO_NETWORK_STATE_SUSPENDED) {
       return;
     }
+
     if (!this.registeredAsDataCallCallback) {
       this.mRIL.registerDataCallCallback(this);
       this.registeredAsDataCallCallback = true;
     }
 
-    let apn, user, passwd;
-    // Eventually these values would be retrieved from the user's preferences
-    // via the settings API. For now we just use Gecko's preferences.
-    try {
-      apn = Services.prefs.getCharPref("ril.data.apn");
-      user = Services.prefs.getCharPref("ril.data.user");
-      passwd = Services.prefs.getCharPref("ril.data.passwd");
-    } catch (ex) {
-      debug("No APN settings found, not going to set up data connection.");
-      return;
+    if (options) {
+      // Save the APN data locally for using them in connection retries. 
+      this.dataCallSettings = options;
     }
-    debug("Going to set up data connection with APN " + apn);
+
+    this.httpProxyHost = this.dataCallSettings["httpProxyHost"];
+    this.httpProxyPort = this.dataCallSettings["httpProxyPort"];
+
+    debug("Going to set up data connection with APN " + this.dataCallSettings["apn"]);
     this.mRIL.setupDataCall(RIL.DATACALL_RADIOTECHNOLOGY_GSM,
-                            apn, user, passwd,
+                            this.dataCallSettings["apn"], 
+                            this.dataCallSettings["user"], 
+                            this.dataCallSettings["passwd"],
                             RIL.DATACALL_AUTH_PAP_OR_CHAP, "IP");
     this.connecting = true;
   },
 
   reset: function reset() {
     let apnRetryTimer;
     this.connecting = false;
     // We will retry the connection in increasing times
--- a/dom/system/gonk/nsINetworkManager.idl
+++ b/dom/system/gonk/nsINetworkManager.idl
@@ -2,17 +2,17 @@
  * 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"
 
 /**
  * Information about networks that is exposed to network manager API consumers.
  */
-[scriptable, uuid(e016d594-3072-11e1-9b7d-0010183a41af)]
+[scriptable, uuid(57b56c6f-4c3f-4c55-bf1b-e5af22407931)]
 interface nsINetworkInterface : nsISupports
 {
   const long NETWORK_STATE_UNKNOWN = -1;
   const long NETWORK_STATE_CONNECTING = 0;
   const long NETWORK_STATE_CONNECTED = 1;
   const long NETWORK_STATE_SUSPENDED = 2;
   const long NETWORK_STATE_DISCONNECTING = 3;
   const long NETWORK_STATE_DISCONNECTED = 4;
@@ -39,16 +39,26 @@ interface nsINetworkInterface : nsISuppo
    */
   readonly attribute DOMString name;
 
   /**
    * Indicates whether DHCP should be run when the interface connects.
    */
   readonly attribute boolean dhcp;
 
+  /**
+   * The host name of the http proxy server.
+   */
+  readonly attribute DOMString httpProxyHost;
+
+  /*
+   * The port number of the http proxy server. 
+   */
+  readonly attribute long httpProxyPort;
+
 };
 
 /**
  * Manage network interfaces.
  */
 [scriptable, uuid(3bc29392-2fba-11e1-80fd-0010183a41af)]
 interface nsINetworkManager : nsISupports
 {
--- a/dom/wifi/WifiWorker.js
+++ b/dom/wifi/WifiWorker.js
@@ -1262,16 +1262,20 @@ let WifiNetworkInterface = {
   type: Ci.nsINetworkInterface.NETWORK_TYPE_WIFI,
 
   name: null,
 
   // For now we do our own DHCP. In the future this should be handed off
   // to the Network Manager.
   dhcp: false,
 
+  httpProxyHost: null,
+
+  httpProxyPort: null,
+
 };
 
 
 // TODO Make the difference between a DOM-based network object and our
 // networks objects much clearer.
 let netToDOM;
 let netFromDOM;
 
--- a/hal/gonk/GonkSwitch.cpp
+++ b/hal/gonk/GonkSwitch.cpp
@@ -10,193 +10,354 @@
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * 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.
  */
 
 #include <android/log.h>
+#include <fcntl.h>
 #include <sysutils/NetlinkEvent.h>
 
 #include "base/message_loop.h"
 
 #include "Hal.h"
+#include "mozilla/FileUtils.h"
 #include "mozilla/Monitor.h"
+#include "nsPrintfCString.h"
 #include "nsXULAppAPI.h"
 #include "UeventPoller.h"
 
 using namespace mozilla::hal;
 
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GonkSwitch" , ## args) 
 
+#define SWITCH_HEADSET_DEVPATH "/devices/virtual/switch/h2w"
+#define SWITCH_USB_DEVPATH_GB  "/devices/virtual/switch/usb_configuration"
+#define SWITCH_USB_DEVPATH_ICS "/devices/virtual/android_usb/android0"
+
 namespace mozilla {
 namespace hal_impl {
+/**
+ * The uevent for a headset on SGS2 insertion looks like:
+ * 
+ * change@/devices/virtual/switch/h2w
+ *   ACTION=change
+ *   DEVPATH=/devices/virtual/switch/h2w
+ *   SUBSYSTEM=switch
+ *   SWITCH_NAME=h2w
+ *   SWITCH_STATE=2
+ *   SEQNUM=2581
+ * On Otoro, SWITCH_NAME could be Headset/No Device when plug/unplug.
+ * change@/devices/virtual/switch/h2w
+ *   ACTION=change
+ *   DEVPATH=/devices/virtual/switch/h2w
+ *   SUBSYSTEM=switch
+ *   SWITCH_NAME=Headset
+ *   SWITCH_STATE=1
+ *   SEQNUM=1602
+ * 
+ * The uevent for usb on GB,
+ *  change@/devices/virtual/switch/usb_configuration
+ *    ACTION=change
+ *    DEVPATH=/devices/virtual/switch/usb_configuration
+ *    SUBSYSTEM=switch
+ *    SWITCH_NAME=usb_configuration
+ *    SWITCH_STATE=0
+ *    SEQNUM=5038
+ */ 
+class SwitchHandler : public RefCounted<SwitchHandler>
+{
+public:
+  SwitchHandler(const char* aDevPath, SwitchDevice aDevice)
+    : mDevPath(aDevPath),
+      mState(SWITCH_STATE_UNKNOWN),
+      mDevice(aDevice)
+  {
+    GetInitialState();
+  }
 
-struct {const char* name; SwitchDevice device; } kSwitchNameMap[] = {
-  { "h2w", SWITCH_HEADPHONES },
-  { "usb_configuration", SWITCH_USB },
-  { NULL, SWITCH_DEVICE_UNKNOWN },
+  virtual ~SwitchHandler()
+  {
+  }
+
+  bool CheckEvent(NetlinkEvent* aEvent)
+  {
+    if (strcmp(GetSubsystem(), aEvent->getSubsystem()) ||
+        strcmp(mDevPath, aEvent->findParam("DEVPATH"))) {
+        return false;
+    }
+    
+    mState = ConvertState(GetStateString(aEvent));
+    return mState != SWITCH_STATE_UNKNOWN;
+  }
+
+  SwitchState GetState()
+  { 
+    return mState;
+  }
+
+  SwitchDevice GetType()
+  {
+    return mDevice;
+  }
+protected:
+  virtual const char* GetSubsystem()
+  {
+    return "switch";
+  }
+
+  virtual const char* GetStateString(NetlinkEvent* aEvent)
+  {
+    return aEvent->findParam("SWITCH_STATE");
+  }
+
+  void GetInitialState()
+  {
+    nsPrintfCString statePath("/sys%s/state", mDevPath);
+    int fd = open(statePath.get(), O_RDONLY);
+    if (fd <= 0) {
+      return;
+    }
+
+    ScopedClose autoClose(fd);
+    char state[16];
+    ssize_t bytesRead = read(fd, state, sizeof(state));
+    if (bytesRead < 0) {
+      LOG("Read data from %s fails", statePath.get());
+      return;
+    }
+
+    if (state[bytesRead - 1] == '\n') {
+      bytesRead--;
+    }
+    
+    state[bytesRead] = '\0';
+    mState = ConvertState(state);
+  }
+
+  virtual SwitchState ConvertState(const char* aState)
+  {
+    MOZ_ASSERT(aState);
+    return aState[0] == '0' ? SWITCH_STATE_OFF : SWITCH_STATE_ON;
+  }
+
+  const char* mDevPath;
+  SwitchState mState;
+  SwitchDevice mDevice;
 };
 
-static SwitchDevice
-NameToDevice(const char* name) {
-  for (int i = 0; kSwitchNameMap[i].device != SWITCH_DEVICE_UNKNOWN; i++) {
-    if (strcmp(name, kSwitchNameMap[i].name) == 0) {
-      return kSwitchNameMap[i].device;
-    }
+/**
+ * The uevent delivered for the USB configuration under ICS looks like,
+ *
+ *  change@/devices/virtual/android_usb/android0
+ *    ACTION=change
+ *    DEVPATH=/devices/virtual/android_usb/android0
+ *    SUBSYSTEM=android_usb
+ *    USB_STATE=CONFIGURED
+ *    SEQNUM=1802
+ */
+class SwitchHandlerUsbIcs: public SwitchHandler
+{
+public:
+  SwitchHandlerUsbIcs(const char* aDevPath) : SwitchHandler(aDevPath, SWITCH_USB)
+  {
+    SwitchHandler::GetInitialState();
   }
-  return SWITCH_DEVICE_UNKNOWN;
-}
+
+  virtual ~SwitchHandlerUsbIcs() { }
+
+protected:
+  virtual const char* GetSubsystem()
+  {
+    return "android_usb";
+  }
+
+  virtual const char* GetStateString(NetlinkEvent* aEvent)
+  {
+    return aEvent->findParam("USB_STATE");
+  }
+
+  SwitchState ConvertState(const char* aState)
+  {
+    MOZ_ASSERT(aState);
+    return strcmp(aState, "CONFIGURED") == 0 ? SWITCH_STATE_ON : SWITCH_STATE_OFF;
+  }
+};
+
+typedef nsTArray<RefPtr<SwitchHandler> > SwitchHandlerArray;
 
 class SwitchEventRunnable : public nsRunnable
 {
 public:
-  SwitchEventRunnable(SwitchEvent& event) : mEvent(event) {}
+  SwitchEventRunnable(SwitchEvent& aEvent) : mEvent(aEvent)
+  {
+  }
 
-  NS_IMETHOD Run() {
+  NS_IMETHOD Run()
+  {
     NotifySwitchChange(mEvent);
     return NS_OK;
   }
 private:
   SwitchEvent mEvent;
 };
 
-class SwitchEventObserver : public IUeventObserver
+class SwitchEventObserver : public IUeventObserver,
+                            public RefCounted<SwitchEventObserver>
 {
 public:
-  SwitchEventObserver() : mEnableNum(0) {
-   InternalInit();
+  SwitchEventObserver() : mEnableCount(0)
+  {
+    Init();
   }
-  ~SwitchEventObserver() {}
 
-  int GetEnableCount() {
-    return mEnableNum;
+  ~SwitchEventObserver()
+  {
+    mHandler.Clear();
   }
 
-  void EnableSwitch(SwitchDevice aDevice) {
-    mEventInfo[aDevice].mEnable = true;
-    mEnableNum++;
+  int GetEnableCount()
+  {
+    return mEnableCount;
+  }
+
+  void EnableSwitch(SwitchDevice aDevice)
+  {
+    mEventInfo[aDevice].mEnabled = true;
+    mEnableCount++;
   }
 
-  void DisableSwitch(SwitchDevice aDevice) {
-    mEventInfo[aDevice].mEnable = false;
-    mEnableNum--;
+  void DisableSwitch(SwitchDevice aDevice)
+  {
+    mEventInfo[aDevice].mEnabled = false;
+    mEnableCount--;
   }
 
-  void Notify(const NetlinkEvent& event) {
-    const char* name;
-    const char* state;
-   
-    SwitchDevice device = ProcessEvent(event, &name, &state);
-    if (device == SWITCH_DEVICE_UNKNOWN) { 
+  void Notify(const NetlinkEvent& aEvent)
+  {
+    SwitchState currState;
+    
+    SwitchDevice device = GetEventInfo(aEvent, currState);
+    if (device == SWITCH_DEVICE_UNKNOWN) {
       return; 
-    } 
+    }
 
-    EventInfo& info = mEventInfo[device]; 
-    info.mEvent.status() = atoi(state) == 0 ? SWITCH_STATE_OFF : SWITCH_STATE_ON; 
-    if (info.mEnable) { 
-      NS_DispatchToMainThread(new SwitchEventRunnable(info.mEvent)); 
-    } 
+    EventInfo& info = mEventInfo[device];
+    if (currState == info.mEvent.status()) {
+      return;
+    }
+
+    info.mEvent.status() = currState;
+
+    if (info.mEnabled) {
+      NS_DispatchToMainThread(new SwitchEventRunnable(info.mEvent));
+    }
   }
 
-  SwitchState GetCurrentInformation(SwitchDevice aDevice) {
+  SwitchState GetCurrentInformation(SwitchDevice aDevice)
+  {
     return mEventInfo[aDevice].mEvent.status();
   }
 
+  void NotifyAnEvent(SwitchDevice aDevice)
+  {
+    EventInfo& info = mEventInfo[aDevice];
+    if (info.mEvent.status() != SWITCH_STATE_UNKNOWN) {
+      NS_DispatchToMainThread(new SwitchEventRunnable(info.mEvent));
+    }
+  }
 private:
-  class EventInfo {
+  class EventInfo
+  {
   public:
-    EventInfo() : mEnable(false) {}
+    EventInfo() : mEnabled(false)
+    {
+      mEvent.status() = SWITCH_STATE_UNKNOWN;
+      mEvent.device() = SWITCH_DEVICE_UNKNOWN;
+    }
     SwitchEvent mEvent;
-    bool mEnable;
+    bool mEnabled;
   };
 
   EventInfo mEventInfo[NUM_SWITCH_DEVICE];
-  size_t mEnableNum;
+  size_t mEnableCount;
+  SwitchHandlerArray mHandler;
 
-  void InternalInit() {
-    for (int i = 0; i < NUM_SWITCH_DEVICE; i++) {
-      mEventInfo[i].mEvent.device() = kSwitchNameMap[i].device;
-      mEventInfo[i].mEvent.status() = SWITCH_STATE_UNKNOWN;
+  void Init()
+  {
+    mHandler.AppendElement(new SwitchHandler(SWITCH_HEADSET_DEVPATH, SWITCH_HEADPHONES));
+    mHandler.AppendElement(new SwitchHandler(SWITCH_USB_DEVPATH_GB, SWITCH_USB));
+    mHandler.AppendElement(new SwitchHandlerUsbIcs(SWITCH_USB_DEVPATH_ICS));
+    
+    SwitchHandlerArray::index_type handlerIndex;
+    SwitchHandlerArray::size_type numHandlers = mHandler.Length();
+
+    for (handlerIndex = 0; handlerIndex < numHandlers; handlerIndex++) {
+      SwitchState state = mHandler[handlerIndex]->GetState();
+      if (state == SWITCH_STATE_UNKNOWN) {
+        continue;
+      }
+
+      SwitchDevice device = mHandler[handlerIndex]->GetType();
+      mEventInfo[device].mEvent.device() = device;
+      mEventInfo[device].mEvent.status() = state;
     }
   }
 
-  bool GetEventInfo(const NetlinkEvent& event, const char** name, const char** state) {
+  SwitchDevice GetEventInfo(const NetlinkEvent& aEvent, SwitchState& aState)
+  {
     //working around the android code not being const-correct
-    NetlinkEvent *e = const_cast<NetlinkEvent*>(&event);
-    const char* subsystem = e->getSubsystem();
-
-    if (subsystem && (strcmp(subsystem, "android_usb") == 0)) {
-      // Under GB, usb cable plugin was done using a virtual switch
-      // (usb_configuration). Under ICS, they changed to using the
-      // android_usb device, so we emulate the usb_configuration switch.
-
-      *name = "usb_configuration";
-      const char *usb_state = e->findParam("USB_STATE");
-      if (!usb_state) {
-        return false;
-      }
-      if (strcmp(usb_state, "CONFIGURED") == 0) {
-        *state = "1";
-        return true;
+    NetlinkEvent *e = const_cast<NetlinkEvent*>(&aEvent);
+    
+    for (size_t i = 0; i < mHandler.Length(); i++) {
+      if (mHandler[i]->CheckEvent(e)) {
+        aState = mHandler[i]->GetState();
+        return mHandler[i]->GetType();
       }
-      *state = "0";
-      return true;
     }
-
-    if (!subsystem || strcmp(subsystem, "switch")) {
-      return false;
-    }
-
-    *name = e->findParam("SWITCH_NAME");
-    *state = e->findParam("SWITCH_STATE");
-
-    if (!*name || !*state) {
-      return false;
-    }
-    return true;
-  }
-
-  SwitchDevice ProcessEvent(const NetlinkEvent& event, const char** name, const char** state) {
-    return GetEventInfo(event, name, state) ?
-      NameToDevice(*name) : SWITCH_DEVICE_UNKNOWN;
+    return SWITCH_DEVICE_UNKNOWN;
   }
 };
 
-SwitchEventObserver* sSwitchObserver;
+static RefPtr<SwitchEventObserver> sSwitchObserver;
 
 static void
 InitializeResourceIfNeed()
 {
   if (!sSwitchObserver) {
     sSwitchObserver = new SwitchEventObserver();
     RegisterUeventListener(sSwitchObserver);
   }
 }
 
 static void
 ReleaseResourceIfNeed()
 {
   if (sSwitchObserver->GetEnableCount() == 0) {
     UnregisterUeventListener(sSwitchObserver);
-    delete sSwitchObserver;
     sSwitchObserver = NULL;
   }
 }
 
 static void
 EnableSwitchNotificationsIOThread(SwitchDevice aDevice, Monitor *aMonitor)
 {
   InitializeResourceIfNeed();
   sSwitchObserver->EnableSwitch(aDevice);
   {
     MonitorAutoLock lock(*aMonitor);
     lock.Notify();
   }
+
+  // Notify the latest state if IO thread has the information. 
+  if (sSwitchObserver->GetEnableCount() > 1) {
+    sSwitchObserver->NotifyAnEvent(aDevice);
+  }
 }
 
 void
 EnableSwitchNotifications(SwitchDevice aDevice)
 {
   Monitor monitor("EnableSwitch.monitor");
   {
     MonitorAutoLock lock(monitor);
--- a/widget/cocoa/nsCocoaWindow.h
+++ b/widget/cocoa/nsCocoaWindow.h
@@ -14,16 +14,19 @@
 #include "nsPIWidgetCocoa.h"
 #include "nsAutoPtr.h"
 #include "nsCocoaUtils.h"
 
 class nsCocoaWindow;
 class nsChildView;
 class nsMenuBarX;
 
+// Value copied from BITMAP_MAX_AREA, used in nsNativeThemeCocoa.mm
+#define CUIDRAW_MAX_AREA 500000
+
 // If we are using an SDK older than 10.7, define bits we need that are missing
 // from it.
 #if !defined(MAC_OS_X_VERSION_10_7) || \
     MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
 
 enum {
     NSWindowAnimationBehaviorDefault = 0,
     NSWindowAnimationBehaviorNone = 2,
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -2754,16 +2754,19 @@ static const NSString* kStateShowsToolba
   }
   return self;
 }
 
 static void
 DrawNativeTitlebar(CGContextRef aContext, CGRect aTitlebarRect,
                    float aToolbarHeight, BOOL aIsMain)
 {
+  if (aTitlebarRect.size.width * aTitlebarRect.size.height > CUIDRAW_MAX_AREA) {
+    return;
+  }
   int unifiedHeight = aTitlebarRect.size.height + aToolbarHeight;
   CUIDraw([NSWindow coreUIRenderer], aTitlebarRect, aContext,
           (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
             @"kCUIWidgetWindowFrame", @"widget",
             @"regularwin", @"windowtype",
             (aIsMain ? @"normal" : @"inactive"), @"state",
             [NSNumber numberWithInt:unifiedHeight], @"kCUIWindowFrameUnifiedTitleBarHeightKey",
             [NSNumber numberWithBool:YES], @"kCUIWindowFrameDrawTitleSeparatorKey",
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -1589,16 +1589,19 @@ nsNativeThemeCocoa::DrawSegment(CGContex
   if (isSelected && aSettings.ignoresPressedWhenSelected) {
     isPressed = NO;
   }
 
   BOOL isRTL = IsFrameRTL(aFrame);
   nsIFrame* left = GetAdjacentSiblingFrameWithSameAppearance(aFrame, isRTL);
   nsIFrame* right = GetAdjacentSiblingFrameWithSameAppearance(aFrame, !isRTL);
   CGRect drawRect = SeparatorAdjustedRect(inBoxRect, left, aFrame, right);
+  if (drawRect.size.width * drawRect.size.height > CUIDRAW_MAX_AREA) {
+    return;
+  }
   BOOL drawLeftSeparator = SeparatorResponsibility(left, aFrame) == aFrame;
   BOOL drawRightSeparator = SeparatorResponsibility(aFrame, right) == aFrame;
   NSControlSize controlSize = FindControlSize(drawRect.size.height, aSettings.heights, 4.0f);
 
   CUIDraw([NSWindow coreUIRenderer], drawRect, cgContext,
           (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
             aSettings.widgetName, @"widget",
             ToolbarButtonPosition(!left, !right), @"kCUIPositionKey",
@@ -1787,26 +1790,28 @@ nsNativeThemeCocoa::DrawUnifiedToolbar(C
   float unifiedHeight = titlebarHeight + inBoxRect.size.height;
 
   BOOL isMain = [aWindow isMainWindow] || ![NSView focusView];
 
   CGContextSaveGState(cgContext);
   CGContextClipToRect(cgContext, inBoxRect);
 
   CGRect drawRect = CGRectOffset(inBoxRect, 0, -titlebarHeight);
-  CUIDraw([NSWindow coreUIRenderer], drawRect, cgContext,
-          (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
-            @"kCUIWidgetWindowFrame", @"widget",
-            @"regularwin", @"windowtype",
-            (isMain ? @"normal" : @"inactive"), @"state",
-            [NSNumber numberWithInt:unifiedHeight], @"kCUIWindowFrameUnifiedTitleBarHeightKey",
-            [NSNumber numberWithBool:YES], @"kCUIWindowFrameDrawTitleSeparatorKey",
-            [NSNumber numberWithBool:YES], @"is.flipped",
-            nil],
-          nil);
+  if (drawRect.size.width * drawRect.size.height <= CUIDRAW_MAX_AREA) {
+    CUIDraw([NSWindow coreUIRenderer], drawRect, cgContext,
+            (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
+              @"kCUIWidgetWindowFrame", @"widget",
+              @"regularwin", @"windowtype",
+              (isMain ? @"normal" : @"inactive"), @"state",
+              [NSNumber numberWithInt:unifiedHeight], @"kCUIWindowFrameUnifiedTitleBarHeightKey",
+              [NSNumber numberWithBool:YES], @"kCUIWindowFrameDrawTitleSeparatorKey",
+              [NSNumber numberWithBool:YES], @"is.flipped",
+              nil],
+            nil);
+  }
 
   CGContextRestoreGState(cgContext);
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 void
 nsNativeThemeCocoa::DrawStatusBar(CGContextRef cgContext, const HIRect& inBoxRect,
@@ -1822,26 +1827,28 @@ nsNativeThemeCocoa::DrawStatusBar(CGCont
 
   // kCUIWidgetWindowFrame draws a complete window frame with both title bar
   // and bottom bar. We only want the bottom bar, so we extend the draw rect
   // upwards to make space for the title bar, and then we clip it away.
   CGRect drawRect = inBoxRect;
   const int extendUpwards = 40;
   drawRect.origin.y -= extendUpwards;
   drawRect.size.height += extendUpwards;
-  CUIDraw([NSWindow coreUIRenderer], drawRect, cgContext,
-          (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
-            @"kCUIWidgetWindowFrame", @"widget",
-            @"regularwin", @"windowtype",
-            (IsActive(aFrame, YES) ? @"normal" : @"inactive"), @"state",
-            [NSNumber numberWithInt:inBoxRect.size.height], @"kCUIWindowFrameBottomBarHeightKey",
-            [NSNumber numberWithBool:YES], @"kCUIWindowFrameDrawBottomBarSeparatorKey",
-            [NSNumber numberWithBool:YES], @"is.flipped",
-            nil],
-          nil);
+  if (drawRect.size.width * drawRect.size.height <= CUIDRAW_MAX_AREA) {
+    CUIDraw([NSWindow coreUIRenderer], drawRect, cgContext,
+            (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
+              @"kCUIWidgetWindowFrame", @"widget",
+              @"regularwin", @"windowtype",
+              (IsActive(aFrame, YES) ? @"normal" : @"inactive"), @"state",
+              [NSNumber numberWithInt:inBoxRect.size.height], @"kCUIWindowFrameBottomBarHeightKey",
+              [NSNumber numberWithBool:YES], @"kCUIWindowFrameDrawBottomBarSeparatorKey",
+              [NSNumber numberWithBool:YES], @"is.flipped",
+              nil],
+            nil);
+  }
 
   CGContextRestoreGState(cgContext);
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 static void
 RenderResizer(CGContextRef cgContext, const HIRect& aRenderRect, void* aData)