Bug 880561 - B2G MMS: Add 2 more error status (in flight mode and no sim card) when sending MMS. r=gene
authorChia-hung Tai <ctai@mozilla.com>
Tue, 18 Jun 2013 12:06:32 +0800
changeset 146926 d1592f77f4598942039bb88f9a1a568116bc60db
parent 146925 9915f8dae4e56dbd2eb21e54bcb935c0c1cb052b
child 146927 7a2a6d227a71af42db602b16cee003af9524f1e0
push idunknown
push userunknown
push dateunknown
reviewersgene
bugs880561
milestone24.0a1
Bug 880561 - B2G MMS: Add 2 more error status (in flight mode and no sim card) when sending MMS. r=gene
b2g/chrome/content/settings.js
dom/mobilemessage/interfaces/nsIMobileMessageCallback.idl
dom/mobilemessage/src/MobileMessageCallback.cpp
dom/mobilemessage/src/ril/MmsService.js
embedding/android/GeckoSmsManager.java
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -169,16 +169,21 @@ SettingsListener.observe('language.curre
     function(value) {
       Services.prefs.setBoolPref('dom.sms.requestStatusReport', value);
   });
 
   SettingsListener.observe('ril.cellbroadcast.disabled', false,
     function(value) {
       Services.prefs.setBoolPref('ril.cellbroadcast.disabled', value);
   });
+
+  SettingsListener.observe('ril.radio.disabled', false,
+    function(value) {
+      Services.prefs.setBoolPref('ril.radio.disabled', value);
+  });
 })();
 
 //=================== DeviceInfo ====================
 Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
 Components.utils.import('resource://gre/modules/ctypes.jsm');
 (function DeviceInfoToSettings() {
   XPCOMUtils.defineLazyServiceGetter(this, 'gSettingsService',
                                      '@mozilla.org/settingsService;1',
--- a/dom/mobilemessage/interfaces/nsIMobileMessageCallback.idl
+++ b/dom/mobilemessage/interfaces/nsIMobileMessageCallback.idl
@@ -8,29 +8,31 @@ dictionary SmsThreadListItem
 {
   unsigned long long id;
   DOMString senderOrReceiver;
   unsigned long long timestamp;
   DOMString body;
   unsigned long long unreadCount;
 };
 
-[scriptable, builtinclass, uuid(6e20c451-8bae-4b36-be3c-da166fdd10ba)]
+[scriptable, builtinclass, uuid(e73baef1-7a9f-48c1-8b04-20d9d16c4974)]
 interface nsIMobileMessageCallback : nsISupports
 {
   /**
    * All SMS related errors.
    * Make sure to keep this list in sync with the list in:
-   * mobile/android/GeckoSmsManager.java
+   * embedding/android/GeckoSmsManager.java
    */
-  const unsigned short SUCCESS_NO_ERROR = 0;
-  const unsigned short NO_SIGNAL_ERROR  = 1;
-  const unsigned short NOT_FOUND_ERROR  = 2;
-  const unsigned short UNKNOWN_ERROR    = 3;
-  const unsigned short INTERNAL_ERROR   = 4;
+  const unsigned short SUCCESS_NO_ERROR          = 0;
+  const unsigned short NO_SIGNAL_ERROR           = 1;
+  const unsigned short NOT_FOUND_ERROR           = 2;
+  const unsigned short UNKNOWN_ERROR             = 3;
+  const unsigned short INTERNAL_ERROR            = 4;
+  const unsigned short NO_SIM_CARD_ERROR         = 5;
+  const unsigned short RADIO_DISABLED_ERROR      = 6;
 
   /**
    * |message| can be nsIDOMMoz{Mms,Sms}Message.
    */
   void notifyMessageSent(in nsISupports message);
   void notifySendMessageFailed(in long error);
 
   /**
--- a/dom/mobilemessage/src/MobileMessageCallback.cpp
+++ b/dom/mobilemessage/src/MobileMessageCallback.cpp
@@ -80,16 +80,22 @@ MobileMessageCallback::NotifyError(int32
       mDOMRequest->FireError(NS_LITERAL_STRING("NotFoundError"));
       break;
     case nsIMobileMessageCallback::UNKNOWN_ERROR:
       mDOMRequest->FireError(NS_LITERAL_STRING("UnknownError"));
       break;
     case nsIMobileMessageCallback::INTERNAL_ERROR:
       mDOMRequest->FireError(NS_LITERAL_STRING("InternalError"));
       break;
+    case nsIMobileMessageCallback::NO_SIM_CARD_ERROR:
+      mDOMRequest->FireError(NS_LITERAL_STRING("NoSimCardError"));
+      break;
+    case nsIMobileMessageCallback::RADIO_DISABLED_ERROR:
+      mDOMRequest->FireError(NS_LITERAL_STRING("RadioDisabledError"));
+      break;
     default: // SUCCESS_NO_ERROR is handled above.
       MOZ_NOT_REACHED("Should never get here!");
       return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
--- a/dom/mobilemessage/src/ril/MmsService.js
+++ b/dom/mobilemessage/src/ril/MmsService.js
@@ -124,20 +124,24 @@ XPCOMUtils.defineLazyGetter(this, "gMmsC
   let conn = {
     QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
 
     /** MMS proxy settings. */
     mmsc: null,
     proxy: null,
     port: null,
 
+    // For keeping track of the radio status.
+    radioDisabled: false,
+
     proxyInfo: null,
     settings: ["ril.mms.mmsc",
                "ril.mms.mmsproxy",
-               "ril.mms.mmsport"],
+               "ril.mms.mmsport",
+               "ril.radio.disabled"],
     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. */
@@ -181,21 +185,29 @@ XPCOMUtils.defineLazyGetter(this, "gMmsC
         this.mmsc = Services.prefs.getCharPref("ril.mms.mmsc");
         if (this.mmsc.endsWith("/")) {
           this.mmsc = this.mmsc.substr(0, this.mmsc.length - 1);
         }
         this.proxy = Services.prefs.getCharPref("ril.mms.mmsproxy");
         this.port = Services.prefs.getIntPref("ril.mms.mmsport");
         this.updateProxyInfo();
       } catch (e) {
-        if (DEBUG) debug("Unable to initialize the MMS proxy settings from the" +
-                         "preference. This could happen at the first-run. Should be" +
-                         "available later.");
+        if (DEBUG) debug("Unable to initialize the MMS proxy settings from " +
+                         "the preference. This could happen at the first-run. " +
+                         "Should be available later.");
         this.clearMmsProxySettings();
       }
+
+      try {
+        this.radioDisabled = Services.prefs.getBoolPref("ril.radio.disabled");
+      } catch (e) {
+        if (DEBUG) debug("Getting preference 'ril.radio.disabled' fails.");
+        this.radioDisabled = false;
+      }
+
       this.connected = gRIL.getDataCallStateByType("mms") ==
         Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED;
     },
 
     /**
      * Return the roaming status of voice call.
      *
      * @return true if voice call is roaming.
@@ -314,16 +326,26 @@ XPCOMUtils.defineLazyGetter(this, "gMmsC
           this.connectTimer.cancel();
           while (this.pendingCallbacks.length) {
             let callback = this.pendingCallbacks.shift();
             callback(true);
           }
           break;
         }
         case kPrefenceChangedObserverTopic: {
+          if (data == "ril.radio.disabled") {
+            try {
+              this.radioDisabled = Services.prefs.getBoolPref("ril.radio.disabled");
+            } catch (e) {
+              if (DEBUG) debug("Updating preference 'ril.radio.disabled' fails.");
+              this.radioDisabled = false;
+            }
+            return;
+          }
+
           try {
             switch (data) {
               case "ril.mms.mmsc":
                 this.mmsc = Services.prefs.getCharPref("ril.mms.mmsc");
                 if (this.mmsc.endsWith("/")) {
                   this.mmsc = this.mmsc.substr(0, this.mmsc.length - 1);
                 }
                 break;
@@ -1422,30 +1444,31 @@ MmsService.prototype = {
     if (DEBUG) debug("send: aParams: " + JSON.stringify(aParams));
     if (aParams.receivers.length == 0) {
       aRequest.notifySendMmsMessageFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
       return;
     }
 
     let self = this;
 
-    let sendTransactionCb = function sendTransactionCb(aRecordId, aIsSentSuccess) {
-      if (DEBUG) debug("The success status of sending transaction: " + aIsSentSuccess);
+    let sendTransactionCb = function sendTransactionCb(aRecordId, aErrorCode) {
+      if (DEBUG) debug("The error code of sending transaction: " + aErrorCode);
+      let isSentSuccess = (aErrorCode == Ci.nsIMobileMessageCallback.SUCCESS_NO_ERROR);
       gMobileMessageDatabaseService
         .setMessageDelivery(aRecordId,
                             null,
-                            aIsSentSuccess ? DELIVERY_SENT : DELIVERY_ERROR,
-                            aIsSentSuccess ? null : DELIVERY_STATUS_ERROR,
+                            isSentSuccess ? DELIVERY_SENT : DELIVERY_ERROR,
+                            isSentSuccess ? null : DELIVERY_STATUS_ERROR,
                             function notifySetDeliveryResult(aRv, aDomMessage) {
         if (DEBUG) debug("Marking the delivery state/staus is done. Notify sent or failed.");
         // TODO bug 832140 handle !Components.isSuccessCode(aRv)
-        if (!aIsSentSuccess) {
+        if (!isSentSuccess) {
           if (DEBUG) debug("Send MMS fail. aParams.receivers = " +
                            JSON.stringify(aParams.receivers));
-          aRequest.notifySendMessageFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
+          aRequest.notifySendMessageFailed(aErrorCode);
           Services.obs.notifyObservers(aDomMessage, kSmsFailedObserverTopic, null);
           return;
         }
 
         if (DEBUG) debug("Send MMS successful. aParams.receivers = " +
                          JSON.stringify(aParams.receivers));
 
         // Notifying observers the MMS message is sent.
@@ -1456,30 +1479,47 @@ MmsService.prototype = {
       });
     };
 
     let savableMessage = this.createSavableFromParams(aParams);
     gMobileMessageDatabaseService
       .saveSendingMessage(savableMessage,
                           function notifySendingResult(aRv, aDomMessage) {
       if (DEBUG) debug("Saving sending message is done. Start to send.");
+
+      // For radio disabled error.
+      if(gMmsConnection.radioDisabled) {
+        if (DEBUG) debug("Error! Radio is disabled when sending MMS.");
+        sendTransactionCb(aDomMessage.id, Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR);
+        return;
+      }
+
+      // For SIM card is not ready.
+      if(gRIL.rilContext.cardState != "ready") {
+        if (DEBUG) debug("Error! SIM card is not ready when sending MMS.");
+        sendTransactionCb(aDomMessage.id, Ci.nsIMobileMessageCallback.NO_SIM_CARD_ERROR);
+        return;
+      }
+
       // TODO bug 832140 handle !Components.isSuccessCode(aRv)
       Services.obs.notifyObservers(aDomMessage, kSmsSendingObserverTopic, null);
       let sendTransaction;
       try {
         sendTransaction = new SendTransaction(savableMessage);
       } catch (e) {
         if (DEBUG) debug("Exception: fail to create a SendTransaction instance.");
-        sendTransactionCb(aDomMessage.id, false);
+        sendTransactionCb(aDomMessage.id, Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
         return;
       }
       sendTransaction.run(function callback(aMmsStatus, aMsg) {
         let isSentSuccess = (aMmsStatus == MMS.MMS_PDU_ERROR_OK);
         if (DEBUG) debug("The sending status of sendTransaction.run(): " + aMmsStatus);
-        sendTransactionCb(aDomMessage.id, isSentSuccess);
+        sendTransactionCb(aDomMessage.id, isSentSuccess?
+                          Ci.nsIMobileMessageCallback.SUCCESS_NO_ERROR:
+                          Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
       });
     });
   },
 
   retrieve: function retrieve(aMessageId, aRequest) {
     if (DEBUG) debug("Retrieving message with ID " + aMessageId);
     gMobileMessageDatabaseService.getMessageRecordById(aMessageId,
         (function notifyResult(aRv, aMessageRecord, aDomMessage) {
--- a/embedding/android/GeckoSmsManager.java
+++ b/embedding/android/GeckoSmsManager.java
@@ -296,21 +296,23 @@ public class GeckoSmsManager
   public final static String ACTION_SMS_SENT      = "org.mozilla.gecko.SMS_SENT";
   public final static String ACTION_SMS_DELIVERED = "org.mozilla.gecko.SMS_DELIVERED";
 
   /*
    * Make sure that the following error codes are in sync with the ones
    * defined in dom/mobilemessage/interfaces/nsISmsRequestManager.idl. They are owned
    * owned by the interface.
    */
-  public final static int kNoError       = 0;
-  public final static int kNoSignalError = 1;
-  public final static int kNotFoundError = 2;
-  public final static int kUnknownError  = 3;
-  public final static int kInternalError = 4;
+  public final static int kNoError                = 0;
+  public final static int kNoSignalError          = 1;
+  public final static int kNotFoundError          = 2;
+  public final static int kUnknownError           = 3;
+  public final static int kInternalError          = 4;
+  public final static int kNoSimCardError         = 5;
+  public final static int kRadioDisabledError     = 6;
 
   private final static int kMaxMessageSize    = 160;
 
   private final static Uri kSmsContentUri     = Uri.parse("content://sms");
   private final static Uri kSmsSentContentUri = Uri.parse("content://sms/sent");
 
   private final static int kSmsTypeInbox      = 1;
   private final static int kSmsTypeSentbox    = 2;