Bug 714968 - B2G telephony: support a second incoming call. r=philikon
authorHsinyi Tsai <htsai@mozilla.com>
Tue, 10 Apr 2012 18:10:18 +0800
changeset 91400 0b3c7a491be1059f376d9cb3471ea57a355009df
parent 91399 836cd0fed64636885f5237aac609efbf48cad361
child 91401 b44a23917a99aa1a5e32306a42458a0893d24544
push id22445
push usereakhgari@mozilla.com
push dateThu, 12 Apr 2012 16:19:55 +0000
treeherdermozilla-central@901dfde60183 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersphilikon
bugs714968
milestone14.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 714968 - B2G telephony: support a second incoming call. r=philikon
dom/system/gonk/ril_worker.js
dom/telephony/TelephonyCall.cpp
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -923,68 +923,86 @@ let RIL = {
 
   /**
    * Hang up the phone.
    *
    * @param callIndex
    *        Call index (1-based) as reported by REQUEST_GET_CURRENT_CALLS.
    */
   hangUp: function hangUp(options) {
-    //TODO need to check whether call is holding/waiting/background
-    // and then use REQUEST_HANGUP_WAITING_OR_BACKGROUND
-    Buf.newParcel(REQUEST_HANGUP);
-    Buf.writeUint32(1);
-    Buf.writeUint32(options.callIndex);
-    Buf.sendParcel();
+    let call = this.currentCalls[options.callIndex];
+    if (call && call.state != CALL_STATE_HOLDING) {
+      Buf.simpleRequest(REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND);
+    }
   },
 
   /**
    * Mute or unmute the radio.
    *
    * @param mute
    *        Boolean to indicate whether to mute or unmute the radio.
    */
   setMute: function setMute(mute) {
     Buf.newParcel(REQUEST_SET_MUTE);
     Buf.writeUint32(1);
     Buf.writeUint32(mute ? 1 : 0);
     Buf.sendParcel();
   },
 
   /**
-   * Answer an incoming call.
+   * Answer an incoming/waiting call.
    *
    * @param callIndex
    *        Call index of the call to answer.
    */
   answerCall: function answerCall(options) {
-    // Check for races. Since we dispatched the incoming call notification the
-    // incoming call may have changed. The main thread thinks that it is
-    // answering the call with the given index, so only answer if that is still
-    // incoming.
+    // Check for races. Since we dispatched the incoming/waiting call
+    // notification the incoming/waiting call may have changed. The main
+    // thread thinks that it is answering the call with the given index,
+    // so only answer if that is still incoming/waiting.
     let call = this.currentCalls[options.callIndex];
-    if (call && call.state == CALL_STATE_INCOMING) {
-      Buf.simpleRequest(REQUEST_ANSWER);
+    if (!call) {
+      return;
+    }
+    
+    switch (call.state) {
+      case CALL_STATE_INCOMING:
+        Buf.simpleRequest(REQUEST_ANSWER);
+        break;
+      case CALL_STATE_WAITING:
+        // Answer the waiting (second) call, and hold the first call.
+        Buf.simpleRequest(REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE);
+        break;
     }
   },
 
   /**
-   * Reject an incoming call.
+   * Reject an incoming/waiting call.
    *
    * @param callIndex
    *        Call index of the call to reject.
    */
-  rejectCall: function rejectCall() {
-    // Check for races. Since we dispatched the incoming call notification the
-    // incoming call may have changed. The main thread thinks that it is
-    // rejecting the call with the given index, so only reject if that is still
-    // incoming.
+  rejectCall: function rejectCall(options) {
+    // Check for races. Since we dispatched the incoming/waiting call
+    // notification the incoming/waiting call may have changed. The main
+    // thread thinks that it is rejecting the call with the given index,
+    // so only reject if that is still incoming/waiting.
     let call = this.currentCalls[options.callIndex];
-    if (call && call.state == CALL_STATE_INCOMING) {
-      Buf.simpleRequest(REQUEST_UDUB);
+    if (!call) {
+      return;
+    }
+    
+    switch (call.state) {
+      case CALL_STATE_INCOMING:
+        Buf.simpleRequest(REQUEST_UDUB);
+        break;
+      case CALL_STATE_WAITING:
+        // Reject the waiting (second) call, and remain the first call.
+        Buf.simpleRequest(REQUEST_HANGUP_WAITING_OR_BACKGROUND);
+        break;
     }
   },
   
   holdCall: function holdCall(options) {
     let call = this.currentCalls[options.callIndex];
     if (call && call.state == CALL_STATE_ACTIVE) {
       Buf.simpleRequest(REQUEST_SWITCH_HOLDING_AND_ACTIVE);
     }
@@ -1851,19 +1869,37 @@ RIL[REQUEST_GET_IMSI] = function REQUEST
 };
 RIL[REQUEST_HANGUP] = function REQUEST_HANGUP(length, options) {
   if (options.rilRequestError) {
     return;
   }
 
   this.getCurrentCalls();
 }; 
-RIL[REQUEST_HANGUP_WAITING_OR_BACKGROUND] = null;
-RIL[REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND] = null;
-RIL[REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE] = null;
+RIL[REQUEST_HANGUP_WAITING_OR_BACKGROUND] = function REQUEST_HANGUP_WAITING_OR_BACKGROUND(length, options) {
+  if (options.rilRequestError) {
+    return;
+  }
+  
+  this.getCurrentCalls();
+};
+RIL[REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND] = function REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND(length, options) {
+  if (options.rilRequestError) {
+    return;
+  }
+
+  this.getCurrentCalls();
+};
+RIL[REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE] = function REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE(length, options) {
+  if (options.rilRequestError) {
+    return;
+  }
+
+  this.getCurrentCalls();
+};
 RIL[REQUEST_SWITCH_HOLDING_AND_ACTIVE] = function REQUEST_SWITCH_HOLDING_AND_ACTIVE(length, options) {
   if (options.rilRequestError) {
     return;
   }
 
   // XXX Normally we should get a UNSOLICITED_RESPONSE_CALL_STATE_CHANGED parcel 
   // notifying us of call state changes, but sometimes we don't (have no idea why).
   // this.getCurrentCalls() helps update the call state actively.
--- a/dom/telephony/TelephonyCall.cpp
+++ b/dom/telephony/TelephonyCall.cpp
@@ -228,16 +228,22 @@ NS_IMETHODIMP
 TelephonyCall::HangUp()
 {
   if (mCallState == nsIRadioInterfaceLayer::CALL_STATE_DISCONNECTING ||
       mCallState == nsIRadioInterfaceLayer::CALL_STATE_DISCONNECTED) {
     NS_WARNING("HangUp on previously disconnected call ignored!");
     return NS_OK;
   }
 
+  if (mCallState == nsIRadioInterfaceLayer::CALL_STATE_HOLDING ||
+      mCallState == nsIRadioInterfaceLayer::CALL_STATE_HELD) {
+    NS_WARNING("HangUp on non-active call ignored!");
+    return NS_OK;
+  }
+
   nsresult rv = mCallState == nsIRadioInterfaceLayer::CALL_STATE_INCOMING ?
                 mTelephony->RIL()->RejectCall(mCallIndex) :
                 mTelephony->RIL()->HangUp(mCallIndex);
   NS_ENSURE_SUCCESS(rv, rv);
 
   ChangeStateInternal(nsIRadioInterfaceLayer::CALL_STATE_DISCONNECTING, true);
   return NS_OK;
 }