Bug 1627999 - part3 : activate controller when it first time becomes audible. r=bryce

This patch will do :
- postpone the timing of activating the media controller. Activate the controller after it first time becomes audible.

The advantage of doing so :
- prevent setting incorrect media metadata before the controller becomes audible

---

More details about this change :

The active media session would be chose after the context owns the audio focus. Therefore, if we would like to get the correct metadata from the media session, we should postpone the timimg of activate controller and wait until we decide the active media session then we can get the correct metadata.

Differential Revision: https://phabricator.services.mozilla.com/D72497
This commit is contained in:
alwu 2020-05-14 09:33:42 +00:00
Родитель 93c8fed2d1
Коммит 96b2a42335
3 изменённых файлов: 49 добавлений и 34 удалений

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

@ -129,13 +129,7 @@ void MediaController::NotifyMediaPlaybackChanged(uint64_t aBrowsingContextId,
return;
}
MediaStatusManager::NotifyMediaPlaybackChanged(aBrowsingContextId, aState);
// Update controller's status according to the media status.
if (ShouldActivateController()) {
Activate();
} else if (ShouldDeactivateController()) {
Deactivate();
}
UpdateActivatedStateIfNeeded();
}
void MediaController::NotifyMediaAudibleChanged(uint64_t aBrowsingContextId,
@ -149,6 +143,7 @@ void MediaController::NotifyMediaAudibleChanged(uint64_t aBrowsingContextId,
if (IsAudible() == oldAudible) {
return;
}
UpdateActivatedStateIfNeeded();
// Request the audio focus amongs different controllers that could cause
// pausing other audible controllers if we enable the audio focus management.
@ -163,7 +158,7 @@ void MediaController::NotifyMediaAudibleChanged(uint64_t aBrowsingContextId,
bool MediaController::ShouldActivateController() const {
MOZ_ASSERT(!mShutdown);
return IsAnyMediaBeingControlled() && !mIsRegisteredToService;
return IsAnyMediaBeingControlled() && IsAudible() && !mIsRegisteredToService;
}
bool MediaController::ShouldDeactivateController() const {
@ -221,5 +216,13 @@ bool MediaController::IsInPictureInPictureMode() const {
return mIsInPictureInPictureMode;
}
void MediaController::UpdateActivatedStateIfNeeded() {
if (ShouldActivateController()) {
Activate();
} else if (ShouldDeactivateController()) {
Deactivate();
}
}
} // namespace dom
} // namespace mozilla

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

@ -54,16 +54,14 @@ class IMediaController {
* relationship, we use tab's top-level browsing context ID to initialize the
* controller and use that as its ID.
*
* Whenever controlled media started, we would notify the controller to increase
* or decrease the amount of its controlled media when its controlled media
* started or stopped.
* The controller would be activated when its controlled media starts and
* becomes audible. After the controller is activated, then we can use its
* controlling methods, such as `Play()`, `Pause()` to control the media within
* the tab.
*
* Once the controller started, which means it has controlled some media, then
* we can use its controlling methods, such as `Play()`, `Pause()` to control
* the media within the tab. If there is at least one controlled media playing
* in the tab, then we would say the controller is `playing`. If there is at
* least one controlled media is playing and audible, then we would say the
* controller is `audible`.
* If there is at least one controlled media playing in the tab, then we would
* say the controller is `playing`. If there is at least one controlled media is
* playing and audible, then we would say the controller is `audible`.
*
* Note that, if we don't enable audio competition, then we might have multiple
* tabs playing media at the same time, we can use the ID to query the specific
@ -111,8 +109,15 @@ class MediaController final
void HandleActualPlaybackStateChanged() override;
void UpdateMediaControlKeysEventToContentMediaIfNeeded(
MediaControlKeysEvent aEvent);
// This would register controller to the media control service that takes a
// responsibility to manage all active controllers.
void Activate();
// This would unregister controller from the media control service.
void Deactivate();
void UpdateActivatedStateIfNeeded();
bool ShouldActivateController() const;
bool ShouldDeactivateController() const;

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

@ -43,23 +43,6 @@ TEST(MediaController, IsAnyMediaBeingControlled)
ASSERT_TRUE(!controller->IsAnyMediaBeingControlled());
}
TEST(MediaController, ActiveAndDeactiveController)
{
RefPtr<MediaControlService> service = MediaControlService::GetService();
ASSERT_TRUE(service->GetActiveControllersNum() == 0);
RefPtr<MediaController> controller1 =
new MediaController(FIRST_CONTROLLER_ID);
controller1->NotifyMediaPlaybackChanged(FAKE_CONTEXT_ID,
MediaPlaybackState::eStarted);
ASSERT_TRUE(service->GetActiveControllersNum() == 1);
controller1->NotifyMediaPlaybackChanged(FAKE_CONTEXT_ID,
MediaPlaybackState::eStopped);
ASSERT_TRUE(service->GetActiveControllersNum() == 0);
}
class FakeControlledMedia final {
public:
explicit FakeControlledMedia(MediaController* aController)
@ -99,6 +82,30 @@ class FakeControlledMedia final {
RefPtr<MediaController> mController;
};
TEST(MediaController, ActiveAndDeactiveController)
{
RefPtr<MediaControlService> service = MediaControlService::GetService();
ASSERT_TRUE(service->GetActiveControllersNum() == 0);
RefPtr<MediaController> controller = new MediaController(FIRST_CONTROLLER_ID);
// In order to check active control number after FakeControlledMedia
// destroyed.
{
FakeControlledMedia fakeMedia(controller);
fakeMedia.SetPlaying(MediaPlaybackState::ePlayed);
ASSERT_TRUE(service->GetActiveControllersNum() == 0);
fakeMedia.SetAudible(MediaAudibleState::eAudible);
ASSERT_TRUE(service->GetActiveControllersNum() == 1);
fakeMedia.SetAudible(MediaAudibleState::eInaudible);
ASSERT_TRUE(service->GetActiveControllersNum() == 1);
}
ASSERT_TRUE(service->GetActiveControllersNum() == 0);
}
TEST(MediaController, AudibleChanged)
{
RefPtr<MediaController> controller = new MediaController(CONTROLLER_ID);