Bug 1634494 - part1 : store the active media session context Id on WindowContext. r=chunmin,farre

We determine which media session is active media session in chrome process, but the media session in content process doesn't know the detail.

This patch would store the active session context Id on the top level WindowContext, so that media session in content process can know if it's an active context or not, which helps to trigger the action handler only on active media session, after changing our propagation mechanism in following patches.

Differential Revision: https://phabricator.services.mozilla.com/D88106
This commit is contained in:
alwu 2020-08-27 14:11:05 +00:00
parent bf740b7795
commit 75773fa092
6 changed files with 56 additions and 0 deletions

View File

@ -200,6 +200,12 @@ bool WindowContext::CanSet(FieldIndex<IDX_ShortcutsPermission>,
return IsTop() && CheckOnlyOwningProcessCanSet(aSource);
}
bool WindowContext::CanSet(FieldIndex<IDX_ActiveMediaSessionContextId>,
const Maybe<uint64_t>& aValue,
ContentParent* aSource) {
return IsTop();
}
bool WindowContext::CanSet(FieldIndex<IDX_PopupPermission>, const uint32_t&,
ContentParent* aSource) {
return CheckOnlyOwningProcessCanSet(aSource);

View File

@ -64,6 +64,9 @@ class BrowsingContextGroup;
FIELD(DocTreeHadAudibleMedia, bool) \
FIELD(AutoplayPermission, uint32_t) \
FIELD(ShortcutsPermission, uint32_t) \
/* Store the Id of the browsing context where active media session \
* exists on the top level window context */ \
FIELD(ActiveMediaSessionContextId, Maybe<uint64_t>) \
/* ALLOW_ACTION if it is allowed to open popups for the sub-tree \
* starting and including the current WindowContext */ \
FIELD(PopupPermission, uint32_t) \
@ -213,6 +216,8 @@ class WindowContext : public nsISupports, public nsWrapperCache {
ContentParent* aSource);
bool CanSet(FieldIndex<IDX_ShortcutsPermission>, const uint32_t& aValue,
ContentParent* aSource);
bool CanSet(FieldIndex<IDX_ActiveMediaSessionContextId>,
const Maybe<uint64_t>& aValue, ContentParent* aSource);
bool CanSet(FieldIndex<IDX_PopupPermission>, const uint32_t&,
ContentParent* aSource);
bool CanSet(FieldIndex<IDX_SHEntryHasUserInteraction>,

View File

@ -141,6 +141,7 @@ void MediaStatusManager::SetActiveMediaSessionContextId(
return;
}
mActiveMediaSessionContextId = Some(aBrowsingContextId);
StoreMediaSessionContextIdOnWindowContext();
LOG("context %" PRIu64 " becomes active session context",
*mActiveMediaSessionContextId);
mMetadataChangedEvent.Notify(GetCurrentMediaMetadata());
@ -153,10 +154,20 @@ void MediaStatusManager::ClearActiveMediaSessionContextIdIfNeeded() {
}
LOG("Clear active session context");
mActiveMediaSessionContextId.reset();
StoreMediaSessionContextIdOnWindowContext();
mMetadataChangedEvent.Notify(GetCurrentMediaMetadata());
mSupportedActionsChangedEvent.Notify(GetSupportedActions());
}
void MediaStatusManager::StoreMediaSessionContextIdOnWindowContext() {
RefPtr<CanonicalBrowsingContext> bc =
CanonicalBrowsingContext::Get(mTopLevelBrowsingContextId);
if (bc && bc->GetTopWindowContext()) {
Unused << bc->GetTopWindowContext()->SetActiveMediaSessionContextId(
mActiveMediaSessionContextId);
}
}
bool MediaStatusManager::IsSessionOwningAudioFocus(
uint64_t aBrowsingContextId) const {
Maybe<uint64_t> audioFocusContextId =

View File

@ -228,6 +228,8 @@ class MediaStatusManager : public IMediaInfoUpdater {
// media event.
CopyableTArray<MediaSessionAction> GetSupportedActions() const;
void StoreMediaSessionContextIdOnWindowContext();
// When the amount of playing media changes, we would use this function to
// update the guessed playback state.
void SetGuessedPlayState(MediaSessionPlaybackState aState);

View File

@ -7,8 +7,16 @@
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/ContentMediaController.h"
#include "mozilla/dom/MediaSession.h"
#include "mozilla/dom/MediaControlUtils.h"
#include "mozilla/dom/WindowContext.h"
#include "mozilla/EnumeratedArrayCycleCollection.h"
// avoid redefined macro in unified build
#undef LOG
#define LOG(msg, ...) \
MOZ_LOG(gMediaControlLog, LogLevel::Debug, \
("MediaSession=%p, " msg, this, ##__VA_ARGS__))
namespace mozilla {
namespace dom {
@ -166,6 +174,22 @@ bool MediaSession::IsSupportedAction(MediaSessionAction aAction) const {
return mActionHandlers[aAction] != nullptr;
}
bool MediaSession::IsActive() const {
RefPtr<BrowsingContext> currentBC = GetParentObject()->GetBrowsingContext();
MOZ_ASSERT(currentBC);
RefPtr<WindowContext> wc = currentBC->GetTopWindowContext();
if (!wc) {
return false;
}
Maybe<uint64_t> activeSessionContextId = wc->GetActiveMediaSessionContextId();
if (!activeSessionContextId) {
return false;
}
LOG("session context Id=%" PRIu64 ", active session context Id=%" PRIu64,
currentBC->Id(), *activeSessionContextId);
return *activeSessionContextId == currentBC->Id();
}
void MediaSession::Shutdown() {
NotifyMediaSessionStatus(SessionStatus::eDestroyed);
}

View File

@ -69,6 +69,14 @@ class MediaSession final : public nsISupports, public nsWrapperCache {
void Shutdown();
// `MediaStatusManager` would determine which media session is an active media
// session and update it from the chrome process. This active session is not
// 100% equal to the active media session in the spec, which is a globally
// active media session *among all tabs*. The active session here is *among
// different windows but in same tab*, so each tab can have at most one
// active media session.
bool IsActive() const;
private:
// Propagate media context status to the media session controller in the
// chrome process when we create or destroy the media session.