Bug 872430 - Timeout between when the media is paused and when the wakelock is released. r=jlebar

This commit is contained in:
Andrea Marchesini 2013-05-28 13:30:17 -04:00
parent 109adb2480
commit a94a6e394a
5 changed files with 81 additions and 14 deletions

View File

@ -43,6 +43,8 @@ class MediaResource;
class MediaDecoder;
}
class nsITimer;
namespace mozilla {
namespace dom {
@ -533,6 +535,8 @@ protected:
WakeLockBoolWrapper(bool val = false)
: mValue(val), mCanPlay(true), mOuter(nullptr) {}
~WakeLockBoolWrapper();
void SetOuter(HTMLMediaElement* outer) { mOuter = outer; }
void SetCanPlay(bool aCanPlay);
@ -542,12 +546,15 @@ protected:
bool operator !() const { return !mValue; }
static void TimerCallback(nsITimer* aTimer, void* aClosure);
private:
void UpdateWakeLock();
bool mValue;
bool mCanPlay;
HTMLMediaElement* mOuter;
nsCOMPtr<nsITimer> mTimer;
};
/**

View File

@ -1987,6 +1987,8 @@ HTMLMediaElement::~HTMLMediaElement()
if (mAudioStream) {
mAudioStream->Shutdown();
}
WakeLockRelease();
}
void
@ -2106,7 +2108,8 @@ NS_IMETHODIMP HTMLMediaElement::Play()
}
HTMLMediaElement::WakeLockBoolWrapper&
HTMLMediaElement::WakeLockBoolWrapper::operator=(bool val) {
HTMLMediaElement::WakeLockBoolWrapper::operator=(bool val)
{
if (mValue == val) {
return *this;
}
@ -2116,6 +2119,13 @@ HTMLMediaElement::WakeLockBoolWrapper::operator=(bool val) {
return *this;
}
HTMLMediaElement::WakeLockBoolWrapper::~WakeLockBoolWrapper()
{
if (mTimer) {
mTimer->Cancel();
}
}
void
HTMLMediaElement::WakeLockBoolWrapper::SetCanPlay(bool aCanPlay)
{
@ -2133,12 +2143,30 @@ HTMLMediaElement::WakeLockBoolWrapper::UpdateWakeLock()
bool playing = (!mValue && mCanPlay);
if (playing) {
if (mTimer) {
mTimer->Cancel();
mTimer = nullptr;
}
mOuter->WakeLockCreate();
} else {
mOuter->WakeLockRelease();
} else if (!mTimer) {
// Don't release the wake lock immediately; instead, release it after a
// grace period.
int timeout = Preferences::GetInt("media.wakelock_timeout", 2000);
mTimer = do_CreateInstance("@mozilla.org/timer;1");
mTimer->InitWithFuncCallback(TimerCallback, this, timeout,
nsITimer::TYPE_ONE_SHOT);
}
}
void
HTMLMediaElement::WakeLockBoolWrapper::TimerCallback(nsITimer* aTimer,
void* aClosure)
{
WakeLockBoolWrapper* wakeLock = static_cast<WakeLockBoolWrapper*>(aClosure);
wakeLock->mOuter->WakeLockRelease();
wakeLock->mTimer = nullptr;
}
void
HTMLMediaElement::WakeLockCreate()
{

View File

@ -20,8 +20,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=868943
/** Test for Bug 868943 **/
SpecialPowers.addPermission("power", true, document);
function testAudioPlayPause() {
var lockState = true;
var count = 0;
@ -32,9 +30,11 @@ function testAudioPlayPause() {
audio.src = "wakelock.ogg";
content.appendChild(audio);
var startDate;
audio.addEventListener('progress', function() {
lockState = false;
audio.pause();
startDate = new Date();
});
navigator.mozPower.addWakeLockListener(function testAudioPlayListener(topic, state) {
@ -49,6 +49,9 @@ function testAudioPlayPause() {
// count == 2 is when the cpu wakelock is released
if (count == 2) {
var diffDate = (new Date() - startDate);
ok(diffDate > 200, "There was at least 200 milliseconds between the stop and the wakelock release");
content.removeChild(audio);
navigator.mozPower.removeWakeLockListener(testAudioPlayListener);
runTests();
@ -68,6 +71,11 @@ function testAudioPlay() {
audio.src = "wakelock.ogg";
content.appendChild(audio);
var startDate;
audio.addEventListener('progress', function() {
startDate = new Date();
});
navigator.mozPower.addWakeLockListener(function testAudioPlayListener(topic, state) {
is(topic, "cpu", "Audio element locked the target == cpu");
var locked = state == "locked-foreground" ||
@ -84,6 +92,9 @@ function testAudioPlay() {
// The next step is to unlock the resource.
lockState = false;
} else if (count == 2) {
var diffDate = (new Date() - startDate);
ok(diffDate > 200, "There was at least 200 milliseconds between the stop and the wakelock release");
content.removeChild(audio);
navigator.mozPower.removeWakeLockListener(testAudioPlayListener);
runTests();
@ -104,8 +115,10 @@ function runTests() {
test();
};
SpecialPowers.addPermission("power", true, document);
SpecialPowers.pushPrefEnv({"set": [["media.wakelock_timeout", 500]]}, runTests);
SimpleTest.waitForExplicitFinish();
runTests();
</script>
</pre>

View File

@ -20,8 +20,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=868943
/** Test for Bug 868943 **/
SpecialPowers.addPermission("power", true, document);
function testVideoPlayPause() {
var lockState = true;
var count = 0;
@ -32,6 +30,15 @@ function testVideoPlayPause() {
video.src = "wakelock.ogv";
content.appendChild(video);
var startDate;
video.addEventListener('progress', function() {
startDate = new Date();
// The next step is to unlock the resource.
lockState = false;
video.pause();
});
navigator.mozPower.addWakeLockListener(function testVideoPlayPauseListener(topic, state) {
is(topic, "screen", "Video element locked the target == screen");
var locked = state == "locked-foreground" ||
@ -40,11 +47,10 @@ function testVideoPlayPause() {
is(locked, lockState, "Video element locked the screen - paused");
count++;
if (count == 1) {
// The next step is to unlock the resource.
lockState = false;
video.pause();
} else if (count == 2) {
if (count == 2) {
var diffDate = (new Date() - startDate);
ok(diffDate > 200, "There was at least 200 milliseconds between the stop and the wakelock release");
content.removeChild(video);
navigator.mozPower.removeWakeLockListener(testVideoPlayPauseListener);
runTests();
@ -64,6 +70,11 @@ function testVideoPlay() {
video.src = "wakelock.ogv";
content.appendChild(video);
var startDate;
video.addEventListener('progress', function() {
startDate = new Date();
});
navigator.mozPower.addWakeLockListener(function testVideoPlayListener(topic, state) {
is(topic, "screen", "Video element locked the target == screen");
var locked = state == "locked-foreground" ||
@ -76,6 +87,9 @@ function testVideoPlay() {
// The next step is to unlock the resource.
lockState = false;
} else if (count == 2) {
var diffDate = (new Date() - startDate);
ok(diffDate > 200, "There was at least milliseconds between the stop and the wakelock release");
content.removeChild(video);
navigator.mozPower.removeWakeLockListener(testVideoPlayListener);
runTests();
@ -96,8 +110,10 @@ function runTests() {
test();
};
SpecialPowers.addPermission("power", true, document);
SpecialPowers.pushPrefEnv({"set": [["media.wakelock_timeout", 500]]}, runTests);
SimpleTest.waitForExplicitFinish();
runTests();
</script>
</pre>

View File

@ -152,6 +152,9 @@ pref("media.cache_size", 512000);
// Master HTML5 media volume scale.
pref("media.volume_scale", "1.0");
// Timeout for wakelock release
pref("media.wakelock_timeout", 2000);
#ifdef MOZ_WMF
pref("media.windows-media-foundation.enabled", true);
pref("media.windows-media-foundation.use-dxva", true);