Bug 1571493 - part4 : support 'ControlledMediaState' in media controller r=chunmin

Introduce `ControlledMediaState` to media controller, so now we can now how many controlled media are playing, which allow us to update `mIsPlaying` correctly.

Differential Revision: https://phabricator.services.mozilla.com/D57574

--HG--
extra : moz-landing-system : lando
This commit is contained in:
alwu 2020-01-03 01:39:33 +00:00
Родитель 2d2b857325
Коммит bdc6a8cae7
5 изменённых файлов: 135 добавлений и 18 удалений

Просмотреть файл

@ -5924,7 +5924,7 @@ mozilla::ipc::IPCResult ContentParent::RecvNotifyMediaStateChanged(
MOZ_ASSERT(!aContext->GetParent(), "Should be top level browsing context!");
RefPtr<MediaController> controller =
service->GetOrCreateControllerById(aContext->Id());
// TODO : implementation in following patches.
controller->NotifyMediaStateChanged(aState);
return IPC_OK();
}

Просмотреть файл

@ -110,7 +110,9 @@ void ContentMediaController::NotifyMediaStateChanged(
} else {
// Currently this only happen when we disable e10s, otherwise all controlled
// media would be run in the content process.
// TODO : implementation in following patches.
RefPtr<MediaController> controller =
MediaControlService::GetService()->GetOrCreateControllerById(bc->Id());
controller->NotifyMediaStateChanged(aState);
}
}

Просмотреть файл

@ -75,11 +75,15 @@ void MediaController::Shutdown() {
service->GetAudioFocusManager().RevokeAudioFocus(Id());
}
void MediaController::NotifyMediaActiveChanged(bool aActive) {
if (aActive) {
void MediaController::NotifyMediaStateChanged(ControlledMediaState aState) {
if (aState == ControlledMediaState::eStarted) {
IncreaseControlledMediaNum();
} else {
} else if (aState == ControlledMediaState::eStopped) {
DecreaseControlledMediaNum();
} else if (aState == ControlledMediaState::ePlayed) {
IncreasePlayingControlledMediaNum();
} else if (aState == ControlledMediaState::ePaused) {
DecreasePlayingControlledMediaNum();
}
}
@ -110,16 +114,37 @@ void MediaController::DecreaseControlledMediaNum() {
}
}
void MediaController::IncreasePlayingControlledMediaNum() {
MOZ_ASSERT(mPlayingControlledMediaNum >= 0);
mPlayingControlledMediaNum++;
LOG("Increase playing controlled media num to %" PRId64,
mPlayingControlledMediaNum);
MOZ_ASSERT(mPlayingControlledMediaNum <= mControlledMediaNum,
"The number of playing media should not exceed the number of "
"controlled media!");
if (mPlayingControlledMediaNum == 1) {
mIsPlaying = true;
}
}
void MediaController::DecreasePlayingControlledMediaNum() {
mPlayingControlledMediaNum--;
LOG("Decrease playing controlled media num to %" PRId64,
mPlayingControlledMediaNum);
MOZ_ASSERT(mPlayingControlledMediaNum >= 0);
if (mPlayingControlledMediaNum == 0) {
mIsPlaying = false;
}
}
// TODO : Use watchable to moniter mControlledMediaNum
void MediaController::Activate() {
mIsPlaying = true;
RefPtr<MediaControlService> service = MediaControlService::GetService();
MOZ_ASSERT(service);
service->AddMediaController(this);
}
void MediaController::Deactivate() {
mIsPlaying = false;
RefPtr<MediaControlService> service = MediaControlService::GetService();
MOZ_ASSERT(service);
service->RemoveMediaController(this);
@ -130,7 +155,7 @@ uint64_t MediaController::Id() const { return mBrowsingContextId; }
bool MediaController::IsPlaying() const { return mIsPlaying; }
bool MediaController::IsAudible() const { return mIsPlaying && mAudible; }
bool MediaController::IsAudible() const { return IsPlaying() && mAudible; }
uint64_t MediaController::ControlledMediaNum() const {
return mControlledMediaNum;

Просмотреть файл

@ -7,6 +7,7 @@
#ifndef DOM_MEDIA_MEDIACONTROL_MEDIACONTROLLER_H_
#define DOM_MEDIA_MEDIACONTROL_MEDIACONTROLLER_H_
#include "ContentMediaController.h"
#include "MediaControlKeysEvent.h"
#include "nsDataHashtable.h"
#include "nsISupportsImpl.h"
@ -58,7 +59,7 @@ class MediaController final {
// These methods are only being used to notify the state changes of controlled
// media in ContentParent or MediaControlUtils.
void NotifyMediaActiveChanged(bool aActive);
void NotifyMediaStateChanged(ControlledMediaState aState);
void NotifyMediaAudibleChanged(bool aAudible);
private:
@ -68,6 +69,8 @@ class MediaController final {
MediaControlKeysEvent aEvent);
void IncreaseControlledMediaNum();
void DecreaseControlledMediaNum();
void IncreasePlayingControlledMediaNum();
void DecreasePlayingControlledMediaNum();
void Activate();
void Deactivate();
@ -76,6 +79,7 @@ class MediaController final {
bool mIsPlaying = false;
bool mAudible = false;
int64_t mControlledMediaNum = 0;
int64_t mPlayingControlledMediaNum = 0;
};
} // namespace dom

Просмотреть файл

@ -19,21 +19,21 @@ TEST(MediaController, DefaultValueCheck)
ASSERT_TRUE(!controller->IsAudible());
}
TEST(MediaController, NotifyMediaActiveChanged)
TEST(MediaController, NotifyMediaStateChanged)
{
RefPtr<MediaController> controller = new MediaController(CONTROLLER_ID);
ASSERT_TRUE(controller->ControlledMediaNum() == 0);
controller->NotifyMediaActiveChanged(true);
controller->NotifyMediaStateChanged(ControlledMediaState::eStarted);
ASSERT_TRUE(controller->ControlledMediaNum() == 1);
controller->NotifyMediaActiveChanged(true);
controller->NotifyMediaStateChanged(ControlledMediaState::eStarted);
ASSERT_TRUE(controller->ControlledMediaNum() == 2);
controller->NotifyMediaActiveChanged(false);
controller->NotifyMediaStateChanged(ControlledMediaState::eStopped);
ASSERT_TRUE(controller->ControlledMediaNum() == 1);
controller->NotifyMediaActiveChanged(false);
controller->NotifyMediaStateChanged(ControlledMediaState::eStopped);
ASSERT_TRUE(controller->ControlledMediaNum() == 0);
}
@ -45,10 +45,10 @@ TEST(MediaController, ActiveAndDeactiveController)
RefPtr<MediaController> controller1 =
new MediaController(FIRST_CONTROLLER_ID);
controller1->NotifyMediaActiveChanged(true);
controller1->NotifyMediaStateChanged(ControlledMediaState::eStarted);
ASSERT_TRUE(service->GetControllersNum() == 1);
controller1->NotifyMediaActiveChanged(false);
controller1->NotifyMediaStateChanged(ControlledMediaState::eStopped);
ASSERT_TRUE(service->GetControllersNum() == 0);
}
@ -86,7 +86,7 @@ TEST(MediaController, AlwaysInaudibleIfControllerIsNotPlaying)
ASSERT_TRUE(!controller->IsAudible());
}
TEST(MediaController, playingStateChanged)
TEST(MediaController, ChangePlayingStateViaPlayPauseStop)
{
RefPtr<MediaController> controller = new MediaController(CONTROLLER_ID);
ASSERT_TRUE(!controller->IsPlaying());
@ -94,11 +94,97 @@ TEST(MediaController, playingStateChanged)
controller->Play();
ASSERT_TRUE(controller->IsPlaying());
controller->Play();
controller->Pause();
ASSERT_TRUE(!controller->IsPlaying());
controller->Play();
ASSERT_TRUE(controller->IsPlaying());
controller->Stop();
ASSERT_TRUE(!controller->IsPlaying());
}
class FakeControlledMedia final {
public:
explicit FakeControlledMedia(MediaController* aController)
: mController(aController) {
mController->NotifyMediaStateChanged(ControlledMediaState::eStarted);
}
void SetPlaying(bool aIsPlaying) {
if (mIsPlaying == aIsPlaying) {
return;
}
mController->NotifyMediaStateChanged(aIsPlaying
? ControlledMediaState::ePlayed
: ControlledMediaState::ePaused);
mIsPlaying = aIsPlaying;
}
~FakeControlledMedia() {
if (mIsPlaying) {
mController->NotifyMediaStateChanged(ControlledMediaState::ePaused);
}
mController->NotifyMediaStateChanged(ControlledMediaState::eStopped);
}
private:
bool mIsPlaying = false;
RefPtr<MediaController> mController;
};
TEST(MediaController, PlayingStateChangeViaControlledMedia)
{
RefPtr<MediaController> controller = new MediaController(CONTROLLER_ID);
ASSERT_TRUE(!controller->IsPlaying());
// In order to check playing state after FakeControlledMedia destroyed.
{
FakeControlledMedia foo(controller);
ASSERT_TRUE(!controller->IsPlaying());
foo.SetPlaying(true);
ASSERT_TRUE(controller->IsPlaying());
foo.SetPlaying(false);
ASSERT_TRUE(!controller->IsPlaying());
foo.SetPlaying(true);
ASSERT_TRUE(controller->IsPlaying());
}
// FakeControlledMedia has been destroyed, no playing media exists.
ASSERT_TRUE(!controller->IsPlaying());
}
TEST(MediaController, ControllerShouldRemainPlayingIfAnyPlayingMediaExists)
{
RefPtr<MediaController> controller = new MediaController(CONTROLLER_ID);
ASSERT_TRUE(!controller->IsPlaying());
{
FakeControlledMedia foo(controller);
ASSERT_TRUE(!controller->IsPlaying());
foo.SetPlaying(true);
ASSERT_TRUE(controller->IsPlaying());
// foo is playing, so controller is in `playing` state.
FakeControlledMedia bar(controller);
ASSERT_TRUE(controller->IsPlaying());
bar.SetPlaying(true);
ASSERT_TRUE(controller->IsPlaying());
// Although we paused bar, but foo is still playing, so the controller would
// still be in `playing`.
bar.SetPlaying(false);
ASSERT_TRUE(controller->IsPlaying());
foo.SetPlaying(false);
ASSERT_TRUE(!controller->IsPlaying());
}
// both foo and bar have been destroyed, no playing media exists.
ASSERT_TRUE(!controller->IsPlaying());
}