summaryrefslogtreecommitdiffstats
path: root/dom/media/mediacontrol
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/mediacontrol')
-rw-r--r--dom/media/mediacontrol/ContentMediaController.cpp4
-rw-r--r--dom/media/mediacontrol/ContentMediaController.h2
-rw-r--r--dom/media/mediacontrol/ContentPlaybackController.cpp9
-rw-r--r--dom/media/mediacontrol/MediaControlKeyManager.cpp14
-rw-r--r--dom/media/mediacontrol/MediaControlKeyManager.h2
-rw-r--r--dom/media/mediacontrol/MediaControlKeySource.cpp6
-rw-r--r--dom/media/mediacontrol/MediaControlKeySource.h8
-rw-r--r--dom/media/mediacontrol/MediaControlService.cpp10
-rw-r--r--dom/media/mediacontrol/MediaControlUtils.h13
-rw-r--r--dom/media/mediacontrol/MediaController.cpp20
-rw-r--r--dom/media/mediacontrol/MediaController.h2
-rw-r--r--dom/media/mediacontrol/MediaStatusManager.cpp27
-rw-r--r--dom/media/mediacontrol/MediaStatusManager.h13
-rw-r--r--dom/media/mediacontrol/tests/browser/browser_media_control_before_media_starts.js2
-rw-r--r--dom/media/mediacontrol/tests/gtest/MediaKeyListenerTest.h2
-rw-r--r--dom/media/mediacontrol/tests/gtest/moz.build2
16 files changed, 96 insertions, 40 deletions
diff --git a/dom/media/mediacontrol/ContentMediaController.cpp b/dom/media/mediacontrol/ContentMediaController.cpp
index 1171785fe4..c0b466ff0f 100644
--- a/dom/media/mediacontrol/ContentMediaController.cpp
+++ b/dom/media/mediacontrol/ContentMediaController.cpp
@@ -286,8 +286,8 @@ void ContentMediaAgent::NotifyMediaFullScreenState(uint64_t aBrowsingContextId,
}
}
-void ContentMediaAgent::UpdatePositionState(uint64_t aBrowsingContextId,
- const PositionState& aState) {
+void ContentMediaAgent::UpdatePositionState(
+ uint64_t aBrowsingContextId, const Maybe<PositionState>& aState) {
RefPtr<BrowsingContext> bc = GetBrowsingContextForAgent(aBrowsingContextId);
if (!bc || bc->IsDiscarded()) {
return;
diff --git a/dom/media/mediacontrol/ContentMediaController.h b/dom/media/mediacontrol/ContentMediaController.h
index 9e162dbb27..a58be24b9d 100644
--- a/dom/media/mediacontrol/ContentMediaController.h
+++ b/dom/media/mediacontrol/ContentMediaController.h
@@ -66,7 +66,7 @@ class ContentMediaAgent : public IMediaInfoUpdater {
void NotifyMediaFullScreenState(uint64_t aBrowsingContextId,
bool aIsInFullScreen) override;
void UpdatePositionState(uint64_t aBrowsingContextId,
- const PositionState& aState) override;
+ const Maybe<PositionState>& aState) override;
// Use these methods to register/unregister `ContentMediaControlKeyReceiver`
// in order to listen to media control key events.
diff --git a/dom/media/mediacontrol/ContentPlaybackController.cpp b/dom/media/mediacontrol/ContentPlaybackController.cpp
index ba48c0a5ce..fcc8e3ab58 100644
--- a/dom/media/mediacontrol/ContentPlaybackController.cpp
+++ b/dom/media/mediacontrol/ContentPlaybackController.cpp
@@ -168,8 +168,12 @@ void ContentMediaControlKeyHandler::HandleMediaControlAction(
if (!aContext->GetDocShell()) {
return;
}
+ if (aAction.mKey.isNothing()) {
+ MOZ_ASSERT_UNREACHABLE("Invalid media control key.");
+ return;
+ }
ContentPlaybackController controller(aContext);
- switch (aAction.mKey) {
+ switch (aAction.mKey.value()) {
case MediaControlKey::Focus:
controller.Focus();
return;
@@ -179,6 +183,9 @@ void ContentMediaControlKeyHandler::HandleMediaControlAction(
case MediaControlKey::Pause:
controller.Pause();
return;
+ case MediaControlKey::Playpause:
+ MOZ_ASSERT_UNREACHABLE("Invalid media control key.");
+ return;
case MediaControlKey::Stop:
controller.Stop();
return;
diff --git a/dom/media/mediacontrol/MediaControlKeyManager.cpp b/dom/media/mediacontrol/MediaControlKeyManager.cpp
index 4cb562aa84..ba6ed3a524 100644
--- a/dom/media/mediacontrol/MediaControlKeyManager.cpp
+++ b/dom/media/mediacontrol/MediaControlKeyManager.cpp
@@ -184,10 +184,16 @@ void MediaControlKeyManager::SetEnablePictureInPictureMode(bool aIsEnabled) {
}
}
-void MediaControlKeyManager::SetPositionState(const PositionState& aState) {
- LOG_INFO("Set PositionState, duration=%f, playbackRate=%f, position=%f",
- aState.mDuration, aState.mPlaybackRate,
- aState.mLastReportedPlaybackPosition);
+void MediaControlKeyManager::SetPositionState(
+ const Maybe<PositionState>& aState) {
+ if (aState) {
+ LOG_INFO("Set PositionState, duration=%f, playbackRate=%f, position=%f",
+ aState->mDuration, aState->mPlaybackRate,
+ aState->mLastReportedPlaybackPosition);
+ } else {
+ LOG_INFO("Set PositionState, Nothing");
+ }
+
if (mEventSource && mEventSource->IsOpened()) {
mEventSource->SetPositionState(aState);
}
diff --git a/dom/media/mediacontrol/MediaControlKeyManager.h b/dom/media/mediacontrol/MediaControlKeyManager.h
index feb857e335..9b029f3bc9 100644
--- a/dom/media/mediacontrol/MediaControlKeyManager.h
+++ b/dom/media/mediacontrol/MediaControlKeyManager.h
@@ -41,7 +41,7 @@ class MediaControlKeyManager final : public MediaControlKeySource,
void SetSupportedMediaKeys(const MediaKeysArray& aSupportedKeys) override;
void SetEnableFullScreen(bool aIsEnabled) override;
void SetEnablePictureInPictureMode(bool aIsEnabled) override;
- void SetPositionState(const PositionState& aState) override;
+ void SetPositionState(const Maybe<PositionState>& aState) override;
private:
~MediaControlKeyManager();
diff --git a/dom/media/mediacontrol/MediaControlKeySource.cpp b/dom/media/mediacontrol/MediaControlKeySource.cpp
index 22756c860a..db372fc57b 100644
--- a/dom/media/mediacontrol/MediaControlKeySource.cpp
+++ b/dom/media/mediacontrol/MediaControlKeySource.cpp
@@ -36,7 +36,11 @@ void MediaControlKeyHandler::OnActionPerformed(
return;
}
- switch (aAction.mKey) {
+ if (aAction.mKey.isNothing()) {
+ MOZ_ASSERT_UNREACHABLE("Error : undefined media key!");
+ return;
+ }
+ switch (aAction.mKey.value()) {
case MediaControlKey::Focus:
controller->Focus();
return;
diff --git a/dom/media/mediacontrol/MediaControlKeySource.h b/dom/media/mediacontrol/MediaControlKeySource.h
index f5d62a429e..4ab2c8b8be 100644
--- a/dom/media/mediacontrol/MediaControlKeySource.h
+++ b/dom/media/mediacontrol/MediaControlKeySource.h
@@ -28,10 +28,10 @@ struct SeekDetails {
struct MediaControlAction {
MediaControlAction() = default;
- explicit MediaControlAction(MediaControlKey aKey) : mKey(aKey) {}
+ explicit MediaControlAction(MediaControlKey aKey) : mKey(Some(aKey)) {}
MediaControlAction(MediaControlKey aKey, const SeekDetails& aDetails)
- : mKey(aKey), mDetails(Some(aDetails)) {}
- MediaControlKey mKey = MediaControlKey::EndGuard_;
+ : mKey(Some(aKey)), mDetails(Some(aDetails)) {}
+ Maybe<MediaControlKey> mKey;
Maybe<SeekDetails> mDetails;
};
@@ -109,7 +109,7 @@ class MediaControlKeySource {
// to notify change to the embedded application.
virtual void SetEnableFullScreen(bool aIsEnabled){};
virtual void SetEnablePictureInPictureMode(bool aIsEnabled){};
- virtual void SetPositionState(const PositionState& aState){};
+ virtual void SetPositionState(const Maybe<PositionState>& aState){};
protected:
virtual ~MediaControlKeySource() = default;
diff --git a/dom/media/mediacontrol/MediaControlService.cpp b/dom/media/mediacontrol/MediaControlService.cpp
index c321e080d2..f45ab4253d 100644
--- a/dom/media/mediacontrol/MediaControlService.cpp
+++ b/dom/media/mediacontrol/MediaControlService.cpp
@@ -157,6 +157,10 @@ void MediaControlService::NotifyMediaControlHasEverBeenUsed() {
Telemetry::ScalarSet(Telemetry::ScalarID::MEDIA_CONTROL_PLATFORM_USAGE,
u"Android"_ns, usedOnMediaControl);
#endif
+#ifdef MOZ_WIDGET_UIKIT
+ Telemetry::ScalarSet(Telemetry::ScalarID::MEDIA_CONTROL_PLATFORM_USAGE,
+ u"iOS"_ns, usedOnMediaControl);
+#endif
}
void MediaControlService::NotifyMediaControlHasEverBeenEnabled() {
@@ -182,6 +186,10 @@ void MediaControlService::NotifyMediaControlHasEverBeenEnabled() {
Telemetry::ScalarSet(Telemetry::ScalarID::MEDIA_CONTROL_PLATFORM_USAGE,
u"Android"_ns, enableOnMediaControl);
#endif
+#ifdef MOZ_WIDGET_UIKIT
+ Telemetry::ScalarSet(Telemetry::ScalarID::MEDIA_CONTROL_PLATFORM_USAGE,
+ u"iOS"_ns, enableOnMediaControl);
+#endif
}
NS_IMETHODIMP
@@ -510,7 +518,7 @@ void MediaControlService::ControllerManager::ConnectMainControllerEvents() {
mSource->SetEnablePictureInPictureMode(aIsEnabled);
});
mPositionChangedListener = mMainController->PositionChangedEvent().Connect(
- AbstractThread::MainThread(), [this](const PositionState& aState) {
+ AbstractThread::MainThread(), [this](const Maybe<PositionState>& aState) {
mSource->SetPositionState(aState);
});
}
diff --git a/dom/media/mediacontrol/MediaControlUtils.h b/dom/media/mediacontrol/MediaControlUtils.h
index a327c2f3d8..e4e75e7c97 100644
--- a/dom/media/mediacontrol/MediaControlUtils.h
+++ b/dom/media/mediacontrol/MediaControlUtils.h
@@ -50,6 +50,14 @@ inline const char* ToMediaControlKeyStr(MediaControlKey aKey) {
}
}
+inline const char* ToMediaControlKeyStr(const Maybe<MediaControlKey>& aKey) {
+ if (aKey.isNothing()) {
+ MOZ_ASSERT_UNREACHABLE("Invalid action.");
+ return "Unknown";
+ }
+ return ToMediaControlKeyStr(aKey.value());
+}
+
inline const char* ToMediaSessionActionStr(MediaSessionAction aAction) {
switch (aAction) {
case MediaSessionAction::Play:
@@ -99,11 +107,6 @@ inline MediaControlKey ConvertMediaSessionActionToControlKey(
}
}
-inline MediaSessionAction ConvertToMediaSessionAction(uint8_t aActionValue) {
- MOZ_DIAGNOSTIC_ASSERT(aActionValue < uint8_t(MediaSessionAction::EndGuard_));
- return static_cast<MediaSessionAction>(aActionValue);
-}
-
inline const char* ToMediaPlaybackStateStr(MediaPlaybackState aState) {
switch (aState) {
case MediaPlaybackState::eStarted:
diff --git a/dom/media/mediacontrol/MediaController.cpp b/dom/media/mediacontrol/MediaController.cpp
index bfb98f24c9..4290e952b0 100644
--- a/dom/media/mediacontrol/MediaController.cpp
+++ b/dom/media/mediacontrol/MediaController.cpp
@@ -186,9 +186,10 @@ bool MediaController::ShouldPropagateActionToAllContexts(
// These three actions have default action handler for each frame, so we
// need to propagate to all contexts. We would handle default handlers in
// `ContentMediaController::HandleMediaKey`.
- return aAction.mKey == MediaControlKey::Play ||
- aAction.mKey == MediaControlKey::Pause ||
- aAction.mKey == MediaControlKey::Stop;
+ return aAction.mKey.isSome() &&
+ (aAction.mKey.value() == MediaControlKey::Play ||
+ aAction.mKey.value() == MediaControlKey::Pause ||
+ aAction.mKey.value() == MediaControlKey::Stop);
}
void MediaController::UpdateMediaControlActionToContentMediaIfNeeded(
@@ -493,11 +494,16 @@ void MediaController::HandleSupportedMediaSessionActionsChanged(
MediaController_Binding::ClearCachedSupportedKeysValue(this);
}
-void MediaController::HandlePositionStateChanged(const PositionState& aState) {
+void MediaController::HandlePositionStateChanged(
+ const Maybe<PositionState>& aState) {
+ if (!aState) {
+ return;
+ }
+
PositionStateEventInit init;
- init.mDuration = aState.mDuration;
- init.mPlaybackRate = aState.mPlaybackRate;
- init.mPosition = aState.mLastReportedPlaybackPosition;
+ init.mDuration = aState->mDuration;
+ init.mPlaybackRate = aState->mPlaybackRate;
+ init.mPosition = aState->mLastReportedPlaybackPosition;
RefPtr<PositionStateEvent> event =
PositionStateEvent::Constructor(this, u"positionstatechange"_ns, init);
DispatchAsyncEvent(event.forget());
diff --git a/dom/media/mediacontrol/MediaController.h b/dom/media/mediacontrol/MediaController.h
index 82b351ead7..f95ff6368e 100644
--- a/dom/media/mediacontrol/MediaController.h
+++ b/dom/media/mediacontrol/MediaController.h
@@ -159,7 +159,7 @@ class MediaController final : public DOMEventTargetHelper,
void HandleSupportedMediaSessionActionsChanged(
const nsTArray<MediaSessionAction>& aSupportedAction);
- void HandlePositionStateChanged(const PositionState& aState);
+ void HandlePositionStateChanged(const Maybe<PositionState>& aState);
void HandleMetadataChanged(const MediaMetadataBase& aMetadata);
// This would register controller to the media control service that takes a
diff --git a/dom/media/mediacontrol/MediaStatusManager.cpp b/dom/media/mediacontrol/MediaStatusManager.cpp
index 4365e6b531..9187e56f25 100644
--- a/dom/media/mediacontrol/MediaStatusManager.cpp
+++ b/dom/media/mediacontrol/MediaStatusManager.cpp
@@ -154,6 +154,7 @@ void MediaStatusManager::SetActiveMediaSessionContextId(
*mActiveMediaSessionContextId);
mMetadataChangedEvent.Notify(GetCurrentMediaMetadata());
mSupportedActionsChangedEvent.Notify(GetSupportedActions());
+ mPositionStateChangedEvent.Notify(GetCurrentPositionState());
if (StaticPrefs::media_mediacontrol_testingevents_enabled()) {
if (nsCOMPtr<nsIObserverService> obs = services::GetObserverService()) {
obs->NotifyObservers(nullptr, "active-media-session-changed", nullptr);
@@ -170,6 +171,7 @@ void MediaStatusManager::ClearActiveMediaSessionContextIdIfNeeded() {
StoreMediaSessionContextIdOnWindowContext();
mMetadataChangedEvent.Notify(GetCurrentMediaMetadata());
mSupportedActionsChangedEvent.Notify(GetSupportedActions());
+ mPositionStateChangedEvent.Notify(GetCurrentPositionState());
if (StaticPrefs::media_mediacontrol_testingevents_enabled()) {
if (nsCOMPtr<nsIObserverService> obs = services::GetObserverService()) {
obs->NotifyObservers(nullptr, "active-media-session-changed", nullptr);
@@ -362,8 +364,14 @@ void MediaStatusManager::DisableAction(uint64_t aBrowsingContextId,
NotifySupportedKeysChangedIfNeeded(aBrowsingContextId);
}
-void MediaStatusManager::UpdatePositionState(uint64_t aBrowsingContextId,
- const PositionState& aState) {
+void MediaStatusManager::UpdatePositionState(
+ uint64_t aBrowsingContextId, const Maybe<PositionState>& aState) {
+ auto info = mMediaSessionInfoMap.Lookup(aBrowsingContextId);
+ if (info) {
+ LOG("Update position state for context %" PRIu64, aBrowsingContextId);
+ info->mPositionState = aState;
+ }
+
// The position state comes from non-active media session which we don't care.
if (!mActiveMediaSessionContextId ||
*mActiveMediaSessionContextId != aBrowsingContextId) {
@@ -393,9 +401,8 @@ CopyableTArray<MediaSessionAction> MediaStatusManager::GetSupportedActions()
MediaSessionInfo info =
mMediaSessionInfoMap.Get(*mActiveMediaSessionContextId);
- const uint8_t actionNums = uint8_t(MediaSessionAction::EndGuard_);
- for (uint8_t actionValue = 0; actionValue < actionNums; actionValue++) {
- MediaSessionAction action = ConvertToMediaSessionAction(actionValue);
+ for (MediaSessionAction action :
+ MakeWebIDLEnumeratedRange<MediaSessionAction>()) {
if (info.IsActionSupported(action)) {
supportedActions.AppendElement(action);
}
@@ -421,6 +428,16 @@ MediaMetadataBase MediaStatusManager::GetCurrentMediaMetadata() const {
return CreateDefaultMetadata();
}
+Maybe<PositionState> MediaStatusManager::GetCurrentPositionState() const {
+ if (mActiveMediaSessionContextId) {
+ auto info = mMediaSessionInfoMap.Lookup(*mActiveMediaSessionContextId);
+ if (info) {
+ return info->mPositionState;
+ }
+ }
+ return Nothing();
+}
+
void MediaStatusManager::FillMissingTitleAndArtworkIfNeeded(
MediaMetadataBase& aMetadata) const {
// If the metadata doesn't set its title and artwork properly, we would like
diff --git a/dom/media/mediacontrol/MediaStatusManager.h b/dom/media/mediacontrol/MediaStatusManager.h
index 24247d119d..a4216c8453 100644
--- a/dom/media/mediacontrol/MediaStatusManager.h
+++ b/dom/media/mediacontrol/MediaStatusManager.h
@@ -53,6 +53,7 @@ class MediaSessionInfo {
Maybe<MediaMetadataBase> mMetadata;
MediaSessionPlaybackState mDeclaredPlaybackState =
MediaSessionPlaybackState::None;
+ Maybe<PositionState> mPositionState;
// Use bitwise to store the supported actions.
uint32_t mSupportedActions = 0;
};
@@ -118,7 +119,7 @@ class IMediaInfoUpdater {
// Use this method when media session update its position state.
virtual void UpdatePositionState(uint64_t aBrowsingContextId,
- const PositionState& aState) = 0;
+ const Maybe<PositionState>& aState) = 0;
};
/**
@@ -163,7 +164,7 @@ class MediaStatusManager : public IMediaInfoUpdater {
void DisableAction(uint64_t aBrowsingContextId,
MediaSessionAction aAction) override;
void UpdatePositionState(uint64_t aBrowsingContextId,
- const PositionState& aState) override;
+ const Maybe<PositionState>& aState) override;
// Return active media session's metadata if active media session exists and
// it has already set its metadata. Otherwise, return default media metadata
@@ -180,7 +181,7 @@ class MediaStatusManager : public IMediaInfoUpdater {
return mMetadataChangedEvent;
}
- MediaEventSource<PositionState>& PositionChangedEvent() {
+ MediaEventSource<Maybe<PositionState>>& PositionChangedEvent() {
return mPositionStateChangedEvent;
}
@@ -246,6 +247,10 @@ class MediaStatusManager : public IMediaInfoUpdater {
// media session doesn't exist, return 'None' instead.
MediaSessionPlaybackState GetCurrentDeclaredPlaybackState() const;
+ // Return the active media session's position state. If the active media
+ // session doesn't exist or doesn't have any state, Nothing is returned.
+ Maybe<PositionState> GetCurrentPositionState() const;
+
// This state can match to the `guessed playback state` in the spec [1], it
// indicates if we have any media element playing within the tab which this
// controller belongs to. But currently we only take media elements into
@@ -266,7 +271,7 @@ class MediaStatusManager : public IMediaInfoUpdater {
MediaEventProducer<MediaMetadataBase> mMetadataChangedEvent;
MediaEventProducer<nsTArray<MediaSessionAction>>
mSupportedActionsChangedEvent;
- MediaEventProducer<PositionState> mPositionStateChangedEvent;
+ MediaEventProducer<Maybe<PositionState>> mPositionStateChangedEvent;
MediaEventProducer<MediaSessionPlaybackState> mPlaybackStateChangedEvent;
MediaPlaybackStatus mPlaybackStatusDelegate;
};
diff --git a/dom/media/mediacontrol/tests/browser/browser_media_control_before_media_starts.js b/dom/media/mediacontrol/tests/browser/browser_media_control_before_media_starts.js
index 292c2f521f..a0c75bfa7c 100644
--- a/dom/media/mediacontrol/tests/browser/browser_media_control_before_media_starts.js
+++ b/dom/media/mediacontrol/tests/browser/browser_media_control_before_media_starts.js
@@ -184,7 +184,7 @@ function enableMediaFullScreenInIframe(tab) {
}
function waitUntilIframeMediaStartedPlaying(tab) {
- return SpecialPowers.spawn(tab.linkedBrowser, [IFRAME_URL], async url => {
+ return SpecialPowers.spawn(tab.linkedBrowser, [IFRAME_URL], async () => {
info(`check if media in iframe starts playing`);
const iframe = content.document.getElementById("iframe");
iframe.contentWindow.postMessage("check-playing", "*");
diff --git a/dom/media/mediacontrol/tests/gtest/MediaKeyListenerTest.h b/dom/media/mediacontrol/tests/gtest/MediaKeyListenerTest.h
index 5145eb7dbb..50ef254947 100644
--- a/dom/media/mediacontrol/tests/gtest/MediaKeyListenerTest.h
+++ b/dom/media/mediacontrol/tests/gtest/MediaKeyListenerTest.h
@@ -18,7 +18,7 @@ class MediaKeyListenerTest : public MediaControlKeyListener {
void Clear() { mReceivedKey = mozilla::Nothing(); }
void OnActionPerformed(const MediaControlAction& aAction) override {
- mReceivedKey = mozilla::Some(aAction.mKey);
+ mReceivedKey = aAction.mKey;
}
bool IsResultEqualTo(MediaControlKey aResult) const {
if (mReceivedKey) {
diff --git a/dom/media/mediacontrol/tests/gtest/moz.build b/dom/media/mediacontrol/tests/gtest/moz.build
index 7043bfcd5e..a8602f6718 100644
--- a/dom/media/mediacontrol/tests/gtest/moz.build
+++ b/dom/media/mediacontrol/tests/gtest/moz.build
@@ -11,7 +11,7 @@ UNIFIED_SOURCES += [
"TestMediaKeysEvent.cpp",
]
-if CONFIG["MOZ_APPLEMEDIA"]:
+if CONFIG["MOZ_APPLEMEDIA"] and CONFIG["TARGET_OS"] == "OSX":
UNIFIED_SOURCES += ["TestMediaKeysEventMac.mm", "TestMediaKeysEventMediaCenter.mm"]
include("/ipc/chromium/chromium-config.mozbuild")