Bug 722841 - WebTelephony: Implement navigator.mozTelephony.sendTones(). r=hsinyi

This commit is contained in:
Albert Crespell 2015-01-07 07:37:03 +01:00
parent 60fda4ff74
commit 44c3140d91
10 changed files with 135 additions and 4 deletions

View File

@ -2244,7 +2244,7 @@ RilObject.prototype = {
*/
startTone: function(options) {
let Buf = this.context.Buf;
Buf.newParcel(REQUEST_DTMF_START);
Buf.newParcel(REQUEST_DTMF_START, options);
Buf.writeString(options.dtmfChar);
Buf.sendParcel();
},
@ -6187,7 +6187,13 @@ RilObject.prototype[REQUEST_QUERY_AVAILABLE_NETWORKS] = function REQUEST_QUERY_A
}
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_DTMF_START] = null;
RilObject.prototype[REQUEST_DTMF_START] = function REQUEST_DTMF_START(length, options) {
options.success = (options.rilRequestError === 0);
if (!options.success) {
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
}
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_DTMF_STOP] = null;
RilObject.prototype[REQUEST_BASEBAND_VERSION] = function REQUEST_BASEBAND_VERSION(length, options) {
if (options.rilRequestError) {

View File

@ -360,6 +360,45 @@ Telephony::DialEmergency(const nsAString& aNumber,
return promise.forget();
}
already_AddRefed<Promise>
Telephony::SendTones(const nsAString& aDTMFChars,
uint32_t aPauseDuration,
uint32_t aToneDuration,
const Optional<uint32_t>& aServiceId,
ErrorResult& aRv)
{
uint32_t serviceId = ProvidedOrDefaultServiceId(aServiceId);
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
if (!global) {
return nullptr;
}
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
}
if (aDTMFChars.IsEmpty()) {
NS_WARNING("Empty tone string will be ignored");
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
return promise.forget();
}
if (!IsValidServiceId(serviceId)) {
aRv.Throw(NS_ERROR_INVALID_ARG);
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
return promise.forget();
}
nsCOMPtr<nsITelephonyCallback> callback =
new TelephonyCallback(promise);
aRv = mService->SendTones(serviceId, aDTMFChars, aPauseDuration,
aToneDuration, callback);
return promise.forget();
}
void
Telephony::StartTone(const nsAString& aDTMFChar,
const Optional<uint32_t>& aServiceId,

View File

@ -79,6 +79,13 @@ public:
DialEmergency(const nsAString& aNumber, const Optional<uint32_t>& aServiceId,
ErrorResult& aRv);
already_AddRefed<Promise>
SendTones(const nsAString& aDTMFChars,
uint32_t aPauseDuration,
uint32_t aToneDuration,
const Optional<uint32_t>& aServiceId,
ErrorResult& aRv);
void
StartTone(const nsAString& aDTMFChar, const Optional<uint32_t>& aServiceId,
ErrorResult& aRv);

View File

@ -47,6 +47,8 @@ const DIAL_ERROR_BAD_NUMBER = RIL.GECKO_CALL_ERROR_BAD_NUMBER;
const DEFAULT_EMERGENCY_NUMBERS = ["112", "911"];
const TONES_GAP_DURATION = 70;
// MMI match groups
const MMI_MATCH_GROUP_FULL_MMI = 1;
const MMI_MATCH_GROUP_PROCEDURE = 2;
@ -897,6 +899,36 @@ TelephonyService.prototype = {
}
},
sendTones: function(aClientId, aDtmfChars, aPauseDuration, aToneDuration,
aCallback) {
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
let tones = aDtmfChars;
let playTone = (tone) => {
this._sendToRilWorker(aClientId, "startTone", { dtmfChar: tone }, response => {
if (!response.success) {
aCallback.notifyError(response.errorMsg);
return;
}
timer.initWithCallback(() => {
this.stopTone();
timer.initWithCallback(() => {
if (tones.length === 1) {
aCallback.notifySuccess();
} else {
tones = tones.substr(1);
playTone(tones[0]);
}
}, TONES_GAP_DURATION, Ci.nsITimer.TYPE_ONE_SHOT);
}, aToneDuration, Ci.nsITimer.TYPE_ONE_SHOT);
});
};
timer.initWithCallback(() => {
playTone(tones[0]);
}, aPauseDuration, Ci.nsITimer.TYPE_ONE_SHOT);
},
startTone: function(aClientId, aDtmfChar) {
this._sendToRilWorker(aClientId, "startTone", { dtmfChar: aDtmfChar });
},

View File

@ -70,6 +70,14 @@ struct ResumeCallRequest
uint32_t callIndex;
};
struct SendTonesRequest
{
uint32_t clientId;
nsString dtmfChars;
uint32_t pauseDuration;
uint32_t toneDuration;
};
union IPCTelephonyRequest
{
EnumerateCallsRequest;
@ -82,6 +90,7 @@ union IPCTelephonyRequest
RejectCallRequest;
HoldCallRequest;
ResumeCallRequest;
SendTonesRequest;
};
sync protocol PTelephony {

View File

@ -285,6 +285,15 @@ TelephonyIPCService::ResumeConference(uint32_t aClientId)
return NS_OK;
}
NS_IMETHODIMP
TelephonyIPCService::SendTones(uint32_t aClientId, const nsAString& aDtmfChars,
uint32_t aPauseDuration, uint32_t aToneDuration,
nsITelephonyCallback *aCallback)
{
return SendRequest(nullptr, aCallback, SendTonesRequest(aClientId,
nsString(aDtmfChars), aPauseDuration, aToneDuration));
}
NS_IMETHODIMP
TelephonyIPCService::StartTone(uint32_t aClientId, const nsAString& aDtmfChar)
{

View File

@ -108,6 +108,16 @@ TelephonyParent::RecvPTelephonyRequestConstructor(PTelephonyRequestParent* aActo
return true;
}
case IPCTelephonyRequest::TSendTonesRequest: {
const SendTonesRequest& request = aRequest.get_SendTonesRequest();
service->SendTones(request.clientId(),
request.dtmfChars(),
request.pauseDuration(),
request.toneDuration(),
actor);
return true;
}
default:
MOZ_CRASH("Unknown type!");
}

View File

@ -10,7 +10,7 @@
"@mozilla.org/telephony/gonktelephonyservice;1"
%}
[scriptable, uuid(aec05f05-0ca5-470b-8230-cdee0209eafd)]
[scriptable, uuid(a334105b-a329-49b0-9aa8-0900dec71eb8)]
interface nsIGonkTelephonyService : nsITelephonyService
{
void notifyAudioStateChanged(in unsigned long clientId, in short state);

View File

@ -251,7 +251,7 @@ interface nsITelephonyDialCallback : nsITelephonyCallback
* XPCOM component (in the content process) that provides the telephony
* information.
*/
[scriptable, uuid(0ab80865-7221-4c81-802f-8f7d7fc73674)]
[scriptable, uuid(a91fa6be-0acc-4d36-99f1-3e3a88e83ae9)]
interface nsITelephonyService : nsISupports
{
const unsigned short CALL_STATE_UNKNOWN = 0;
@ -296,6 +296,10 @@ interface nsITelephonyService : nsISupports
void dial(in unsigned long clientId, in DOMString number,
in boolean isEmergency, in nsITelephonyDialCallback callback);
void sendTones(in unsigned long clientId, in DOMString dtmfChars,
in unsigned long pauseDuration, in unsigned long toneDuration,
in nsITelephonyCallback callback);
void startTone(in unsigned long clientId, in DOMString dtmfChar);
void stopTone(in unsigned long clientId);

View File

@ -28,6 +28,21 @@ interface Telephony : EventTarget {
[Throws]
Promise<TelephonyCall> dialEmergency(DOMString number, optional unsigned long serviceId);
/**
* Send a series of DTMF tones.
*
* @param tones
* DTMF chars.
* @param pauseDuraton (ms) [optional]
* Time to wait before sending tones. Default value is 3000 ms.
* @param toneDuration (ms) [optional]
* Duration of each tone. Default value is 70 ms.
* @param serviceId [optional]
* Default value is as user setting dom.telephony.defaultServiceId.
*/
[Throws]
Promise<void> sendTones(DOMString tones, optional unsigned long pauseDuration = 3000, optional unsigned long toneDuration = 70, optional unsigned long serviceId);
[Throws]
void startTone(DOMString tone, optional unsigned long serviceId);