Bug 1565689 - part4 : notify controller about media active state and audible state changed from content processes. r=baku

We implement some helpful functions in MediaControlUtils which can be used to notify controller when media starts/stops playing or become audible/inaudible.

For now, we can temporarily notify these changes in AudioChannelService where we have already known when media has these kinds of status changing.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
alwu 2019-08-05 08:48:51 +00:00
parent 03eb5ac7ab
commit 0987d9bd13
5 changed files with 139 additions and 0 deletions

View File

@ -139,6 +139,10 @@ bool IsEnableAudioCompetingForAllAgents() {
namespace mozilla {
namespace dom {
extern void NotifyMediaStarted(uint64_t aWindowID);
extern void NotifyMediaStopped(uint64_t aWindowID);
extern void NotifyMediaAudibleChanged(uint64_t aWindowID, bool aAudible);
const char* SuspendTypeToStr(const nsSuspendedTypes& aSuspend) {
MOZ_ASSERT(aSuspend == nsISuspendedTypes::NONE_SUSPENDED ||
aSuspend == nsISuspendedTypes::SUSPENDED_PAUSE ||
@ -770,6 +774,7 @@ void AudioChannelService::AudioChannelWindow::AppendAgentAndIncreaseAgentsNum(
if (mConfig.mNumberOfAgents == 1) {
NotifyChannelActive(aAgent->WindowID(), true);
}
NotifyMediaStarted(aAgent->WindowID());
}
void AudioChannelService::AudioChannelWindow::RemoveAgentAndReduceAgentsNum(
@ -785,6 +790,7 @@ void AudioChannelService::AudioChannelWindow::RemoveAgentAndReduceAgentsNum(
if (mConfig.mNumberOfAgents == 0) {
NotifyChannelActive(aAgent->WindowID(), false);
}
NotifyMediaStopped(aAgent->WindowID());
}
void AudioChannelService::AudioChannelWindow::AudioCapturedChanged(
@ -824,6 +830,7 @@ void AudioChannelService::AudioChannelWindow::AppendAudibleAgentIfNotContained(
NotifyAudioAudibleChanged(aAgent->Window(), AudibleState::eAudible,
aReason);
}
NotifyMediaAudibleChanged(aAgent->WindowID(), true);
}
}
@ -837,6 +844,7 @@ void AudioChannelService::AudioChannelWindow::RemoveAudibleAgentIfContained(
NotifyAudioAudibleChanged(aAgent->Window(), AudibleState::eNotAudible,
aReason);
}
NotifyMediaAudibleChanged(aAgent->WindowID(), false);
}
}

View File

@ -12,6 +12,7 @@
#include "ContentParent.h"
#include "ProcessUtils.h"
#include "BrowserParent.h"
#include "mozilla/dom/MediaControlService.h"
#if defined(ANDROID) || defined(LINUX)
# include <sys/time.h>
@ -5780,6 +5781,28 @@ mozilla::ipc::IPCResult ContentParent::RecvStoreUserInteractionAsPermission(
return IPC_OK();
}
mozilla::ipc::IPCResult ContentParent::RecvNotifyMediaActiveChanged(
BrowsingContext* aContext, bool aActive) {
RefPtr<MediaControlService> service = MediaControlService::GetService();
MOZ_ASSERT(!aContext->GetParent(), "Should be top level browsing context!");
RefPtr<MediaController> controller =
service->GetOrCreateControllerById(aContext->Id());
controller->NotifyMediaActiveChanged(aActive);
return IPC_OK();
}
mozilla::ipc::IPCResult ContentParent::RecvNotifyMediaAudibleChanged(
BrowsingContext* aContext, bool aAudible) {
RefPtr<MediaControlService> service = MediaControlService::GetService();
MOZ_ASSERT(!aContext->GetParent(), "Should be top level browsing context!");
RefPtr<MediaController> controller =
service->GetControllerById(aContext->Id());
if (controller) {
controller->NotifyMediaAudibleChanged(aAudible);
}
return IPC_OK();
}
mozilla::ipc::IPCResult ContentParent::RecvAttachBrowsingContext(
BrowsingContext::IPCInitializer&& aInit) {
RefPtr<CanonicalBrowsingContext> parent;

View File

@ -1186,6 +1186,12 @@ class ContentParent final : public PContentParent,
mozilla::ipc::IPCResult RecvStoreUserInteractionAsPermission(
const Principal& aPrincipal);
mozilla::ipc::IPCResult RecvNotifyMediaActiveChanged(
BrowsingContext* aContext, bool aActive);
mozilla::ipc::IPCResult RecvNotifyMediaAudibleChanged(
BrowsingContext* aContext, bool aAudible);
// Notify the ContentChild to enable the input event prioritization when
// initializing.
void MaybeEnableRemoteInputEventQueue();

View File

@ -1383,6 +1383,18 @@ parent:
async StoreUserInteractionAsPermission(Principal aPrincipal);
/**
* When media started or stopped in content process, we have to notify the
* chrome process in order to know which tab is playing media.
*/
async NotifyMediaActiveChanged(BrowsingContext aContext, bool aActive);
/**
* When media became audible or inaudible in content process, we have to
* notify chrome process in order to which tab is audible.
*/
async NotifyMediaAudibleChanged(BrowsingContext aContext, bool aAudible);
both:
async CommitBrowsingContextTransaction(BrowsingContext aContext,
BrowsingContextTransaction aTransaction,

View File

@ -10,6 +10,11 @@
#include "MediaController.h"
#include "MediaControlService.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/ContentChild.h"
#include "nsGlobalWindowOuter.h"
#include "nsXULAppAPI.h"
mozilla::LazyLogModule gMediaControlLog("MediaControl");
#undef LOG
@ -17,4 +22,89 @@ mozilla::LazyLogModule gMediaControlLog("MediaControl");
MOZ_LOG(gMediaControlLog, LogLevel::Debug, \
("MediaControlUtils, " msg, ##__VA_ARGS__))
namespace mozilla {
namespace dom {
static void NotifyMediaActiveChanged(const RefPtr<BrowsingContext>& aBc,
bool aActive) {
if (XRE_IsContentProcess()) {
ContentChild* contentChild = ContentChild::GetSingleton();
Unused << contentChild->SendNotifyMediaActiveChanged(aBc, aActive);
} else {
MediaControlService::GetService()
->GetOrCreateControllerById(aBc->Id())
->NotifyMediaActiveChanged(aActive);
}
}
static RefPtr<BrowsingContext> GetBrowingContextByWindowID(uint64_t aWindowID) {
RefPtr<nsGlobalWindowOuter> window =
nsGlobalWindowOuter::GetOuterWindowWithId(aWindowID);
if (!window) {
return nullptr;
}
return window->GetBrowsingContext();
}
const char* ToMediaControlActionsStr(
mozilla::dom::MediaControlActions aAction) {
switch (aAction) {
case MediaControlActions::ePlay:
return "Play";
case MediaControlActions::ePause:
return "Pause";
case MediaControlActions::eStop:
return "Stop";
default:
MOZ_ASSERT_UNREACHABLE("Invalid action.");
}
return "UNKNOWN";
}
void NotifyMediaStarted(uint64_t aWindowID) {
RefPtr<BrowsingContext> bc = GetBrowingContextByWindowID(aWindowID);
if (!bc) {
return;
}
LOG("Notify media started in BC %" PRId64, bc->Id());
bc = bc->Top();
MOZ_ASSERT(bc->IsTopContent(), "Should use top level browsing context.");
NotifyMediaActiveChanged(bc, true);
}
void NotifyMediaStopped(uint64_t aWindowID) {
RefPtr<BrowsingContext> bc = GetBrowingContextByWindowID(aWindowID);
if (!bc) {
return;
}
LOG("Notify media stopped in BC %" PRId64, bc->Id());
bc = bc->Top();
MOZ_ASSERT(bc->IsTopContent(), "Should use top level browsing context.");
NotifyMediaActiveChanged(bc, false);
}
void NotifyMediaAudibleChanged(uint64_t aWindowID, bool aAudible) {
RefPtr<BrowsingContext> bc = GetBrowingContextByWindowID(aWindowID);
if (!bc) {
return;
}
LOG("Notify media became %s in BC %" PRId64,
aAudible ? "audible" : "inaudible", bc->Id());
bc = bc->Top();
MOZ_ASSERT(bc->IsTopContent(), "Should use top level browsing context.");
if (XRE_IsContentProcess()) {
ContentChild* contentChild = ContentChild::GetSingleton();
Unused << contentChild->SendNotifyMediaAudibleChanged(bc, aAudible);
} else {
RefPtr<MediaController> controller =
MediaControlService::GetService()->GetControllerById(bc->Id());
if (controller) {
controller->NotifyMediaAudibleChanged(aAudible);
}
}
}
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_MediaControlUtils_h