Bug 1592037 - part3 : notifty updating media session's metadata. r=MeFisto94

Whenever media session's metadata changes in the content process, we would like to propogate the updated metadata to the media controller in the parent process in order to show that in the virtual media control interface, which would only be set in the chrome process.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
alwu 2020-03-05 20:58:54 +00:00
parent 4b1adaf259
commit 1d40019c19
9 changed files with 127 additions and 2 deletions

View File

@ -5884,6 +5884,19 @@ mozilla::ipc::IPCResult ContentParent::RecvNotifyMediaSessionUpdated(
return IPC_OK();
}
mozilla::ipc::IPCResult ContentParent::RecvNotifyUpdateMediaMetadata(
const MaybeDiscarded<BrowsingContext>& aContext,
const Maybe<MediaMetadataBase>& aMetadata) {
if (aContext.IsNullOrDiscarded()) {
return IPC_OK();
}
if (RefPtr<MediaController> controller =
aContext.get_canonical()->GetMediaController()) {
controller->UpdateMetadata(aContext.ContextId(), aMetadata);
}
return IPC_OK();
}
mozilla::ipc::IPCResult ContentParent::RecvGetModulesTrust(
ModulePaths&& aModPaths, bool aRunAtNormalPriority,
GetModulesTrustResolver&& aResolver) {

View File

@ -1256,6 +1256,10 @@ class ContentParent final
mozilla::ipc::IPCResult RecvNotifyMediaSessionUpdated(
const MaybeDiscarded<BrowsingContext>& aContext, bool aIsCreated);
mozilla::ipc::IPCResult RecvNotifyUpdateMediaMetadata(
const MaybeDiscarded<BrowsingContext>& aContext,
const Maybe<MediaMetadataBase>& aMetadata);
mozilla::ipc::IPCResult RecvGetModulesTrust(
ModulePaths&& aModPaths, bool aRunAtNormalPriority,
GetModulesTrustResolver&& aResolver);

View File

@ -120,6 +120,7 @@ using mozilla::fontlist::Pointer from "SharedFontList.h";
using gfxSparseBitSet from "gfxFontUtils.h";
using mozilla::dom::MediaControlKeysEvent from "ipc/MediaControlIPC.h";
using mozilla::dom::ControlledMediaState from "ipc/MediaControlIPC.h";
using mozilla::dom::MaybeMediaMetadataBase from "mozilla/dom/MediaSessionIPCUtils.h";
using refcounted class nsDocShellLoadState from "nsDocShellLoadState.h";
using mozilla::dom::ServiceWorkerShutdownState::Progress from "mozilla/dom/ServiceWorkerShutdownState.h";
@ -1515,6 +1516,13 @@ parent:
*/
async NotifyMediaSessionUpdated(MaybeDiscardedBrowsingContext aContext, bool aIsCreated);
/**
* This method is used to update media session's media metadata whenever its
* metadata is being updated.
*/
async NotifyUpdateMediaMetadata(MaybeDiscardedBrowsingContext aContext,
MaybeMediaMetadataBase aMetadata);
/**
* Due to sandboxing, a child process's UntrustedModulesProcessor cannot
* obtain enough information about a DLL file to determine its

View File

@ -71,6 +71,11 @@ class MediaMetadata final : public nsISupports,
void SetArtwork(JSContext* aCx, const Sequence<JSObject*>& aArtwork,
ErrorResult& aRv);
// This would expose MediaMetadataBase's members as public, so use this method
// carefully. Now we only use this when we want to update the metadata to the
// media session controller in the chrome process.
MediaMetadataBase* AsMetadataBase() { return this; }
private:
MediaMetadata(nsIGlobalObject* aParent, const nsString& aTitle,
const nsString& aArtist, const nsString& aAlbum);

View File

@ -36,7 +36,7 @@ MediaMetadata* MediaSession::GetMetadata() const { return mMediaMetadata; }
void MediaSession::SetMetadata(MediaMetadata* aMetadata) {
mMediaMetadata = aMetadata;
// TODO: Perform update-metadata algorithm.
NotifyMetadataUpdated();
}
void MediaSession::SetActionHandler(MediaSessionAction aAction,
@ -106,5 +106,25 @@ void MediaSession::NotifyMediaSessionStatus(SessionStatus aState) {
aState == SessionStatus::eCreated);
}
void MediaSession::NotifyMetadataUpdated() {
RefPtr<BrowsingContext> currentBC = GetParentObject()->GetBrowsingContext();
MOZ_ASSERT(currentBC, "Update session metadata after context destroyed!");
Maybe<MediaMetadataBase> metadata;
if (GetMetadata()) {
metadata.emplace(*(GetMetadata()->AsMetadataBase()));
}
if (XRE_IsContentProcess()) {
ContentChild* contentChild = ContentChild::GetSingleton();
Unused << contentChild->SendNotifyUpdateMediaMetadata(currentBC, metadata);
return;
}
// This would only happen when we disable e10s.
if (RefPtr<MediaController> controller =
currentBC->Canonical()->GetMediaController()) {
controller->UpdateMetadata(currentBC->Id(), metadata);
}
}
} // namespace dom
} // namespace mozilla

View File

@ -59,6 +59,8 @@ class MediaSession final : public nsISupports, public nsWrapperCache {
};
void NotifyMediaSessionStatus(SessionStatus aState);
void NotifyMetadataUpdated();
void DispatchNotifyHandler(const MediaSessionActionDetails& aDetails);
MediaSessionActionHandler* GetActionHandler(MediaSessionAction aAction) const;

View File

@ -73,7 +73,10 @@ void MediaSessionController::UpdateMetadata(
LOG("Reset metadata for session %" PRId64, aSessionContextId);
mMetadataMap.GetValue(aSessionContextId)->reset();
} else {
LOG("Update metadata for session %" PRId64, aSessionContextId);
LOG("Update metadata for session %" PRId64 " title=%s artist=%s album=%s",
aSessionContextId, NS_ConvertUTF16toUTF8((*aMetadata).mTitle).get(),
NS_ConvertUTF16toUTF8(aMetadata->mArtist).get(),
NS_ConvertUTF16toUTF8(aMetadata->mAlbum).get());
mMetadataMap.Put(aSessionContextId, aMetadata);
}
}

View File

@ -0,0 +1,69 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef DOM_MEDIA_MEDIASESSION_MEDIASESSIONIPCUTILS_H_
#define DOM_MEDIA_MEDIASESSION_MEDIASESSIONIPCUTILS_H_
#include "ipc/IPCMessageUtils.h"
#include "MediaMetadata.h"
#include "mozilla/dom/MediaSessionBinding.h"
#include "mozilla/Maybe.h"
namespace mozilla {
namespace dom {
typedef Maybe<MediaMetadataBase> MaybeMediaMetadataBase;
} // namespace dom
} // namespace mozilla
namespace IPC {
template <>
struct ParamTraits<mozilla::dom::MediaImage> {
typedef mozilla::dom::MediaImage paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, aParam.mSizes);
WriteParam(aMsg, aParam.mSrc);
WriteParam(aMsg, aParam.mType);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
if (!ReadParam(aMsg, aIter, &(aResult->mSizes)) ||
!ReadParam(aMsg, aIter, &(aResult->mSrc)) ||
!ReadParam(aMsg, aIter, &(aResult->mType))) {
return false;
}
return true;
}
};
template <>
struct ParamTraits<mozilla::dom::MediaMetadataBase> {
typedef mozilla::dom::MediaMetadataBase paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, aParam.mTitle);
WriteParam(aMsg, aParam.mArtist);
WriteParam(aMsg, aParam.mAlbum);
WriteParam(aMsg, aParam.mArtwork);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
if (!ReadParam(aMsg, aIter, &(aResult->mTitle)) ||
!ReadParam(aMsg, aIter, &(aResult->mArtist)) ||
!ReadParam(aMsg, aIter, &(aResult->mAlbum)) ||
!ReadParam(aMsg, aIter, &(aResult->mArtwork))) {
return false;
}
return true;
}
};
} // namespace IPC
#endif // DOM_MEDIA_MEDIASESSION_MEDIASESSIONIPCUTILS_H_

View File

@ -10,6 +10,7 @@ EXPORTS.mozilla.dom += [
'MediaMetadata.h',
'MediaSession.h',
'MediaSessionController.h',
'MediaSessionIPCUtils.h',
'MediaSessionUtils.h',
]