Bug 1088690 - Fix _processCalls. r=hsinyi
authorSzu-Yu Chen [:aknow] <szchen@mozilla.com>
Mon, 17 Nov 2014 17:20:55 +0800
changeset 216071 d0ec4a4eeae0c4e33e6ec059c541f6b5acba0fb0
parent 216070 ceaba3a78fa48e5846511d0e92c37206b9b37b8b
child 216072 3d4cf044cf6b17e8ce841297a8e28286300b1c10
push id51935
push userryanvm@gmail.com
push dateMon, 17 Nov 2014 21:28:33 +0000
treeherdermozilla-inbound@872f98f50872 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershsinyi
bugs1088690
milestone36.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
Bug 1088690 - Fix _processCalls. r=hsinyi
dom/system/gonk/ril_worker.js
dom/system/gonk/tests/test_ril_worker_ssn.js
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -3930,18 +3930,35 @@ RilObject.prototype = {
     }
 
     return [CALL_STATE_UNKNOWN, new Set()];
   },
 
   /**
    * Helpers for processing call state changes.
    */
-  _processClassifiedCalls: function(removedCalls, remainedCalls, addedCalls,
-                                    failCause) {
+  _processCalls: function(newCalls, failCause) {
+    // Let's get the failCause first if there are removed calls. Otherwise, we
+    // need to trigger another async request when removing call and it cause
+    // the order of callDisconnected and conferenceCallStateChanged
+    // unpredictable.
+    if (failCause === undefined) {
+      for each (let currentCall in this.currentCalls) {
+        if (!newCalls[currentCall.callIndex] && !currentCall.hangUpLocal) {
+          this.getFailCauseCode((function(newCalls, failCause) {
+            this._processCalls(newCalls, failCause);
+          }).bind(this, newCalls));
+          return;
+        }
+      }
+    }
+
+    let [removedCalls, remainedCalls, addedCalls] =
+      this._classifyCalls(newCalls);
+
     // Handle removed calls.
     // Only remove it from the map here. Notify callDisconnected later.
     for (let call of removedCalls) {
       delete this.currentCalls[call.callIndex];
       call.failCause = call.hangUpLocal ? GECKO_CALL_ERROR_NORMAL_CALL_CLEARING
                                         : failCause;
     }
 
@@ -4014,32 +4031,16 @@ RilObject.prototype = {
     if (this.currentConferenceState != newConferenceState) {
       this.currentConferenceState = newConferenceState;
       let message = {rilMessageType: "conferenceCallStateChanged",
                      state: newConferenceState};
       this.sendChromeMessage(message);
     }
   },
 
-  _processCalls: function(newCalls) {
-    let [removed, remained, added] = this._classifyCalls(newCalls);
-
-    // Let's get the failCause first if there are removed calls. Otherwise, we
-    // need to trigger another async request when removing call and it cause
-    // the order of callDisconnected and conferenceCallStateChanged
-    // unpredictable.
-    if (removed.length) {
-      this.getFailCauseCode((function(removed, remained, added, failCause) {
-        this._processClassifiedCalls(removed, remained, added, failCause);
-      }).bind(this, removed, remained, added));
-    } else {
-      this._processClassifiedCalls(removed, remained, added);
-    }
-  },
-
   _detectAudioState: function() {
     let callNum = Object.keys(this.currentCalls).length;
     if (!callNum) {
       return AUDIO_STATE_NO_CALL;
     }
 
     let firstIndex = Object.keys(this.currentCalls)[0];
     if (callNum == 1 &&
@@ -5384,20 +5385,16 @@ RilObject.prototype[REQUEST_GET_CURRENT_
 
   let Buf = this.context.Buf;
   let calls_length = 0;
   // The RIL won't even send us the length integer if there are no active calls.
   // So only read this integer if the parcel actually has it.
   if (length) {
     calls_length = Buf.readInt32();
   }
-  if (!calls_length) {
-    this._processCalls(null);
-    return;
-  }
 
   let calls = {};
   for (let i = 0; i < calls_length; i++) {
     let call = {};
 
     // Extra uint32 field to get correct callIndex and rest of call data for
     // call waiting feature.
     if (RILQUIRKS_EXTRA_UINT32_2ND_CALL && i > 0) {
@@ -5461,33 +5458,24 @@ RilObject.prototype[REQUEST_GET_IMSI] = 
   options.rilMessageType = "iccimsi";
   options.imsi = this.iccInfoPrivate.imsi;
   this.sendChromeMessage(options);
 };
 RilObject.prototype[REQUEST_HANGUP] = function REQUEST_HANGUP(length, options) {
   options.success = options.rilRequestError === 0;
   options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
   this.sendChromeMessage(options);
-
-  if (options.success) {
-    this.getCurrentCalls();
-  }
 };
 RilObject.prototype[REQUEST_HANGUP_WAITING_OR_BACKGROUND] = function REQUEST_HANGUP_WAITING_OR_BACKGROUND(length, options) {
   RilObject.prototype[REQUEST_HANGUP].call(this, length, options);
 };
 RilObject.prototype[REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND] = function REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND(length, options) {
   RilObject.prototype[REQUEST_HANGUP].call(this, length, options);
 };
 RilObject.prototype[REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE] = function REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE(length, options) {
-  if (options.rilRequestError) {
-    return;
-  }
-
-  this.getCurrentCalls();
 };
 RilObject.prototype[REQUEST_CONFERENCE] = function REQUEST_CONFERENCE(length, options) {
   options.success = (options.rilRequestError === 0);
   if (!options.success) {
     options.errorName = "addError";
     options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
     this.sendChromeMessage(options);
     return;
--- a/dom/system/gonk/tests/test_ril_worker_ssn.js
+++ b/dom/system/gonk/tests/test_ril_worker_ssn.js
@@ -67,17 +67,17 @@ add_test(function test_notification() {
     context.RIL._processSuppSvcNotification(notificationInfo);
 
     let postedMessage = workerHelper.postedMessage;
     do_check_eq(postedMessage.rilMessageType, 'suppSvcNotification');
     do_check_eq(postedMessage.notification, resultNotification);
     do_check_eq(postedMessage.callIndex, resultCallIndex);
 
     // Clear all existed calls.
-    context.RIL._processCalls(null);
+    context.RIL._processCalls({});
   }
 
   testNotification(oneCall, SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD, null,
                    GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD, 0);
 
   testNotification(oneCall, SUPP_SVC_NOTIFICATION_CODE2_RETRIEVED, null,
                    GECKO_SUPP_SVC_NOTIFICATION_REMOTE_RESUMED, 0);