Bug 1056618 - Automatically hold the active calls before dial. r=hsinyi

--HG--
extra : rebase_source : 1c46a322fac0443816ff5c312ffb7315f82298b4
This commit is contained in:
Szu-Yu Chen [:aknow] 2014-08-22 03:26:00 -04:00
parent 1e24f537b8
commit 067fd2f89c
3 changed files with 96 additions and 2 deletions

View File

@ -459,6 +459,19 @@ TelephonyService.prototype = {
return hasConference ? numCalls + 1 : numCalls;
},
/**
* Get arbitrary one of active call.
*/
_getOneActiveCall: function(aClientId) {
for (let index in this._currentCalls[aClientId]) {
let call = this._currentCalls[aClientId][index];
if (call.state === nsITelephonyService.CALL_STATE_CONNECTED) {
return call;
}
}
return null;
},
_addCdmaChildCall: function(aClientId, aNumber, aParentId) {
let childCall = {
callIndex: CDMA_SECOND_CALL_INDEX,
@ -509,6 +522,7 @@ TelephonyService.prototype = {
});
},
cachedDialRequest: null,
isDialing: false,
dial: function(aClientId, aNumber, aIsDialEmergency, aCallback) {
@ -563,7 +577,25 @@ TelephonyService.prototype = {
}
}
this._dialInternal(aClientId, options, aCallback);
// Before we dial, we have to hold the active call first.
let activeCall = this._getOneActiveCall(aClientId);
if (!activeCall) {
this._dialInternal(aClientId, options, aCallback);
} else {
if (DEBUG) debug("There is an active call. Hold it first before dial.");
this.cachedDialRequest = {
clientId: aClientId,
options: options,
callback: aCallback
};
if (activeCall.isConference) {
this.holdConference(aClientId);
} else {
this.holdCall(aClientId, activeCall.callIndex);
}
}
}, cause => {
aCallback.notifyDialError(DIAL_ERROR_BAD_NUMBER);
});
@ -588,7 +620,7 @@ TelephonyService.prototype = {
} else {
// RIL doesn't hold the 2nd call. We create one by ourselves.
aCallback.notifyDialSuccess(CDMA_SECOND_CALL_INDEX, response.number);
this._addCdmaChildCall(aClientId, aNumber, currentCdmaCallIndex);
this._addCdmaChildCall(aClientId, response.number, currentCdmaCallIndex);
}
});
},
@ -899,6 +931,15 @@ TelephonyService.prototype = {
this._currentCalls[aClientId][aCall.callIndex] = call;
}
// Handle cached dial request.
if (this.cachedDialRequest && !this._getOneActiveCall()) {
if (DEBUG) debug("All calls held. Perform the cached dial request.");
let request = this.cachedDialRequest;
this._dialInternal(request.clientId, request.options, request.callback);
this.cachedDialRequest = null;
}
this._notifyAllListeners("callStateChanged", [aClientId,
call.callIndex,
call.state,

View File

@ -64,3 +64,4 @@ disabled = Bug 821958
[test_temporary_clir.js]
[test_outgoing_error_state.js]
[test_mmi_code.js]
[test_outgoing_auto_hold.js]

View File

@ -0,0 +1,52 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
function testAutoHoldCall() {
let outCall1;
let outCall2;
return gDial("0900000001")
.then(call => { outCall1 = call; })
.then(() => gRemoteAnswer(outCall1))
.then(() => {
is(outCall1.state, "connected");
})
.then(() => gDial("0900000002"))
.then(call => { outCall2 = call; })
.then(() => {
is(outCall1.state, "held");
})
.then(() => gRemoteHangUpCalls([outCall1, outCall2]));
}
function testAutoHoldConferenceCall() {
let subCall1;
let subCall2;
let outCall;
return gSetupConference(["0900000001", "0900000002"])
.then(calls => {
[subCall1, subCall2] = calls;
is(conference.state, "connected");
})
.then(() => gDial("0900000003"))
.then(call => { outCall = call; })
.then(() => {
is(subCall1.state, "held");
is(subCall2.state, "held");
is(conference.state, "held");
})
.then(() => gRemoteHangUpCalls([subCall1, subCall2, outCall]));
}
startTest(function() {
testAutoHoldCall()
.then(() => testAutoHoldConferenceCall())
.then(null, () => {
ok(false, 'promise rejects during test.');
})
.then(finish);
});