mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Bug 1016277 - Telephony AudioChannel policy: LIFO r=mchen
--HG-- rename : dom/base/test/audio.ogg => dom/audiochannel/tests/audio.ogg
This commit is contained in:
parent
42cda37bac
commit
187ed14a21
@ -151,6 +151,13 @@ AudioChannelService::RegisterType(AudioChannel aChannel, uint64_t aChildID,
|
||||
mChannelCounters[type].AppendElement(aChildID);
|
||||
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
|
||||
// We must keep the childIds in order to decide which app is allowed to play
|
||||
// with then telephony channel.
|
||||
if (aChannel == AudioChannel::Telephony) {
|
||||
RegisterTelephonyChild(aChildID);
|
||||
}
|
||||
|
||||
// Since there is another telephony registered, we can unregister old one
|
||||
// immediately.
|
||||
if (mDeferTelChannelTimer && aChannel == AudioChannel::Telephony) {
|
||||
@ -234,15 +241,21 @@ AudioChannelService::UnregisterType(AudioChannel aChannel,
|
||||
// There are two reasons to defer the decrease of telephony channel.
|
||||
// 1. User can have time to remove device from his ear before music resuming.
|
||||
// 2. Give BT SCO to be disconnected before starting to connect A2DP.
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default &&
|
||||
aChannel == AudioChannel::Telephony &&
|
||||
(mChannelCounters[AUDIO_CHANNEL_INT_TELEPHONY_HIDDEN].Length() +
|
||||
mChannelCounters[AUDIO_CHANNEL_INT_TELEPHONY].Length()) == 1) {
|
||||
mTimerElementHidden = aElementHidden;
|
||||
mTimerChildID = aChildID;
|
||||
mDeferTelChannelTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
mDeferTelChannelTimer->InitWithCallback(this, 1500, nsITimer::TYPE_ONE_SHOT);
|
||||
return;
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
|
||||
if (aChannel == AudioChannel::Telephony) {
|
||||
UnregisterTelephonyChild(aChildID);
|
||||
}
|
||||
|
||||
if (aChannel == AudioChannel::Telephony &&
|
||||
(mChannelCounters[AUDIO_CHANNEL_INT_TELEPHONY_HIDDEN].Length() +
|
||||
mChannelCounters[AUDIO_CHANNEL_INT_TELEPHONY].Length()) == 1) {
|
||||
mTimerElementHidden = aElementHidden;
|
||||
mTimerChildID = aChildID;
|
||||
mDeferTelChannelTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
mDeferTelChannelTimer->InitWithCallback(this, 1500, nsITimer::TYPE_ONE_SHOT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UnregisterTypeInternal(aChannel, aElementHidden, aChildID, aWithVideo);
|
||||
@ -358,7 +371,7 @@ AudioChannelService::GetStateInternal(AudioChannel aChannel, uint64_t aChildID,
|
||||
if (CheckVolumeFadedCondition(newType, aElementHidden)) {
|
||||
return AUDIO_CHANNEL_STATE_FADED;
|
||||
}
|
||||
return AUDIO_CHANNEL_STATE_NORMAL;
|
||||
return CheckTelephonyPolicy(aChannel, aChildID);
|
||||
}
|
||||
|
||||
// We are not visible, maybe we have to mute.
|
||||
@ -387,7 +400,34 @@ AudioChannelService::GetStateInternal(AudioChannel aChannel, uint64_t aChildID,
|
||||
return AUDIO_CHANNEL_STATE_MUTED;
|
||||
}
|
||||
|
||||
return AUDIO_CHANNEL_STATE_NORMAL;
|
||||
return CheckTelephonyPolicy(aChannel, aChildID);
|
||||
}
|
||||
|
||||
AudioChannelState
|
||||
AudioChannelService::CheckTelephonyPolicy(AudioChannel aChannel,
|
||||
uint64_t aChildID)
|
||||
{
|
||||
// Only the latest childID is allowed to play with telephony channel.
|
||||
if (aChannel != AudioChannel::Telephony) {
|
||||
return AUDIO_CHANNEL_STATE_NORMAL;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mTelephonyChildren.IsEmpty());
|
||||
|
||||
#if DEBUG
|
||||
bool found = false;
|
||||
for (uint32_t i = 0, len = mTelephonyChildren.Length(); i < len; ++i) {
|
||||
if (mTelephonyChildren[i].mChildID == aChildID) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(found);
|
||||
#endif
|
||||
|
||||
return mTelephonyChildren.LastElement().mChildID == aChildID
|
||||
? AUDIO_CHANNEL_STATE_NORMAL : AUDIO_CHANNEL_STATE_MUTED;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -986,3 +1026,39 @@ AudioChannelService::GetDefaultAudioChannelString(nsAString& aString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioChannelService::RegisterTelephonyChild(uint64_t aChildID)
|
||||
{
|
||||
for (uint32_t i = 0, len = mTelephonyChildren.Length(); i < len; ++i) {
|
||||
if (mTelephonyChildren[i].mChildID == aChildID) {
|
||||
++mTelephonyChildren[i].mInstances;
|
||||
|
||||
if (i != len - 1) {
|
||||
TelephonyChild child = mTelephonyChildren[i];
|
||||
mTelephonyChildren.RemoveElementAt(i);
|
||||
mTelephonyChildren.AppendElement(child);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mTelephonyChildren.AppendElement(TelephonyChild(aChildID));
|
||||
}
|
||||
|
||||
void
|
||||
AudioChannelService::UnregisterTelephonyChild(uint64_t aChildID)
|
||||
{
|
||||
for (uint32_t i = 0, len = mTelephonyChildren.Length(); i < len; ++i) {
|
||||
if (mTelephonyChildren[i].mChildID == aChildID) {
|
||||
if (!--mTelephonyChildren[i].mInstances) {
|
||||
mTelephonyChildren.RemoveElementAt(i);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(false, "This should not happen.");
|
||||
}
|
||||
|
@ -150,6 +150,11 @@ protected:
|
||||
void SetDefaultVolumeControlChannelInternal(int32_t aChannel,
|
||||
bool aHidden, uint64_t aChildID);
|
||||
|
||||
AudioChannelState CheckTelephonyPolicy(AudioChannel aChannel,
|
||||
uint64_t aChildID);
|
||||
void RegisterTelephonyChild(uint64_t aChildID);
|
||||
void UnregisterTelephonyChild(uint64_t aChildID);
|
||||
|
||||
AudioChannelService();
|
||||
virtual ~AudioChannelService();
|
||||
|
||||
@ -225,6 +230,19 @@ protected:
|
||||
|
||||
nsTArray<uint64_t> mWithVideoChildIDs;
|
||||
|
||||
// Telephony Channel policy is "LIFO", the last app to require the resource is
|
||||
// allowed to play. The others are muted.
|
||||
struct TelephonyChild {
|
||||
uint64_t mChildID;
|
||||
uint32_t mInstances;
|
||||
|
||||
explicit TelephonyChild(uint64_t aChildID)
|
||||
: mChildID(aChildID)
|
||||
, mInstances(1)
|
||||
{}
|
||||
};
|
||||
nsTArray<TelephonyChild> mTelephonyChildren;
|
||||
|
||||
// mPlayableHiddenContentChildID stores the ChildID of the process which can
|
||||
// play content channel(s) in the background.
|
||||
// A background process contained content channel(s) will become playable:
|
||||
|
BIN
dom/audiochannel/tests/audio.ogg
Normal file
BIN
dom/audiochannel/tests/audio.ogg
Normal file
Binary file not shown.
18
dom/audiochannel/tests/file_telephonyPolicy.html
Normal file
18
dom/audiochannel/tests/file_telephonyPolicy.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test Telephony Channel Policy</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
var audio = new Audio();
|
||||
audio.mozAudioChannelType = 'telephony';
|
||||
audio.src = "audio.ogg";
|
||||
audio.play();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,7 +1,11 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
audio.ogg
|
||||
file_audio.html
|
||||
file_telephonyPolicy.html
|
||||
AudioChannelChromeScript.js
|
||||
|
||||
[test_telephonyPolicy.html]
|
||||
skip-if = (toolkit == 'gonk' || e10s)
|
||||
[test_audioChannelChange.html]
|
||||
skip-if = (toolkit != 'gonk')
|
||||
|
85
dom/audiochannel/tests/test_telephonyPolicy.html
Normal file
85
dom/audiochannel/tests/test_telephonyPolicy.html
Normal file
@ -0,0 +1,85 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test the Telephony Channel Policy</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
function mainApp() {
|
||||
var audio = new Audio();
|
||||
audio.mozAudioChannelType = 'telephony';
|
||||
audio.src = "audio.ogg";
|
||||
audio.loop = true;
|
||||
audio.play();
|
||||
|
||||
audio.addEventListener('mozinterruptbegin', function() {
|
||||
ok(true, "This element has been muted!");
|
||||
}, false);
|
||||
|
||||
audio.addEventListener('mozinterruptend', function() {
|
||||
ok(true, "This element has been unmuted!");
|
||||
audio.pause();
|
||||
runTest();
|
||||
}, false);
|
||||
|
||||
setTimeout(runTest, 600);
|
||||
}
|
||||
|
||||
function newApp() {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('mozbrowser', true);
|
||||
// That needs to be an app.
|
||||
iframe.setAttribute('mozapp', 'https://acertified.com/manifest.webapp');
|
||||
iframe.src = "file_telephonyPolicy.html";
|
||||
document.body.appendChild(iframe);
|
||||
}
|
||||
|
||||
var tests = [
|
||||
// Permissions
|
||||
function() {
|
||||
SpecialPowers.pushPermissions(
|
||||
[{ "type": "browser", "allow": 1, "context": document },
|
||||
{ "type": "embed-apps", "allow": 1, "context": document },
|
||||
{ "type": "webapps-manage", "allow": 1, "context": document },
|
||||
{ "type": "audio-channel-telephony", "allow": 1, "context": document }], runTest);
|
||||
},
|
||||
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.ipc.browser_frames.oop_by_default", true],
|
||||
["media.useAudioChannelService", true],
|
||||
["media.defaultAudioChannel", "telephony"],
|
||||
["dom.mozBrowserFramesEnabled", true],
|
||||
["network.disable.ipc.security", true]]}, runTest);
|
||||
},
|
||||
|
||||
// Run 2 apps
|
||||
mainApp,
|
||||
newApp,
|
||||
];
|
||||
|
||||
function runTest() {
|
||||
if (!tests.length) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var test = tests.shift();
|
||||
test();
|
||||
}
|
||||
|
||||
function finish() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user