diff --git a/dom/system/gonk/ril_worker.js b/dom/system/gonk/ril_worker.js index 60d4b93dd14..d51a21fe111 100644 --- a/dom/system/gonk/ril_worker.js +++ b/dom/system/gonk/ril_worker.js @@ -928,12 +928,10 @@ let RIL = { * 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); + } }, /** @@ -950,36 +948,56 @@ let RIL = { }, /** - * 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; } }, @@ -1856,9 +1874,27 @@ RIL[REQUEST_HANGUP] = function REQUEST_HANGUP(length, options) { 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; diff --git a/dom/telephony/TelephonyCall.cpp b/dom/telephony/TelephonyCall.cpp index 035c1bde567..78f2ae45f8a 100644 --- a/dom/telephony/TelephonyCall.cpp +++ b/dom/telephony/TelephonyCall.cpp @@ -233,6 +233,12 @@ TelephonyCall::HangUp() 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);