Bug 990368 - [B2G][MMS][DSDS] Feedback NonActiveSimError if send an MMS with non active SIM selected. r=vyang, a=1.4+
authorBevis Tseng <btseng@mozilla.com>
Wed, 02 Apr 2014 11:24:20 +0800
changeset 192569 a0fbcf6abdeda302f7bcb0e5a52780f881c3fe67
parent 192568 779a2822329d8bf8b5fd0ba3a83e3cb267a28bf3
child 192570 362b7ef9e801e087098c8b2fafe586b698bcae62
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvyang, 1
bugs990368
milestone30.0a2
Bug 990368 - [B2G][MMS][DSDS] Feedback NonActiveSimError if send an MMS with non active SIM selected. r=vyang, a=1.4+
dom/mobilemessage/src/gonk/MmsService.js
--- a/dom/mobilemessage/src/gonk/MmsService.js
+++ b/dom/mobilemessage/src/gonk/MmsService.js
@@ -146,16 +146,50 @@ XPCOMUtils.defineLazyServiceGetter(this,
                                    "nsIRadioInterfaceLayer");
 
 XPCOMUtils.defineLazyGetter(this, "MMS", function() {
   let MMS = {};
   Cu.import("resource://gre/modules/MmsPduHelper.jsm", MMS);
   return MMS;
 });
 
+// Internal Utilities
+
+/**
+ * Return default service Id for MMS.
+ */
+function getDefaultServiceId() {
+  let id = Services.prefs.getIntPref(kPrefDefaultServiceId);
+  let numRil = Services.prefs.getIntPref(kPrefRilNumRadioInterfaces);
+
+  if (id >= numRil || id < 0) {
+    id = 0;
+  }
+
+  return id;
+}
+
+/**
+ * Return Radio disabled state.
+ */
+function getRadioDisabledState() {
+  let state;
+  try {
+    state = Services.prefs.getBoolPref(kPrefRilRadioDisabled);
+  } catch (e) {
+    if (DEBUG) debug("Getting preference 'ril.radio.disabled' fails.");
+    state = false;
+  }
+
+  return state;
+}
+
+/**
+ * Helper Class to control MMS Data Connection.
+ */
 function MmsConnection(aServiceId) {
   this.serviceId = aServiceId;
   this.radioInterface = gRil.getRadioInterface(aServiceId);
 };
 
 MmsConnection.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
 
@@ -187,19 +221,16 @@ MmsConnection.prototype = {
       gpps.newProxyInfo("http", this.mmsProxy, port,
                         Ci.nsIProxyInfo.TRANSPARENT_PROXY_RESOLVES_HOST,
                         -1, null);
     if (DEBUG) debug("getProxyInfo: " + JSON.stringify(proxyInfo));
 
     return proxyInfo;
   },
 
-  // For keeping track of the radio status.
-  radioDisabled: false,
-  settings: [kPrefRilRadioDisabled],
   connected: false,
 
   //A queue to buffer the MMS HTTP requests when the MMS network
   //is not yet connected. The buffered requests will be cleared
   //if the MMS network fails to be connected within a timer.
   pendingCallbacks: [],
 
   /** MMS network connection reference count. */
@@ -231,26 +262,16 @@ MmsConnection.prototype = {
       this.radioInterface.deactivateDataCallByType("mms");
     }
   },
 
   init: function() {
     Services.obs.addObserver(this, kNetworkConnStateChangedTopic,
                              false);
     Services.obs.addObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
-    this.settings.forEach(function(name) {
-      Services.prefs.addObserver(name, this, false);
-    }, this);
-
-    try {
-      this.radioDisabled = Services.prefs.getBoolPref(kPrefRilRadioDisabled);
-    } catch (e) {
-      if (DEBUG) debug("Getting preference 'ril.radio.disabled' fails.");
-      this.radioDisabled = false;
-    }
 
     this.connected = this.radioInterface.getDataCallStateByType("mms") ==
       Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED;
     // If the MMS network is connected during the initialization, it means the
     // MMS network must share the same APN with the mobile network by default.
     // Under this case, |networkManager.active| should keep the mobile network,
     // which is supposed be an instance of |nsIRilNetworkInterface| for sure.
     if (this.connected) {
@@ -348,17 +369,17 @@ MmsConnection.prototype = {
     this.disconnectTimer.cancel();
 
     // If the MMS network is not yet connected, buffer the
     // MMS request and try to setup the MMS network first.
     if (!this.connected) {
       this.pendingCallbacks.push(callback);
 
       let errorStatus;
-      if (this.radioDisabled) {
+      if (getRadioDisabledState()) {
         if (DEBUG) debug("Error! Radio is disabled when sending MMS.");
         errorStatus = _HTTP_STATUS_RADIO_DISABLED;
       } else if (this.radioInterface.rilContext.cardState != "ready") {
         if (DEBUG) debug("Error! SIM card is not ready when sending MMS.");
         errorStatus = _HTTP_STATUS_NO_SIM_CARD;
       }
       if (errorStatus != null) {
         this.flushPendingCallbacks(errorStatus);
@@ -452,28 +473,16 @@ MmsConnection.prototype = {
         this.setApnSetting(network);
 
         if (DEBUG) debug("Got the MMS network connected! Resend the buffered " +
                          "MMS requests: number: " + this.pendingCallbacks.length);
         this.connectTimer.cancel();
         this.flushPendingCallbacks(_HTTP_STATUS_ACQUIRE_CONNECTION_SUCCESS)
         break;
       }
-      case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID: {
-        if (data == kPrefRilRadioDisabled) {
-          try {
-            this.radioDisabled = Services.prefs.getBoolPref(kPrefRilRadioDisabled);
-          } catch (e) {
-            if (DEBUG) debug("Updating preference 'ril.radio.disabled' fails.");
-            this.radioDisabled = false;
-          }
-          return;
-        }
-        break;
-      }
       case NS_XPCOM_SHUTDOWN_OBSERVER_ID: {
         this.shutdown();
       }
     }
   }
 };
 
 XPCOMUtils.defineLazyGetter(this, "gMmsConnections", function() {
@@ -935,23 +944,18 @@ CancellableTransaction.prototype = {
           return;
         }
 
         this.cancelRunning(_MMS_ERROR_MESSAGE_DELETED);
         break;
       }
       case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID: {
         if (data == kPrefRilRadioDisabled) {
-          try {
-            let radioDisabled = Services.prefs.getBoolPref(kPrefRilRadioDisabled);
-            if (radioDisabled) {
-              this.cancelRunning(_MMS_ERROR_RADIO_DISABLED);
-            }
-          } catch (e) {
-            if (DEBUG) debug("Failed to get preference of 'ril.radio.disabled'.");
+          if (getRadioDisabledState()) {
+            this.cancelRunning(_MMS_ERROR_RADIO_DISABLED);
           }
         } else if (data === kPrefDefaultServiceId &&
                    this.serviceId != getDefaultServiceId()) {
           this.cancelRunning(_MMS_ERROR_SIM_CARD_CHANGED);
         }
         break;
       }
     }
@@ -1345,27 +1349,16 @@ AcknowledgeTransaction.prototype = {
     gMmsTransactionHelper.sendRequest(this.mmsConnection,
                                       "POST",
                                       null,
                                       this.istream,
                                       requestCallback);
   }
 };
 
-function getDefaultServiceId() {
-  let id = Services.prefs.getIntPref(kPrefDefaultServiceId);
-  let numRil = Services.prefs.getIntPref(kPrefRilNumRadioInterfaces);
-
-  if (id >= numRil || id < 0) {
-    id = 0;
-  }
-
-  return id;
-}
-
 /**
  * Return M-Read-Rec.ind back to MMSC
  *
  * @param messageID
  *        Message-ID of the message.
  * @param toAddress
  *        The address of the recipient of the Read Report, i.e. the originator
  *        of the original multimedia message.
@@ -2182,16 +2175,36 @@ MmsService.prototype = {
       Services.obs.notifyObservers(aDomMessage, kSmsSendingObserverTopic, null);
 
       if (errorCode !== Ci.nsIMobileMessageCallback.SUCCESS_NO_ERROR) {
         if (DEBUG) debug("Error! The params for sending MMS are invalid.");
         sendTransactionCb(aDomMessage, errorCode, null);
         return;
       }
 
+      // Check radio state in prior to default service Id.
+      if (getRadioDisabledState()) {
+        if (DEBUG) debug("Error! Radio is disabled when sending MMS.");
+        sendTransactionCb(aDomMessage,
+                          Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR,
+                          null);
+        return;
+      }
+
+      // To support DSDS, we have to stop users sending MMS when the selected
+      // SIM is not active, thus avoiding the data disconnection of the current
+      // SIM. Users have to manually swith the default SIM before sending.
+      if (mmsConnection.serviceId != self.mmsDefaultServiceId) {
+        if (DEBUG) debug("RIL service is not active to send MMS.");
+        sendTransactionCb(aDomMessage,
+                          Ci.nsIMobileMessageCallback.NON_ACTIVE_SIM_CARD_ERROR,
+                          null);
+        return;
+      }
+
       // This is the entry point starting to send MMS.
       let sendTransaction;
       try {
         sendTransaction =
           new SendTransaction(mmsConnection, aDomMessage.id, savableMessage,
                               savableMessage["deliveryStatusRequested"]);
       } catch (e) {
         if (DEBUG) debug("Exception: fail to create a SendTransaction instance.");