Merge b2g-inbound to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 08 Jan 2014 15:22:14 -0500
changeset 162544 8988416e489d5c942056fe9bc6556882c4d61621
parent 162518 f99c42bb080edb87eb49337d3f3d39e92a1246b3 (current diff)
parent 162543 ae40bf26e4d45d5d2619ee734ff32f221faee878 (diff)
child 162561 9ca0f64ee6341d338ad0281b23264a04c1d24960
push id25958
push userryanvm@gmail.com
push dateWed, 08 Jan 2014 20:22:21 +0000
treeherdermozilla-central@8988416e489d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge b2g-inbound to m-c.
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "65400ea2bb3e99ad717f4b99e24ebbfa23b05b58", 
+    "revision": "3b850fa17c888bdd31f1a163fd7b92f6f020449d", 
     "repo_path": "/integration/gaia-central"
 }
--- a/content/media/encoder/OpusTrackEncoder.cpp
+++ b/content/media/encoder/OpusTrackEncoder.cpp
@@ -282,18 +282,18 @@ OpusTrackEncoder::GetEncodedTrack(Encode
     // Chunk to the required frame size.
     int frameToCopy = chunk.GetDuration();
     if (frameCopied + frameToCopy > GetPacketDuration()) {
       frameToCopy = GetPacketDuration() - frameCopied;
     }
 
     if (!chunk.IsNull()) {
       // Append the interleaved data to the end of pcm buffer.
-      InterleaveTrackData(chunk, frameToCopy, mChannels,
-                          pcm.Elements() + frameCopied * mChannels);
+      AudioTrackEncoder::InterleaveTrackData(chunk, frameToCopy, mChannels,
+        pcm.Elements() + frameCopied * mChannels);
     } else {
       memset(pcm.Elements() + frameCopied * mChannels, 0,
              frameToCopy * mChannels * sizeof(AudioDataValue));
     }
 
     frameCopied += frameToCopy;
     iter.Next();
   }
--- a/content/media/encoder/TrackEncoder.cpp
+++ b/content/media/encoder/TrackEncoder.cpp
@@ -101,34 +101,35 @@ AudioTrackEncoder::AppendAudioSegment(co
   }
 
   return NS_OK;
 }
 
 static const int AUDIO_PROCESSING_FRAMES = 640; /* > 10ms of 48KHz audio */
 static const uint8_t gZeroChannel[MAX_AUDIO_SAMPLE_SIZE*AUDIO_PROCESSING_FRAMES] = {0};
 
+/*static*/
 void
 AudioTrackEncoder::InterleaveTrackData(AudioChunk& aChunk,
                                        int32_t aDuration,
                                        uint32_t aOutputChannels,
                                        AudioDataValue* aOutput)
 {
   if (aChunk.mChannelData.Length() < aOutputChannels) {
     // Up-mix. This might make the mChannelData have more than aChannels.
     AudioChannelsUpMix(&aChunk.mChannelData, aOutputChannels, gZeroChannel);
   }
 
   if (aChunk.mChannelData.Length() > aOutputChannels) {
     DownmixAndInterleave(aChunk.mChannelData, aChunk.mBufferFormat, aDuration,
-                         aChunk.mVolume, mChannels, aOutput);
+                         aChunk.mVolume, aOutputChannels, aOutput);
   } else {
     InterleaveAndConvertBuffer(aChunk.mChannelData.Elements(),
                                aChunk.mBufferFormat, aDuration, aChunk.mVolume,
-                               mChannels, aOutput);
+                               aOutputChannels, aOutput);
   }
 }
 
 void
 VideoTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
                                             TrackID aID,
                                             TrackRate aTrackRate,
                                             TrackTicks aTrackOffset,
--- a/content/media/encoder/TrackEncoder.h
+++ b/content/media/encoder/TrackEncoder.h
@@ -143,16 +143,26 @@ public:
   {}
 
   void NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
                                 TrackRate aTrackRate,
                                 TrackTicks aTrackOffset,
                                 uint32_t aTrackEvents,
                                 const MediaSegment& aQueuedMedia) MOZ_OVERRIDE;
 
+  /**
+   * Interleaves the track data and stores the result into aOutput. Might need
+   * to up-mix or down-mix the channel data if the channels number of this chunk
+   * is different from aOutputChannels. The channel data from aChunk might be
+   * modified by up-mixing.
+   */
+  static void InterleaveTrackData(AudioChunk& aChunk, int32_t aDuration,
+                                  uint32_t aOutputChannels,
+                                  AudioDataValue* aOutput);
+
 protected:
   /**
    * Number of samples per channel in a pcm buffer. This is also the value of
    * frame size required by audio encoder, and mReentrantMonitor will be
    * notified when at least this much data has been added to mRawSegment.
    */
   virtual int GetPacketDuration() { return 0; }
 
@@ -175,25 +185,16 @@ protected:
 
   /**
    * Notifies the audio encoder that we have reached the end of source stream,
    * and wakes up mReentrantMonitor if encoder is waiting for more track data.
    */
   virtual void NotifyEndOfStream() MOZ_OVERRIDE;
 
   /**
-   * Interleaves the track data and stores the result into aOutput. Might need
-   * to up-mix or down-mix the channel data if the channels number of this chunk
-   * is different from mChannels. The channel data from aChunk might be modified
-   * by up-mixing.
-   */
-  void InterleaveTrackData(AudioChunk& aChunk, int32_t aDuration,
-                           uint32_t aOutputChannels, AudioDataValue* aOutput);
-
-  /**
    * The number of channels are used for processing PCM data in the audio encoder.
    * This value comes from the first valid audio chunk. If encoder can't support
    * the channels in the chunk, downmix PCM stream can be performed.
    * This value also be used to initialize the audio encoder.
    */
   int mChannels;
 
   /**
--- a/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp
@@ -5,17 +5,19 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "base/basictypes.h"
 
 #include "BluetoothA2dpManager.h"
 
 #include <hardware/bluetooth.h>
 #include <hardware/bt_av.h>
+#if ANDROID_VERSION > 17
 #include <hardware/bt_rc.h>
+#endif
 
 #include "BluetoothCommon.h"
 #include "BluetoothService.h"
 #include "BluetoothSocket.h"
 #include "BluetoothUtils.h"
 
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
 #include "mozilla/Services.h"
@@ -26,17 +28,19 @@
 
 using namespace mozilla;
 USING_BLUETOOTH_NAMESPACE
 
 namespace {
   StaticRefPtr<BluetoothA2dpManager> sBluetoothA2dpManager;
   bool sInShutdown = false;
   static const btav_interface_t* sBtA2dpInterface;
+#if ANDROID_VERSION > 17
   static const btrc_interface_t* sBtAvrcpInterface;
+#endif
 } // anonymous namespace
 
 class SinkPropertyChangedHandler : public nsRunnable
 {
 public:
   SinkPropertyChangedHandler(const BluetoothSignal& aSignal)
     : mSignal(aSignal)
   {
@@ -77,16 +81,17 @@ public:
     BluetoothService* bs = BluetoothService::Get();
     NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
     bs->DistributeSignal(signal);
 
     return NS_OK;
   }
 };
 
+#if ANDROID_VERSION > 17
 class UpdateRegisterNotificationTask : public nsRunnable
 {
 public:
   UpdateRegisterNotificationTask(btrc_event_id_t aEventId, uint32_t aParam)
     : mEventId(aEventId)
     , mParam(aParam)
   {
     MOZ_ASSERT(!NS_IsMainThread());
@@ -168,16 +173,17 @@ public:
     sBtAvrcpInterface->get_element_attr_rsp(mNumAttr, attrs);
 
     return NS_OK;
   }
 private:
   uint8_t mNumAttr;
   btrc_media_attr_t* mPlayerAttrs;
 };
+#endif
 
 NS_IMETHODIMP
 BluetoothA2dpManager::Observe(nsISupports* aSubject,
                               const char* aTopic,
                               const char16_t* aData)
 {
   MOZ_ASSERT(sBluetoothA2dpManager);
 
@@ -259,16 +265,17 @@ A2dpAudioStateCallback(btav_audio_state_
   props.AppendElement(
     BluetoothNamedValue(NS_LITERAL_STRING("State"), a2dpState));
 
   BluetoothSignal signal(NS_LITERAL_STRING("AudioSink"),
                          remoteDeviceBdAddress, props);
   NS_DispatchToMainThread(new SinkPropertyChangedHandler(signal));
 }
 
+#if ANDROID_VERSION > 17
 /*
  * Avrcp 1.3 callbacks
  */
 
 /*
  * This function is to request Gaia player application to update
  * current play status.
  * Callback for play status request
@@ -364,35 +371,80 @@ AvrcpGetPlayerAppValuesTextCallback(uint
 
 static void
 AvrcpSetPlayerAppValueCallback(btrc_player_settings_t* aPlayerVals)
 {
   MOZ_ASSERT(!NS_IsMainThread());
 
 // TODO: Support avrcp application setting related functions
 }
+#endif
+
+#if ANDROID_VERSION > 18
+/*
+ * This callback function is to get CT features from Feature Bit Mask.
+ * If Advanced Control Player bit is set, CT supports
+ * volume sync (absolute volume feature). If Browsing bit is set, Avrcp 1.4
+ * Browse feature will be supported
+ */
+static void
+AvrcpRemoteFeaturesCallback(bt_bdaddr_t* aBdAddress,
+                            btrc_remote_features_t aFeatures)
+{
+// TODO: Support avrcp 1.4 absolute volume/browse
+}
+
+/*
+ * This callback function is to get notification that volume changed on the
+ * remote car kit (if it supports Avrcp 1.4), not notification from phone.
+ */
+static void
+AvrcpRemoteVolumeChangedCallback(uint8_t aVolume, uint8_t aCType)
+{
+// TODO: Support avrcp 1.4 absolute volume/browse
+}
+
+/*
+ * This callback function is to get notification that volume changed on the
+ * remote car kit (if it supports Avrcp 1.4), not notification from phone.
+ */
+static void
+AvrcpPassThroughCallback(int id, int key_state)
+{
+// TODO: Support avrcp 1.4 absolute volume/browse
+}
+#endif
 
 static btav_callbacks_t sBtA2dpCallbacks = {
   sizeof(sBtA2dpCallbacks),
   A2dpConnectionStateCallback,
   A2dpAudioStateCallback
 };
 
+#if ANDROID_VERSION > 17
 static btrc_callbacks_t sBtAvrcpCallbacks = {
   sizeof(sBtAvrcpCallbacks),
+#if ANDROID_VERSION > 18
+  AvrcpRemoteFeaturesCallback,
+#endif
   AvrcpGetPlayStatusCallback,
   AvrcpListPlayerAppAttributeCallback,
   AvrcpListPlayerAppValuesCallback,
   AvrcpGetPlayerAppValueCallback,
   AvrcpGetPlayerAppAttrsTextCallback,
   AvrcpGetPlayerAppValuesTextCallback,
   AvrcpSetPlayerAppValueCallback,
   AvrcpGetElementAttrCallback,
-  AvrcpRegisterNotificationCallback
+  AvrcpRegisterNotificationCallback,
+#if ANDROID_VERSION > 18
+  AvrcpRemoteVolumeChangedCallback,
+  AvrcpPassThroughCallback
+#endif
 };
+#endif
 
 /*
  * This function will be only called when Bluetooth is turning on.
  * It is important to register a2dp callbacks before enable() gets called.
  * It is required to register a2dp callbacks before a2dp media task
  * starts up.
  */
 bool
@@ -406,25 +458,27 @@ BluetoothA2dpManager::Init()
   NS_ENSURE_TRUE(sBtA2dpInterface, false);
 
   int ret = sBtA2dpInterface->init(&sBtA2dpCallbacks);
   if (ret != BT_STATUS_SUCCESS) {
     BT_LOGR("Warning: failed to init a2dp module");
     return false;
   }
 
+#if ANDROID_VERSION > 17
   sBtAvrcpInterface = (btrc_interface_t *)btInf->
     get_profile_interface(BT_PROFILE_AV_RC_ID);
   NS_ENSURE_TRUE(sBtAvrcpInterface, false);
 
   ret = sBtAvrcpInterface->init(&sBtAvrcpCallbacks);
   if (ret != BT_STATUS_SUCCESS) {
     BT_LOGR("Warning: failed to init avrcp module");
     return false;
   }
+#endif
 
   return true;
 }
 
 BluetoothA2dpManager::~BluetoothA2dpManager()
 {
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   NS_ENSURE_TRUE_VOID(obs);
@@ -763,16 +817,17 @@ BluetoothA2dpManager::UpdateMetaData(con
                                      const nsAString& aArtist,
                                      const nsAString& aAlbum,
                                      uint32_t aMediaNumber,
                                      uint32_t aTotalMediaCount,
                                      uint32_t aDuration)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
+#if ANDROID_VERSION > 17
   NS_ENSURE_TRUE_VOID(sBtAvrcpInterface);
 
   // Send track changed and position changed if track num is not the same.
   // See also AVRCP 1.3 Spec 5.4.2
   if (mMediaNumber != aMediaNumber &&
       mTrackChangedNotifyType == BTRC_NOTIFICATION_TYPE_INTERIM) {
     btrc_register_notification_t param;
     // convert to network big endian format
@@ -797,29 +852,31 @@ BluetoothA2dpManager::UpdateMetaData(con
   }
 
   mTitle.Assign(aTitle);
   mArtist.Assign(aArtist);
   mAlbum.Assign(aAlbum);
   mMediaNumber = aMediaNumber;
   mTotalMediaCount = aTotalMediaCount;
   mDuration = aDuration;
+#endif
 }
 
 /*
  * This function is to reply AvrcpGetPlayStatusCallback (play-status-request)
  * from media player application (Gaia side)
  */
 void
 BluetoothA2dpManager::UpdatePlayStatus(uint32_t aDuration,
                                        uint32_t aPosition,
                                        ControlPlayStatus aPlayStatus)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
+#if ANDROID_VERSION > 17
   NS_ENSURE_TRUE_VOID(sBtAvrcpInterface);
   // when play status changed, send both play status and position
   if (mPlayStatus != aPlayStatus &&
       mPlayStatusChangedNotifyType == BTRC_NOTIFICATION_TYPE_INTERIM) {
     btrc_register_notification_t param;
     param.play_status = (btrc_play_status_t)aPlayStatus;
     mPlayStatusChangedNotifyType = BTRC_NOTIFICATION_TYPE_CHANGED;
     sBtAvrcpInterface->register_notification_rsp(BTRC_EVT_PLAY_STATUS_CHANGED,
@@ -837,30 +894,32 @@ BluetoothA2dpManager::UpdatePlayStatus(u
                                                  &param);
   }
 
   sBtAvrcpInterface->get_play_status_rsp((btrc_play_status_t)aPlayStatus,
                                          aDuration, aPosition);
   mDuration = aDuration;
   mPosition = aPosition;
   mPlayStatus = aPlayStatus;
+#endif
 }
 
 /*
  * This function handles RegisterNotification request from
  * AvrcpRegisterNotificationCallback, which updates current
  * track/status/position status.
  *
  * aParam is only valid when position changed
  */
 void
 BluetoothA2dpManager::UpdateRegisterNotification(int aEventId, int aParam)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
+#if ANDROID_VERSION > 17
   NS_ENSURE_TRUE_VOID(sBtAvrcpInterface);
 
   btrc_register_notification_t param;
 
   switch (aEventId) {
     case BTRC_EVT_PLAY_STATUS_CHANGED:
       mPlayPosChangedNotifyType = BTRC_NOTIFICATION_TYPE_INTERIM;
       param.play_status = (btrc_play_status_t)mPlayStatus;
@@ -880,16 +939,17 @@ BluetoothA2dpManager::UpdateRegisterNoti
       break;
     default:
       break;
   }
 
   sBtAvrcpInterface->register_notification_rsp((btrc_event_id_t)aEventId,
                                                BTRC_NOTIFICATION_TYPE_INTERIM,
                                                &param);
+#endif
 }
 
 void
 BluetoothA2dpManager::GetAlbum(nsAString& aAlbum)
 {
   aAlbum.Assign(mAlbum);
 }
 
--- a/dom/network/interfaces/nsIMobileConnectionProvider.idl
+++ b/dom/network/interfaces/nsIMobileConnectionProvider.idl
@@ -30,29 +30,38 @@ interface nsIMobileConnectionListener : 
   void notifyIccChanged();
   void notifyRadioStateChanged();
 };
 
 /**
  * XPCOM component (in the content process) that provides the mobile
  * network information.
  */
-[scriptable, uuid(0e027520-dd87-461d-88a6-c3e46369c03c)]
+[scriptable, uuid(55b8d918-8631-4d72-a9d7-f8c9536d6e6f)]
 interface nsIMobileConnectionProvider : nsISupports
 {
   /**
    * Called when a content process registers receiving unsolicited messages from
    * RadioInterfaceLayer in the chrome process. Only a content process that has
    * the 'mobileconnection' permission is allowed to register.
    */
   void registerMobileConnectionMsg(in unsigned long clientId,
                                    in nsIMobileConnectionListener listener);
   void unregisterMobileConnectionMsg(in unsigned long clientId,
                                      in nsIMobileConnectionListener listener);
 
+  /**
+   * These two fields require the 'mobilenetwork' permission.
+   */
+  DOMString getLastKnownNetwork(in unsigned long clientId);
+  DOMString getLastKnownHomeNetwork(in unsigned long clientId);
+
+  /**
+   * All fields below require the 'mobileconnection' permission.
+   */
   nsIDOMMozMobileConnectionInfo getVoiceConnectionInfo(in unsigned long clientId);
   nsIDOMMozMobileConnectionInfo getDataConnectionInfo(in unsigned long clientId);
   DOMString getIccId(in unsigned long clientId);
   DOMString getNetworkSelectionMode(in unsigned long clientId);
   DOMString getRadioState(in unsigned long clientId);
 
   nsIDOMDOMRequest getNetworks(in unsigned long clientId,
                                in nsIDOMWindow window);
--- a/dom/network/src/MobileConnection.cpp
+++ b/dom/network/src/MobileConnection.cpp
@@ -128,31 +128,29 @@ NS_IMETHODIMP
 MobileConnection::GetLastKnownNetwork(nsAString& aNetwork)
 {
   aNetwork.SetIsVoid(true);
 
   if (!CheckPermission("mobilenetwork")) {
     return NS_OK;
   }
 
-  aNetwork = mozilla::Preferences::GetString("ril.lastKnownNetwork");
-  return NS_OK;
+  return mProvider->GetLastKnownNetwork(mClientId, aNetwork);
 }
 
 NS_IMETHODIMP
 MobileConnection::GetLastKnownHomeNetwork(nsAString& aNetwork)
 {
   aNetwork.SetIsVoid(true);
 
   if (!CheckPermission("mobilenetwork")) {
     return NS_OK;
   }
 
-  aNetwork = mozilla::Preferences::GetString("ril.lastKnownHomeNetwork");
-  return NS_OK;
+  return mProvider->GetLastKnownHomeNetwork(mClientId, aNetwork);
 }
 
 // All fields below require the "mobileconnection" permission.
 
 bool
 MobileConnection::CheckPermission(const char* aType)
 {
   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
--- a/dom/network/tests/marionette/manifest.ini
+++ b/dom/network/tests/marionette/manifest.ini
@@ -14,8 +14,9 @@ disabled = Bug 808783
 [test_mobile_data_location.js]
 [test_mobile_data_state.js]
 [test_mobile_mmi.js]
 [test_mobile_roaming_preference.js]
 [test_call_barring_get_option.js]
 [test_call_barring_set_error.js]
 [test_call_barring_change_password.js]
 [test_mobile_set_radio.js]
+[test_mobile_last_known_network.js]
new file mode 100644
--- /dev/null
+++ b/dom/network/tests/marionette/test_mobile_last_known_network.js
@@ -0,0 +1,47 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 30000;
+
+SpecialPowers.addPermission("mobilenetwork", true, document);
+
+let connection = navigator.mozMobileConnections[0];
+ok(connection instanceof MozMobileConnection,
+   "connection is instanceof " + connection.constructor);
+
+
+function testLastKnownNetwork() {
+  log("testLastKnownNetwork: " + connection.lastKnownNetwork);
+  // The emulator's hard coded operatoer's mcc and mnc codes.
+  is(connection.lastKnownNetwork, "310-260");
+  runNextTest();
+}
+
+function testLastKnownHomeNetwork() {
+  log("testLastKnownHomeNetwork: " + connection.lastKnownHomeNetwork);
+  // The emulator's hard coded icc's mcc and mnc codes.
+  is(connection.lastKnownHomeNetwork, "310-260");
+  runNextTest();
+}
+
+let tests = [
+  testLastKnownNetwork,
+  testLastKnownHomeNetwork
+];
+
+function runNextTest() {
+  let test = tests.shift();
+  if (!test) {
+    cleanUp();
+    return;
+  }
+
+  test();
+}
+
+function cleanUp() {
+  SpecialPowers.removePermission("mobilenetwork", document);
+  finish();
+}
+
+runNextTest();
--- a/dom/system/gonk/RILContentHelper.js
+++ b/dom/system/gonk/RILContentHelper.js
@@ -638,16 +638,28 @@ RILContentHelper.prototype = {
     let context = this.getRilContext(clientId);
     return context && context.cardState;
   },
 
   /**
    * nsIMobileConnectionProvider
    */
 
+  getLastKnownNetwork: function getLastKnownNetwork(clientId) {
+    return cpmm.sendSyncMessage("RIL:GetLastKnownNetwork", {
+      clientId: clientId
+    })[0];
+  },
+
+  getLastKnownHomeNetwork: function getLastKnownHomeNetwork(clientId) {
+    return cpmm.sendSyncMessage("RIL:GetLastKnownHomeNetwork", {
+      clientId: clientId
+    })[0];
+  },
+
   getVoiceConnectionInfo: function getVoiceConnectionInfo(clientId) {
     let context = this.getRilContext(clientId);
     return context && context.voiceConnectionInfo;
   },
 
   getDataConnectionInfo: function getDataConnectionInfo(clientId) {
     let context = this.getRilContext(clientId);
     return context && context.dataConnectionInfo;
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -113,16 +113,21 @@ const RIL_IPC_MOBILECONNECTION_MSG_NAMES
   "RIL:SetRoamingPreference",
   "RIL:GetRoamingPreference",
   "RIL:ExitEmergencyCbMode",
   "RIL:SetRadioEnabled",
   "RIL:SetVoicePrivacyMode",
   "RIL:GetVoicePrivacyMode"
 ];
 
+const RIL_IPC_MOBILENETWORK_MSG_NAMES = [
+  "RIL:GetLastKnownNetwork",
+  "RIL:GetLastKnownHomeNetwork"
+];
+
 const RIL_IPC_ICCMANAGER_MSG_NAMES = [
   "RIL:SendStkResponse",
   "RIL:SendStkMenuSelection",
   "RIL:SendStkTimerExpiration",
   "RIL:SendStkEventDownload",
   "RIL:GetCardLockState",
   "RIL:UnlockCardLock",
   "RIL:SetCardLock",
@@ -230,32 +235,38 @@ XPCOMUtils.defineLazyGetter(this, "gMess
       this._unregisterMessageListeners();
     },
 
     _registerMessageListeners: function _registerMessageListeners() {
       ppmm.addMessageListener("child-process-shutdown", this);
       for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) {
         ppmm.addMessageListener(msgname, this);
       }
+      for (let msgname of RIL_IPC_MOBILENETWORK_MSG_NAMES) {
+        ppmm.addMessageListener(msgname, this);
+      }
       for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) {
         ppmm.addMessageListener(msgName, this);
       }
       for (let msgname of RIL_IPC_VOICEMAIL_MSG_NAMES) {
         ppmm.addMessageListener(msgname, this);
       }
       for (let msgname of RIL_IPC_CELLBROADCAST_MSG_NAMES) {
         ppmm.addMessageListener(msgname, this);
       }
     },
 
     _unregisterMessageListeners: function _unregisterMessageListeners() {
       ppmm.removeMessageListener("child-process-shutdown", this);
       for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) {
         ppmm.removeMessageListener(msgname, this);
       }
+      for (let msgname of RIL_IPC_MOBILENETWORK_MSG_NAMES) {
+        ppmm.removeMessageListener(msgname, this);
+      }
       for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) {
         ppmm.removeMessageListener(msgName, this);
       }
       for (let msgname of RIL_IPC_VOICEMAIL_MSG_NAMES) {
         ppmm.removeMessageListener(msgname, this);
       }
       for (let msgname of RIL_IPC_CELLBROADCAST_MSG_NAMES) {
         ppmm.removeMessageListener(msgname, this);
@@ -370,16 +381,24 @@ XPCOMUtils.defineLazyGetter(this, "gMess
       if (RIL_IPC_MOBILECONNECTION_MSG_NAMES.indexOf(msg.name) != -1) {
         if (!msg.target.assertPermission("mobileconnection")) {
           if (DEBUG) {
             debug("MobileConnection message " + msg.name +
                   " from a content process with no 'mobileconnection' privileges.");
           }
           return null;
         }
+      } else if (RIL_IPC_MOBILENETWORK_MSG_NAMES.indexOf(msg.name) != -1) {
+        if (!msg.target.assertPermission("mobilenetwork")) {
+          if (DEBUG) {
+            debug("MobileNetwork message " + msg.name +
+                  " from a content process with no 'mobilenetwork' privileges.");
+          }
+          return null;
+        }
       } else if (RIL_IPC_ICCMANAGER_MSG_NAMES.indexOf(msg.name) != -1) {
         if (!msg.target.assertPermission("mobileconnection")) {
           if (DEBUG) {
             debug("IccManager message " + msg.name +
                   " from a content process with no 'mobileconnection' privileges.");
           }
           return null;
         }
@@ -1212,16 +1231,22 @@ RadioInterface.prototype = {
   /**
    * Process a message from the content process.
    */
   receiveMessage: function receiveMessage(msg) {
     switch (msg.name) {
       case "RIL:GetRilContext":
         // This message is sync.
         return this.rilContext;
+      case "RIL:GetLastKnownNetwork":
+        // This message is sync.
+        return this._lastKnownNetwork;
+      case "RIL:GetLastKnownHomeNetwork":
+        // This message is sync.
+        return this._lastKnownHomeNetwork;
       case "RIL:GetAvailableNetworks":
         this.workerMessenger.sendWithIPCMessage(msg, "getAvailableNetworks");
         break;
       case "RIL:SelectNetwork":
         this.workerMessenger.sendWithIPCMessage(msg, "selectNetwork");
         break;
       case "RIL:SelectNetworkAuto":
         this.workerMessenger.sendWithIPCMessage(msg, "selectNetworkAuto");
@@ -1819,20 +1844,18 @@ RadioInterface.prototype = {
     let voice = this.rilContext.voice;
     let data = this.rilContext.data;
 
     if (this.isInfoChanged(message, operatorInfo)) {
       this.updateInfo(message, operatorInfo);
 
       // Update lastKnownNetwork
       if (message.mcc && message.mnc) {
-        try {
-          Services.prefs.setCharPref("ril.lastKnownNetwork",
-                                     message.mcc + "-" + message.mnc);
-        } catch (e) {}
+        this._lastKnownNetwork = message.mcc + "-" + message.mnc;
+        if (DEBUG) this.debug("_lastKnownNetwork: " + this._lastKnownNetwork);
       }
 
       // If the voice is unregistered, no need to send RIL:VoiceInfoChanged.
       if (voice.network && !batch) {
         gMessageManager.sendMobileConnectionMessage("RIL:VoiceInfoChanged",
                                                     this.clientId, voice);
       }
 
@@ -2524,20 +2547,18 @@ RadioInterface.prototype = {
       try {
         Services.prefs.setCharPref("ril.lastKnownSimMcc",
                                    message.mcc.toString());
       } catch (e) {}
     }
 
     // Update lastKnownHomeNetwork.
     if (message.mcc && message.mnc) {
-      try {
-        Services.prefs.setCharPref("ril.lastKnownHomeNetwork",
-                                   message.mcc + "-" + message.mnc);
-      } catch (e) {}
+      this._lastKnownHomeNetwork = message.mcc + "-" + message.mnc;
+      this.debug("_lastKnownHomeNetwork: " + this._lastKnownHomeNetwork);
     }
 
     // If spn becomes available, we should check roaming again.
     if (!oldSpn && message.spn) {
       let voice = this.rilContext.voice;
       let data = this.rilContext.data;
       let voiceRoaming = voice.roaming;
       let dataRoaming = data.roaming;
@@ -2655,16 +2676,22 @@ RadioInterface.prototype = {
   _lastNitzMessage: null,
 
   // Object that handles SNTP.
   _sntp: null,
 
   // Cell Broadcast settings values.
   _cellBroadcastSearchListStr: null,
 
+  // Operator's mcc-mnc.
+  _lastKnownNetwork: null,
+
+  // ICC's mcc-mnc.
+  _lastKnownHomeNetwork: null,
+
   handleSettingsChange: function handleSettingsChange(aName, aResult, aMessage) {
     // Don't allow any content processes to modify the setting
     // "time.clock.automatic-update.available" except for the chrome process.
     if (aName === kSettingsClockAutoUpdateAvailable &&
         aMessage !== "fromInternalSetting") {
       let isClockAutoUpdateAvailable = this._lastNitzMessage !== null ||
                                        this._sntp.isAvailable();
       if (aResult !== isClockAutoUpdateAvailable) {
--- a/widget/gonk/nsAppShell.cpp
+++ b/widget/gonk/nsAppShell.cpp
@@ -868,17 +868,17 @@ nsAppShell::Init()
     NS_ENSURE_SUCCESS(rv, rv);
 
     InitGonkMemoryPressureMonitoring();
 
     if (XRE_GetProcessType() == GeckoProcessType_Default) {
 #ifdef MOZ_OMX_DECODER
         android::MediaResourceManagerService::instantiate();
 #endif
-#if ANDROID_VERSION >= 18
+#if ANDROID_VERSION >= 18 && (defined(MOZ_OMX_DECODER) || defined(MOZ_B2G_CAMERA))
         android::FakeSurfaceComposer::instantiate();
 #endif
         GonkPermissionService::instantiate();
     }
 
     nsCOMPtr<nsIObserverService> obsServ = GetObserverService();
     if (obsServ) {
         obsServ->AddObserver(this, "browser-ui-startup-complete", false);