Bug 1780796 - Use one process per platform decoder module sandbox requirements r=alwu,nika,fluent-reviewers,flod

Differential Revision: https://phabricator.services.mozilla.com/D152545
This commit is contained in:
Alexandre Lissy 2022-09-01 12:59:32 +00:00
Родитель bbf9109b68
Коммит b135ca0732
39 изменённых файлов: 498 добавлений и 179 удалений

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

@ -1033,14 +1033,17 @@ static WebIDLUtilityActorName UtilityActorNameToWebIDL(
mozilla::UtilityActorName aType) { mozilla::UtilityActorName aType) {
// Max is the value of the last enum, not the length, so add one. // Max is the value of the last enum, not the length, so add one.
static_assert(WebIDLUtilityActorNameValues::Count == static_assert(WebIDLUtilityActorNameValues::Count ==
static_cast<size_t>(UtilityActorName::AudioDecoder) + 1, static_cast<size_t>(UtilityActorName::AudioDecoder_WMF) + 1,
"In order for this static cast to be okay, " "In order for this static cast to be okay, "
"UtilityActorName must match UtilityActorName exactly"); "UtilityActorName must match UtilityActorName exactly");
// These must match the similar ones in ProcInfo.h and ChromeUtils.webidl // These must match the similar ones in ProcInfo.h and ChromeUtils.webidl
switch (aType) { switch (aType) {
UTILITYACTORNAME_TO_WEBIDL_CASE(Unknown, Unknown); UTILITYACTORNAME_TO_WEBIDL_CASE(Unknown, Unknown);
UTILITYACTORNAME_TO_WEBIDL_CASE(AudioDecoder, AudioDecoder); UTILITYACTORNAME_TO_WEBIDL_CASE(AudioDecoder_Generic, AudioDecoder_Generic);
UTILITYACTORNAME_TO_WEBIDL_CASE(AudioDecoder_AppleMedia,
AudioDecoder_AppleMedia);
UTILITYACTORNAME_TO_WEBIDL_CASE(AudioDecoder_WMF, AudioDecoder_WMF);
} }
MOZ_ASSERT(false, "Unhandled case in WebIDLUtilityActorName"); MOZ_ASSERT(false, "Unhandled case in WebIDLUtilityActorName");

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

@ -706,7 +706,9 @@ dictionary WindowInfoDictionary {
*/ */
enum WebIDLUtilityActorName { enum WebIDLUtilityActorName {
"unknown", "unknown",
"audioDecoder", "audioDecoder_Generic",
"audioDecoder_AppleMedia",
"audioDecoder_WMF",
}; };
dictionary UtilityActorsDictionary { dictionary UtilityActorsDictionary {

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

@ -4906,7 +4906,7 @@ bool StartOpenBSDSandbox(GeckoProcessType type, ipc::SandboxingKind kind) {
MOZ_RELEASE_ASSERT(kind <= SandboxingKind::COUNT, MOZ_RELEASE_ASSERT(kind <= SandboxingKind::COUNT,
"Should define a sandbox"); "Should define a sandbox");
switch (kind) { switch (kind) {
case ipc::SandboxingKind::UTILITY_AUDIO_DECODING: case ipc::SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC:
OpenBSDFindPledgeUnveilFilePath("pledge.utility-audioDecoder", OpenBSDFindPledgeUnveilFilePath("pledge.utility-audioDecoder",
pledgeFile); pledgeFile);
OpenBSDFindPledgeUnveilFilePath("unveil.utility-audioDecoder", OpenBSDFindPledgeUnveilFilePath("unveil.utility-audioDecoder",

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

@ -0,0 +1,76 @@
/* 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/. */
#include "RemoteDecodeUtils.h"
#include "mozilla/ipc/UtilityProcessChild.h"
namespace mozilla {
using SandboxingKind = ipc::SandboxingKind;
SandboxingKind GetCurrentSandboxingKind() {
MOZ_ASSERT(XRE_IsUtilityProcess());
return ipc::UtilityProcessChild::GetSingleton()->mSandbox;
}
SandboxingKind GetSandboxingKindFromLocation(RemoteDecodeIn aLocation) {
switch (aLocation) {
case RemoteDecodeIn::UtilityProcess_Generic:
return SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC;
#ifdef MOZ_APPLEMEDIA
case RemoteDecodeIn::UtilityProcess_AppleMedia:
return SandboxingKind::UTILITY_AUDIO_DECODING_APPLE_MEDIA;
break;
#endif
#ifdef XP_WIN
case RemoteDecodeIn::UtilityProcess_WMF:
return SandboxingKind::UTILITY_AUDIO_DECODING_WMF;
#endif
default:
MOZ_ASSERT_UNREACHABLE("Unsupported RemoteDecodeIn");
return SandboxingKind::COUNT;
}
}
RemoteDecodeIn GetRemoteDecodeInFromKind(SandboxingKind aKind) {
switch (aKind) {
case SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC:
return RemoteDecodeIn::UtilityProcess_Generic;
#ifdef MOZ_APPLEMEDIA
case SandboxingKind::UTILITY_AUDIO_DECODING_APPLE_MEDIA:
return RemoteDecodeIn::UtilityProcess_AppleMedia;
#endif
#ifdef XP_WIN
case SandboxingKind::UTILITY_AUDIO_DECODING_WMF:
return RemoteDecodeIn::UtilityProcess_WMF;
#endif
default:
MOZ_ASSERT_UNREACHABLE("Unsupported SandboxingKind");
return RemoteDecodeIn::Unspecified;
}
}
const char* RemoteDecodeInToStr(RemoteDecodeIn aLocation) {
switch (aLocation) {
case RemoteDecodeIn::RddProcess:
return "RDD";
case RemoteDecodeIn::GpuProcess:
return "GPU";
case RemoteDecodeIn::UtilityProcess_Generic:
return "Utility Generic";
#ifdef MOZ_APPLEMEDIA
case RemoteDecodeIn::UtilityProcess_AppleMedia:
return "Utility AppleMedia";
#endif
#ifdef XP_WIN
case RemoteDecodeIn::UtilityProcess_WMF:
return "Utility WMF";
#endif
default:
MOZ_ASSERT_UNREACHABLE("Unsupported RemoteDecodeIn");
return "Unknown";
}
}
} // namespace mozilla

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

@ -0,0 +1,28 @@
/* 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_IPC_REMOTEDECODEUTILS_H_
#define DOM_MEDIA_IPC_REMOTEDECODEUTILS_H_
#include "mozilla/Logging.h"
#include "mozilla/RemoteDecoderManagerChild.h"
#include "mozilla/ipc/UtilityProcessSandboxing.h"
namespace mozilla {
inline LazyLogModule gRemoteDecodeLog{"RemoteDecode"};
// Return the sandboxing kind of the current utility process. Should only be
// called on the utility process.
ipc::SandboxingKind GetCurrentSandboxingKind();
ipc::SandboxingKind GetSandboxingKindFromLocation(RemoteDecodeIn aLocation);
RemoteDecodeIn GetRemoteDecodeInFromKind(ipc::SandboxingKind aKind);
const char* RemoteDecodeInToStr(RemoteDecodeIn aLocation);
} // namespace mozilla
#endif // DOM_MEDIA_IPC_REMOTEDECODEUTILS_H_

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

@ -7,6 +7,8 @@
#include "RemoteDecoderManagerChild.h" #include "RemoteDecoderManagerChild.h"
#include "mozilla/RemoteDecodeUtils.h"
namespace mozilla { namespace mozilla {
RemoteDecoderChild::RemoteDecoderChild(RemoteDecodeIn aLocation) RemoteDecoderChild::RemoteDecoderChild(RemoteDecodeIn aLocation)
@ -99,13 +101,11 @@ RefPtr<MediaDataDecoder::InitPromise> RemoteDecoderChild::Init() {
return; return;
} }
const auto& initResponse = aResponse.get_InitCompletionIPDL(); const auto& initResponse = aResponse.get_InitCompletionIPDL();
mDescription = mDescription = initResponse.decoderDescription();
initResponse.decoderDescription() + mDescription.Append(" (");
(GetManager()->Location() == RemoteDecodeIn::UtilityProcess mDescription.Append(RemoteDecodeInToStr(GetManager()->Location()));
? " (Utility remote)"_ns mDescription.Append(" remote)");
: GetManager()->Location() == RemoteDecodeIn::RddProcess
? " (RDD remote)"_ns
: " (GPU remote)"_ns);
mIsHardwareAccelerated = initResponse.hardware(); mIsHardwareAccelerated = initResponse.hardware();
mHardwareAcceleratedReason = initResponse.hardwareReason(); mHardwareAcceleratedReason = initResponse.hardwareReason();
mConversion = initResponse.conversion(); mConversion = initResponse.conversion();

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

@ -19,6 +19,7 @@
#include "mozilla/ipc/PBackgroundChild.h" #include "mozilla/ipc/PBackgroundChild.h"
#include "mozilla/ipc/Endpoint.h" #include "mozilla/ipc/Endpoint.h"
#include "mozilla/layers/ISurfaceAllocator.h" #include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/ipc/UtilityAudioDecoderChild.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsIObserver.h" #include "nsIObserver.h"
#include "mozilla/StaticPrefs_media.h" #include "mozilla/StaticPrefs_media.h"
@ -192,7 +193,9 @@ RemoteDecoderManagerChild* RemoteDecoderManagerChild::GetSingleton(
switch (aLocation) { switch (aLocation) {
case RemoteDecodeIn::GpuProcess: case RemoteDecodeIn::GpuProcess:
case RemoteDecodeIn::RddProcess: case RemoteDecodeIn::RddProcess:
case RemoteDecodeIn::UtilityProcess: case RemoteDecodeIn::UtilityProcess_Generic:
case RemoteDecodeIn::UtilityProcess_AppleMedia:
case RemoteDecodeIn::UtilityProcess_WMF:
return sRemoteDecoderManagerChildForProcesses[aLocation]; return sRemoteDecoderManagerChildForProcesses[aLocation];
default: default:
MOZ_CRASH("Unexpected RemoteDecode variant"); MOZ_CRASH("Unexpected RemoteDecode variant");
@ -214,7 +217,9 @@ bool RemoteDecoderManagerChild::Supports(
switch (aLocation) { switch (aLocation) {
case RemoteDecodeIn::GpuProcess: case RemoteDecodeIn::GpuProcess:
case RemoteDecodeIn::RddProcess: case RemoteDecodeIn::RddProcess:
case RemoteDecodeIn::UtilityProcess: { case RemoteDecodeIn::UtilityProcess_AppleMedia:
case RemoteDecodeIn::UtilityProcess_Generic:
case RemoteDecodeIn::UtilityProcess_WMF: {
StaticMutexAutoLock lock(sProcessSupportedMutex); StaticMutexAutoLock lock(sProcessSupportedMutex);
supported = sProcessSupported[aLocation]; supported = sProcessSupported[aLocation];
break; break;
@ -225,8 +230,10 @@ bool RemoteDecoderManagerChild::Supports(
if (!supported) { if (!supported) {
// We haven't received the correct information yet from either the GPU or // We haven't received the correct information yet from either the GPU or
// the RDD process nor the Utility process. // the RDD process nor the Utility process.
if (aLocation == RemoteDecodeIn::UtilityProcess) { if (aLocation == RemoteDecodeIn::UtilityProcess_Generic ||
LaunchUtilityProcessIfNeeded(); aLocation == RemoteDecodeIn::UtilityProcess_AppleMedia ||
aLocation == RemoteDecodeIn::UtilityProcess_WMF) {
LaunchUtilityProcessIfNeeded(aLocation);
} }
if (aLocation == RemoteDecodeIn::RddProcess) { if (aLocation == RemoteDecodeIn::RddProcess) {
// Ensure the RDD process got started. // Ensure the RDD process got started.
@ -274,10 +281,13 @@ RemoteDecoderManagerChild::CreateAudioDecoder(
__func__); __func__);
} }
bool useUtilityAudioDecoding = StaticPrefs::media_utility_process_enabled() && bool useUtilityAudioDecoding =
aLocation == RemoteDecodeIn::UtilityProcess; StaticPrefs::media_utility_process_enabled() &&
(aLocation == RemoteDecodeIn::UtilityProcess_Generic ||
aLocation == RemoteDecodeIn::UtilityProcess_AppleMedia ||
aLocation == RemoteDecodeIn::UtilityProcess_WMF);
RefPtr<GenericNonExclusivePromise> launchPromise = RefPtr<GenericNonExclusivePromise> launchPromise =
useUtilityAudioDecoding ? LaunchUtilityProcessIfNeeded() useUtilityAudioDecoding ? LaunchUtilityProcessIfNeeded(aLocation)
: LaunchRDDProcessIfNeeded(); : LaunchRDDProcessIfNeeded();
return launchPromise->Then( return launchPromise->Then(
@ -482,7 +492,8 @@ RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded() {
/* static */ /* static */
RefPtr<GenericNonExclusivePromise> RefPtr<GenericNonExclusivePromise>
RemoteDecoderManagerChild::LaunchUtilityProcessIfNeeded() { RemoteDecoderManagerChild::LaunchUtilityProcessIfNeeded(
RemoteDecodeIn aLocation) {
MOZ_DIAGNOSTIC_ASSERT(XRE_IsContentProcess(), MOZ_DIAGNOSTIC_ASSERT(XRE_IsContentProcess(),
"Only supported from a content process."); "Only supported from a content process.");
@ -494,7 +505,7 @@ RemoteDecoderManagerChild::LaunchUtilityProcessIfNeeded() {
} }
StaticMutexAutoLock lock(sLaunchMutex); StaticMutexAutoLock lock(sLaunchMutex);
auto& utilityLaunchPromise = sLaunchPromises[RemoteDecodeIn::UtilityProcess]; auto& utilityLaunchPromise = sLaunchPromises[aLocation];
if (utilityLaunchPromise) { if (utilityLaunchPromise) {
return utilityLaunchPromise; return utilityLaunchPromise;
@ -515,8 +526,9 @@ RemoteDecoderManagerChild::LaunchUtilityProcessIfNeeded() {
// IPC connections between *this* content process and the Utility process. // IPC connections between *this* content process and the Utility process.
RefPtr<GenericNonExclusivePromise> p = InvokeAsync( RefPtr<GenericNonExclusivePromise> p = InvokeAsync(
managerThread, __func__, []() -> RefPtr<GenericNonExclusivePromise> { managerThread, __func__,
auto* rps = GetSingleton(RemoteDecodeIn::UtilityProcess); [aLocation]() -> RefPtr<GenericNonExclusivePromise> {
auto* rps = GetSingleton(aLocation);
if (rps && rps->CanSend()) { if (rps && rps->CanSend()) {
return GenericNonExclusivePromise::CreateAndResolve(true, __func__); return GenericNonExclusivePromise::CreateAndResolve(true, __func__);
} }
@ -528,13 +540,14 @@ RemoteDecoderManagerChild::LaunchUtilityProcessIfNeeded() {
__func__); __func__);
} }
return bgActor->SendEnsureUtilityProcessAndCreateBridge()->Then( return bgActor->SendEnsureUtilityProcessAndCreateBridge(aLocation)
managerThread, __func__, ->Then(managerThread, __func__,
[](ipc::PBackgroundChild:: [aLocation](ipc::PBackgroundChild::
EnsureUtilityProcessAndCreateBridgePromise:: EnsureUtilityProcessAndCreateBridgePromise::
ResolveOrRejectValue&& aResult) ResolveOrRejectValue&& aResult)
-> RefPtr<GenericNonExclusivePromise> { -> RefPtr<GenericNonExclusivePromise> {
nsCOMPtr<nsISerialEventTarget> managerThread = GetManagerThread(); nsCOMPtr<nsISerialEventTarget> managerThread =
GetManagerThread();
if (!managerThread || aResult.IsReject()) { if (!managerThread || aResult.IsReject()) {
// The parent process died or we got shutdown // The parent process died or we got shutdown
return GenericNonExclusivePromise::CreateAndReject( return GenericNonExclusivePromise::CreateAndReject(
@ -542,22 +555,22 @@ RemoteDecoderManagerChild::LaunchUtilityProcessIfNeeded() {
} }
nsresult rv = Get<0>(aResult.ResolveValue()); nsresult rv = Get<0>(aResult.ResolveValue());
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return GenericNonExclusivePromise::CreateAndReject(rv, return GenericNonExclusivePromise::CreateAndReject(
__func__); rv, __func__);
} }
OpenRemoteDecoderManagerChildForProcess( OpenRemoteDecoderManagerChildForProcess(
Get<1>(std::move(aResult.ResolveValue())), Get<1>(std::move(aResult.ResolveValue())), aLocation);
RemoteDecodeIn::UtilityProcess); return GenericNonExclusivePromise::CreateAndResolve(
return GenericNonExclusivePromise::CreateAndResolve(true, true, __func__);
__func__);
}); });
}); });
p = p->Then( p = p->Then(
GetCurrentSerialEventTarget(), __func__, GetCurrentSerialEventTarget(), __func__,
[](const GenericNonExclusivePromise::ResolveOrRejectValue& aResult) { [aLocation](
const GenericNonExclusivePromise::ResolveOrRejectValue& aResult) {
StaticMutexAutoLock lock(sLaunchMutex); StaticMutexAutoLock lock(sLaunchMutex);
sLaunchPromises[RemoteDecodeIn::UtilityProcess] = nullptr; sLaunchPromises[aLocation] = nullptr;
return GenericNonExclusivePromise::CreateAndResolveOrReject(aResult, return GenericNonExclusivePromise::CreateAndResolveOrReject(aResult,
__func__); __func__);
}); });
@ -598,7 +611,9 @@ TrackSupportSet RemoteDecoderManagerChild::GetTrackSupport(
#endif #endif
return s; return s;
} }
case RemoteDecodeIn::UtilityProcess: case RemoteDecodeIn::UtilityProcess_Generic:
case RemoteDecodeIn::UtilityProcess_AppleMedia:
case RemoteDecodeIn::UtilityProcess_WMF:
return StaticPrefs::media_utility_process_enabled() return StaticPrefs::media_utility_process_enabled()
? TrackSupportSet{TrackSupport::Audio} ? TrackSupportSet{TrackSupport::Audio}
: TrackSupportSet{TrackSupport::None}; : TrackSupportSet{TrackSupport::None};
@ -647,7 +662,9 @@ RemoteDecoderManagerChild::RemoteDecoderManagerChild(RemoteDecodeIn aLocation)
: mLocation(aLocation) { : mLocation(aLocation) {
MOZ_ASSERT(mLocation == RemoteDecodeIn::GpuProcess || MOZ_ASSERT(mLocation == RemoteDecodeIn::GpuProcess ||
mLocation == RemoteDecodeIn::RddProcess || mLocation == RemoteDecodeIn::RddProcess ||
mLocation == RemoteDecodeIn::UtilityProcess); mLocation == RemoteDecodeIn::UtilityProcess_Generic ||
mLocation == RemoteDecodeIn::UtilityProcess_AppleMedia ||
mLocation == RemoteDecodeIn::UtilityProcess_WMF);
} }
/* static */ /* static */
@ -809,7 +826,9 @@ void RemoteDecoderManagerChild::SetSupported(
switch (aLocation) { switch (aLocation) {
case RemoteDecodeIn::GpuProcess: case RemoteDecodeIn::GpuProcess:
case RemoteDecodeIn::RddProcess: case RemoteDecodeIn::RddProcess:
case RemoteDecodeIn::UtilityProcess: { case RemoteDecodeIn::UtilityProcess_AppleMedia:
case RemoteDecodeIn::UtilityProcess_Generic:
case RemoteDecodeIn::UtilityProcess_WMF: {
StaticMutexAutoLock lock(sProcessSupportedMutex); StaticMutexAutoLock lock(sProcessSupportedMutex);
sProcessSupported[aLocation] = Some(aSupported); sProcessSupported[aLocation] = Some(aSupported);
break; break;

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

@ -12,6 +12,7 @@
#include "mozilla/EnumTypeTraits.h" #include "mozilla/EnumTypeTraits.h"
#include "mozilla/PRemoteDecoderManagerChild.h" #include "mozilla/PRemoteDecoderManagerChild.h"
#include "mozilla/layers/VideoBridgeUtils.h" #include "mozilla/layers/VideoBridgeUtils.h"
#include "mozilla/ipc/UtilityProcessSandboxing.h"
namespace mozilla { namespace mozilla {
@ -22,7 +23,9 @@ enum class RemoteDecodeIn {
Unspecified, Unspecified,
RddProcess, RddProcess,
GpuProcess, GpuProcess,
UtilityProcess, UtilityProcess_Generic,
UtilityProcess_AppleMedia,
UtilityProcess_WMF,
SENTINEL, SENTINEL,
}; };
@ -127,7 +130,8 @@ class RemoteDecoderManagerChild final
static void OpenRemoteDecoderManagerChildForProcess( static void OpenRemoteDecoderManagerChildForProcess(
Endpoint<PRemoteDecoderManagerChild>&& aEndpoint, Endpoint<PRemoteDecoderManagerChild>&& aEndpoint,
RemoteDecodeIn aLocation); RemoteDecodeIn aLocation);
static RefPtr<GenericNonExclusivePromise> LaunchUtilityProcessIfNeeded(); static RefPtr<GenericNonExclusivePromise> LaunchUtilityProcessIfNeeded(
RemoteDecodeIn aLocation);
RefPtr<RemoteDecoderManagerChild> mIPDLSelfRef; RefPtr<RemoteDecoderManagerChild> mIPDLSelfRef;
// The location for decoding, Rdd or Gpu process. // The location for decoding, Rdd or Gpu process.

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

@ -26,6 +26,7 @@ EXPORTS.mozilla += [
"RemoteDecoderManagerParent.h", "RemoteDecoderManagerParent.h",
"RemoteDecoderModule.h", "RemoteDecoderModule.h",
"RemoteDecoderParent.h", "RemoteDecoderParent.h",
"RemoteDecodeUtils.h",
"RemoteImageHolder.h", "RemoteImageHolder.h",
"RemoteMediaData.h", "RemoteMediaData.h",
"RemoteMediaDataDecoder.h", "RemoteMediaDataDecoder.h",
@ -48,6 +49,7 @@ SOURCES += [
"RemoteDecoderManagerParent.cpp", "RemoteDecoderManagerParent.cpp",
"RemoteDecoderModule.cpp", "RemoteDecoderModule.cpp",
"RemoteDecoderParent.cpp", "RemoteDecoderParent.cpp",
"RemoteDecodeUtils.cpp",
"RemoteImageHolder.cpp", "RemoteImageHolder.cpp",
"RemoteMediaData.cpp", "RemoteMediaData.cpp",
"RemoteMediaDataDecoder.cpp", "RemoteMediaDataDecoder.cpp",

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

@ -36,6 +36,8 @@
#include "nsIXULRuntime.h" // for BrowserTabsRemoteAutostart #include "nsIXULRuntime.h" // for BrowserTabsRemoteAutostart
#include "nsPrintfCString.h" #include "nsPrintfCString.h"
#include "mozilla/ipc/UtilityAudioDecoderParent.h"
#ifdef XP_WIN #ifdef XP_WIN
# include "WMFDecoderModule.h" # include "WMFDecoderModule.h"
# include "mozilla/WindowsVersion.h" # include "mozilla/WindowsVersion.h"
@ -562,17 +564,22 @@ void PDMFactory::CreateRddPDMs() {
} }
void PDMFactory::CreateUtilityPDMs() { void PDMFactory::CreateUtilityPDMs() {
const ipc::SandboxingKind aKind =
ipc::UtilityAudioDecoderParent::GetSandboxingKind();
#ifdef XP_WIN #ifdef XP_WIN
if (StaticPrefs::media_wmf_enabled() && if (StaticPrefs::media_wmf_enabled() &&
StaticPrefs::media_utility_wmf_enabled()) { StaticPrefs::media_utility_wmf_enabled() &&
aKind == ipc::SandboxingKind::UTILITY_AUDIO_DECODING_WMF) {
CreateAndStartupPDM<WMFDecoderModule>(); CreateAndStartupPDM<WMFDecoderModule>();
} }
#endif #endif
#ifdef MOZ_APPLEMEDIA #ifdef MOZ_APPLEMEDIA
if (StaticPrefs::media_utility_applemedia_enabled()) { if (StaticPrefs::media_utility_applemedia_enabled() &&
aKind == ipc::SandboxingKind::UTILITY_AUDIO_DECODING_APPLE_MEDIA) {
CreateAndStartupPDM<AppleDecoderModule>(); CreateAndStartupPDM<AppleDecoderModule>();
} }
#endif #endif
if (aKind == ipc::SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC) {
#ifdef MOZ_FFVPX #ifdef MOZ_FFVPX
if (StaticPrefs::media_ffvpx_enabled() && if (StaticPrefs::media_ffvpx_enabled() &&
StaticPrefs::media_utility_ffvpx_enabled()) { StaticPrefs::media_utility_ffvpx_enabled()) {
@ -595,6 +602,7 @@ void PDMFactory::CreateUtilityPDMs() {
#endif #endif
CreateAndStartupPDM<AgnosticDecoderModule>(); CreateAndStartupPDM<AgnosticDecoderModule>();
} }
}
void PDMFactory::CreateContentPDMs() { void PDMFactory::CreateContentPDMs() {
if (StaticPrefs::media_gpu_process_decoder()) { if (StaticPrefs::media_gpu_process_decoder()) {
@ -606,7 +614,18 @@ void PDMFactory::CreateContentPDMs() {
} }
if (StaticPrefs::media_utility_process_enabled()) { if (StaticPrefs::media_utility_process_enabled()) {
CreateAndStartupPDM<RemoteDecoderModule>(RemoteDecodeIn::UtilityProcess); #ifdef MOZ_APPLEMEDIA
CreateAndStartupPDM<RemoteDecoderModule>(
RemoteDecodeIn::UtilityProcess_AppleMedia);
#endif
#ifdef XP_WIN
CreateAndStartupPDM<RemoteDecoderModule>(
RemoteDecodeIn::UtilityProcess_WMF);
#endif
// WMF and AppleMedia should be created before Generic because the order
// affects what decoder module would be chose first.
CreateAndStartupPDM<RemoteDecoderModule>(
RemoteDecodeIn::UtilityProcess_Generic);
} }
#ifdef XP_WIN #ifdef XP_WIN

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

@ -14,6 +14,7 @@
# include "mozilla/EnumSet.h" # include "mozilla/EnumSet.h"
# include "mozilla/MozPromise.h" # include "mozilla/MozPromise.h"
# include "mozilla/RefPtr.h" # include "mozilla/RefPtr.h"
# include "mozilla/ipc/UtilityProcessSandboxing.h"
# include "nsISupports.h" # include "nsISupports.h"
# include "nsStringFwd.h" # include "nsStringFwd.h"
# include "nsTArray.h" # include "nsTArray.h"

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

@ -13,6 +13,7 @@
#include "mozilla/Assertions.h" #include "mozilla/Assertions.h"
#include "mozilla/RDDProcessManager.h" #include "mozilla/RDDProcessManager.h"
#include "mozilla/ipc/UtilityProcessManager.h" #include "mozilla/ipc/UtilityProcessManager.h"
#include "mozilla/RemoteDecodeUtils.h"
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "mozilla/dom/BackgroundSessionStorageServiceParent.h" #include "mozilla/dom/BackgroundSessionStorageServiceParent.h"
#include "mozilla/dom/ClientManagerActors.h" #include "mozilla/dom/ClientManagerActors.h"
@ -1372,6 +1373,7 @@ BackgroundParentImpl::RecvEnsureRDDProcessAndCreateBridge(
mozilla::ipc::IPCResult mozilla::ipc::IPCResult
BackgroundParentImpl::RecvEnsureUtilityProcessAndCreateBridge( BackgroundParentImpl::RecvEnsureUtilityProcessAndCreateBridge(
const RemoteDecodeIn& aLocation,
EnsureUtilityProcessAndCreateBridgeResolver&& aResolver) { EnsureUtilityProcessAndCreateBridgeResolver&& aResolver) {
base::ProcessId otherPid = OtherPid(); base::ProcessId otherPid = OtherPid();
nsCOMPtr<nsISerialEventTarget> managerThread = GetCurrentSerialEventTarget(); nsCOMPtr<nsISerialEventTarget> managerThread = GetCurrentSerialEventTarget();
@ -1380,7 +1382,7 @@ BackgroundParentImpl::RecvEnsureUtilityProcessAndCreateBridge(
} }
NS_DispatchToMainThread(NS_NewRunnableFunction( NS_DispatchToMainThread(NS_NewRunnableFunction(
"BackgroundParentImpl::RecvEnsureUtilityProcessAndCreateBridge()", "BackgroundParentImpl::RecvEnsureUtilityProcessAndCreateBridge()",
[aResolver, managerThread, otherPid]() { [aResolver, managerThread, otherPid, aLocation]() {
RefPtr<UtilityProcessManager> upm = RefPtr<UtilityProcessManager> upm =
UtilityProcessManager::GetSingleton(); UtilityProcessManager::GetSingleton();
using Type = Tuple<const nsresult&, using Type = Tuple<const nsresult&,
@ -1389,11 +1391,13 @@ BackgroundParentImpl::RecvEnsureUtilityProcessAndCreateBridge(
aResolver(Type(NS_ERROR_NOT_AVAILABLE, aResolver(Type(NS_ERROR_NOT_AVAILABLE,
Endpoint<PRemoteDecoderManagerChild>())); Endpoint<PRemoteDecoderManagerChild>()));
} else { } else {
upm->StartAudioDecoding(otherPid)->Then( SandboxingKind sbKind = GetSandboxingKindFromLocation(aLocation);
managerThread, __func__, upm->StartAudioDecoding(otherPid, sbKind)
[resolver = std::move(aResolver)]( ->Then(managerThread, __func__,
mozilla::ipc::UtilityProcessManager::AudioDecodingPromise:: [resolver = aResolver](
ResolveOrRejectValue&& aValue) mutable { mozilla::ipc::UtilityProcessManager::
AudioDecodingPromise::ResolveOrRejectValue&&
aValue) mutable {
if (aValue.IsReject()) { if (aValue.IsReject()) {
resolver(Type(aValue.RejectValue(), resolver(Type(aValue.RejectValue(),
Endpoint<PRemoteDecoderManagerChild>())); Endpoint<PRemoteDecoderManagerChild>()));

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

@ -386,6 +386,7 @@ class BackgroundParentImpl : public PBackgroundParent {
EnsureRDDProcessAndCreateBridgeResolver&& aResolver) override; EnsureRDDProcessAndCreateBridgeResolver&& aResolver) override;
mozilla::ipc::IPCResult RecvEnsureUtilityProcessAndCreateBridge( mozilla::ipc::IPCResult RecvEnsureUtilityProcessAndCreateBridge(
const RemoteDecodeIn& aLocation,
EnsureUtilityProcessAndCreateBridgeResolver&& aResolver) override; EnsureUtilityProcessAndCreateBridgeResolver&& aResolver) override;
bool DeallocPEndpointForReportParent( bool DeallocPEndpointForReportParent(

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

@ -76,6 +76,8 @@ using mozilla::dom::cache::Namespace
using class mozilla::dom::SSCacheCopy from "mozilla/dom/PBackgroundSessionStorageCache.h"; using class mozilla::dom::SSCacheCopy from "mozilla/dom/PBackgroundSessionStorageCache.h";
using mozilla::RemoteDecodeIn from "mozilla/RemoteDecoderManagerChild.h";
namespace mozilla { namespace mozilla {
namespace ipc { namespace ipc {
@ -297,7 +299,7 @@ parent:
async EnsureRDDProcessAndCreateBridge() async EnsureRDDProcessAndCreateBridge()
returns (nsresult rv, Endpoint<PRemoteDecoderManagerChild> aEndpoint); returns (nsresult rv, Endpoint<PRemoteDecoderManagerChild> aEndpoint);
async EnsureUtilityProcessAndCreateBridge() async EnsureUtilityProcessAndCreateBridge(RemoteDecodeIn aLocation)
returns (nsresult rv, Endpoint<PRemoteDecoderManagerChild> aEndpoint); returns (nsresult rv, Endpoint<PRemoteDecoderManagerChild> aEndpoint);
async PWebSocketConnection(uint32_t aListenerId); async PWebSocketConnection(uint32_t aListenerId);

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

@ -6,6 +6,7 @@
include protocol PRemoteDecoderManager; include protocol PRemoteDecoderManager;
using mozilla::media::MediaCodecsSupported from "MediaCodecsSupport.h"; using mozilla::media::MediaCodecsSupported from "MediaCodecsSupport.h";
using mozilla::RemoteDecodeIn from "mozilla/RemoteDecoderManagerChild.h";
namespace mozilla { namespace mozilla {
@ -20,7 +21,7 @@ parent:
Endpoint<PRemoteDecoderManagerParent> endpoint); Endpoint<PRemoteDecoderManagerParent> endpoint);
child: child:
async UpdateMediaCodecsSupported(MediaCodecsSupported aSupported); async UpdateMediaCodecsSupported(RemoteDecodeIn aLocation, MediaCodecsSupported aSupported);
}; };

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

@ -6,20 +6,24 @@
#include "UtilityAudioDecoderChild.h" #include "UtilityAudioDecoderChild.h"
#include "base/basictypes.h"
#include "mozilla/AppShutdown.h" #include "mozilla/AppShutdown.h"
#include "mozilla/dom/ContentParent.h" #include "mozilla/dom/ContentParent.h"
namespace mozilla::ipc { namespace mozilla::ipc {
static StaticRefPtr<UtilityAudioDecoderChild> sAudioDecoderChild; static EnumeratedArray<SandboxingKind, SandboxingKind::COUNT,
StaticRefPtr<UtilityAudioDecoderChild>>
sAudioDecoderChilds;
UtilityAudioDecoderChild::UtilityAudioDecoderChild() { UtilityAudioDecoderChild::UtilityAudioDecoderChild(SandboxingKind aKind)
: mSandbox(aKind) {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
} }
void UtilityAudioDecoderChild::ActorDestroy(ActorDestroyReason aReason) { void UtilityAudioDecoderChild::ActorDestroy(ActorDestroyReason aReason) {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
sAudioDecoderChild = nullptr; sAudioDecoderChilds[mSandbox] = nullptr;
} }
void UtilityAudioDecoderChild::Bind( void UtilityAudioDecoderChild::Bind(
@ -29,20 +33,22 @@ void UtilityAudioDecoderChild::Bind(
} }
/* static */ /* static */
RefPtr<UtilityAudioDecoderChild> UtilityAudioDecoderChild::GetSingleton() { RefPtr<UtilityAudioDecoderChild> UtilityAudioDecoderChild::GetSingleton(
SandboxingKind aKind) {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
bool shutdown = AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMWillShutdown); bool shutdown = AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMWillShutdown);
if (!sAudioDecoderChild && !shutdown) { if (!sAudioDecoderChilds[aKind] && !shutdown) {
sAudioDecoderChild = new UtilityAudioDecoderChild(); sAudioDecoderChilds[aKind] = new UtilityAudioDecoderChild(aKind);
} }
return sAudioDecoderChild; return sAudioDecoderChilds[aKind];
} }
mozilla::ipc::IPCResult mozilla::ipc::IPCResult
UtilityAudioDecoderChild::RecvUpdateMediaCodecsSupported( UtilityAudioDecoderChild::RecvUpdateMediaCodecsSupported(
const RemoteDecodeIn& aLocation,
const media::MediaCodecsSupported& aSupported) { const media::MediaCodecsSupported& aSupported) {
dom::ContentParent::BroadcastMediaCodecsSupportedUpdate( dom::ContentParent::BroadcastMediaCodecsSupportedUpdate(aLocation,
RemoteDecodeIn::UtilityProcess, aSupported); aSupported);
return IPC_OK(); return IPC_OK();
} }

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

@ -11,6 +11,7 @@
#include "mozilla/ipc/Endpoint.h" #include "mozilla/ipc/Endpoint.h"
#include "mozilla/ipc/UtilityProcessParent.h" #include "mozilla/ipc/UtilityProcessParent.h"
#include "mozilla/ipc/UtilityProcessSandboxing.h"
#include "mozilla/ipc/PUtilityAudioDecoderChild.h" #include "mozilla/ipc/PUtilityAudioDecoderChild.h"
#include "PDMFactory.h" #include "PDMFactory.h"
@ -24,9 +25,25 @@ class UtilityAudioDecoderChild final : public PUtilityAudioDecoderChild {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UtilityAudioDecoderChild, override); NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UtilityAudioDecoderChild, override);
mozilla::ipc::IPCResult RecvUpdateMediaCodecsSupported( mozilla::ipc::IPCResult RecvUpdateMediaCodecsSupported(
const RemoteDecodeIn& aLocation,
const media::MediaCodecsSupported& aSupported); const media::MediaCodecsSupported& aSupported);
UtilityActorName GetActorName() { return UtilityActorName::AudioDecoder; } UtilityActorName GetActorName() {
switch (mSandbox) {
case UTILITY_AUDIO_DECODING_GENERIC:
return UtilityActorName::AudioDecoder_Generic;
#ifdef MOZ_APPLEMEDIA
case UTILITY_AUDIO_DECODING_APPLE_MEDIA:
return UtilityActorName::AudioDecoder_AppleMedia;
#endif
#ifdef XP_WIN
case UTILITY_AUDIO_DECODING_WMF:
return UtilityActorName::AudioDecoder_WMF;
#endif
default:
MOZ_CRASH("Unexpected mSandbox for GetActorName()");
}
}
nsresult BindToUtilityProcess(RefPtr<UtilityProcessParent> aUtilityParent) { nsresult BindToUtilityProcess(RefPtr<UtilityProcessParent> aUtilityParent) {
Endpoint<PUtilityAudioDecoderChild> utilityAudioDecoderChildEnd; Endpoint<PUtilityAudioDecoderChild> utilityAudioDecoderChildEnd;
@ -54,11 +71,13 @@ class UtilityAudioDecoderChild final : public PUtilityAudioDecoderChild {
void Bind(Endpoint<PUtilityAudioDecoderChild>&& aEndpoint); void Bind(Endpoint<PUtilityAudioDecoderChild>&& aEndpoint);
static RefPtr<UtilityAudioDecoderChild> GetSingleton(); static RefPtr<UtilityAudioDecoderChild> GetSingleton(SandboxingKind aKind);
private: private:
UtilityAudioDecoderChild(); explicit UtilityAudioDecoderChild(SandboxingKind aKind);
~UtilityAudioDecoderChild() = default; ~UtilityAudioDecoderChild() = default;
const SandboxingKind mSandbox;
}; };
} // namespace mozilla::ipc } // namespace mozilla::ipc

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

@ -25,6 +25,9 @@
# include "AndroidDecoderModule.h" # include "AndroidDecoderModule.h"
#endif #endif
#include "mozilla/ipc/UtilityProcessChild.h"
#include "mozilla/RemoteDecodeUtils.h"
namespace mozilla::ipc { namespace mozilla::ipc {
UtilityAudioDecoderParent::UtilityAudioDecoderParent() { UtilityAudioDecoderParent::UtilityAudioDecoderParent() {
@ -33,14 +36,18 @@ UtilityAudioDecoderParent::UtilityAudioDecoderParent() {
} }
/* static */ /* static */
void UtilityAudioDecoderParent::PreloadForSandbox() { void UtilityAudioDecoderParent::GenericPreloadForSandbox() {
#if defined(MOZ_SANDBOX) && defined(OS_WIN) #if defined(MOZ_SANDBOX) && defined(OS_WIN)
// Preload AV dlls so we can enable Binary Signature Policy // Preload AV dlls so we can enable Binary Signature Policy
// to restrict further dll loads. // to restrict further dll loads.
::LoadLibraryW(L"mozavcodec.dll"); ::LoadLibraryW(L"mozavcodec.dll");
::LoadLibraryW(L"mozavutil.dll"); ::LoadLibraryW(L"mozavutil.dll");
#endif // defined(MOZ_SANDBOX) && defined(OS_WIN)
}
// WMF /* static */
void UtilityAudioDecoderParent::WMFPreloadForSandbox() {
#if defined(MOZ_SANDBOX) && defined(OS_WIN)
::LoadLibraryW(L"mfplat.dll"); ::LoadLibraryW(L"mfplat.dll");
::LoadLibraryW(L"mf.dll"); ::LoadLibraryW(L"mf.dll");
@ -56,6 +63,15 @@ void UtilityAudioDecoderParent::PreloadForSandbox() {
#endif // defined(MOZ_SANDBOX) && defined(OS_WIN) #endif // defined(MOZ_SANDBOX) && defined(OS_WIN)
} }
/* static */
SandboxingKind UtilityAudioDecoderParent::GetSandboxingKind() {
RefPtr<UtilityProcessChild> me = UtilityProcessChild::GetSingleton();
if (!me) {
MOZ_CRASH("I cant find myself");
}
return me->mSandbox;
}
void UtilityAudioDecoderParent::Start( void UtilityAudioDecoderParent::Start(
Endpoint<PUtilityAudioDecoderParent>&& aEndpoint) { Endpoint<PUtilityAudioDecoderParent>&& aEndpoint) {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
@ -71,7 +87,8 @@ void UtilityAudioDecoderParent::Start(
#endif #endif
auto supported = PDMFactory::Supported(); auto supported = PDMFactory::Supported();
Unused << SendUpdateMediaCodecsSupported(std::move(supported)); Unused << SendUpdateMediaCodecsSupported(
GetRemoteDecodeInFromKind(GetSandboxingKind()), supported);
} }
mozilla::ipc::IPCResult mozilla::ipc::IPCResult

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

@ -12,6 +12,8 @@
#include "mozilla/ipc/Endpoint.h" #include "mozilla/ipc/Endpoint.h"
#include "mozilla/ipc/PUtilityAudioDecoderParent.h" #include "mozilla/ipc/PUtilityAudioDecoderParent.h"
#include "mozilla/ipc/UtilityProcessSandboxing.h"
#include "nsThreadManager.h" #include "nsThreadManager.h"
namespace mozilla::ipc { namespace mozilla::ipc {
@ -24,13 +26,16 @@ class UtilityAudioDecoderParent final : public PUtilityAudioDecoderParent {
UtilityAudioDecoderParent(); UtilityAudioDecoderParent();
static void PreloadForSandbox(); static void GenericPreloadForSandbox();
static void WMFPreloadForSandbox();
void Start(Endpoint<PUtilityAudioDecoderParent>&& aEndpoint); void Start(Endpoint<PUtilityAudioDecoderParent>&& aEndpoint);
mozilla::ipc::IPCResult RecvNewContentRemoteDecoderManager( mozilla::ipc::IPCResult RecvNewContentRemoteDecoderManager(
Endpoint<PRemoteDecoderManagerParent>&& aEndpoint); Endpoint<PRemoteDecoderManagerParent>&& aEndpoint);
static SandboxingKind GetSandboxingKind();
private: private:
~UtilityAudioDecoderParent() = default; ~UtilityAudioDecoderParent() = default;
}; };

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

@ -197,7 +197,7 @@ void UtilityProcessHost::InitAfterConnect(bool aSucceeded) {
UniquePtr<SandboxBroker::Policy> policy; UniquePtr<SandboxBroker::Policy> policy;
switch (mSandbox) { switch (mSandbox) {
case SandboxingKind::GENERIC_UTILITY: case SandboxingKind::GENERIC_UTILITY:
case SandboxingKind::UTILITY_AUDIO_DECODING: // TODO: NEW POLICY? case SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC:
policy = SandboxBrokerPolicyFactory::GetUtilityProcessPolicy( policy = SandboxBrokerPolicyFactory::GetUtilityProcessPolicy(
GetActor()->OtherPid()); GetActor()->OtherPid());
break; break;

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

@ -38,8 +38,12 @@ bool UtilityProcessImpl::Init(int aArgc, char* aArgv[]) {
// lower the sandbox in processes where the policy will prevent loading. // lower the sandbox in processes where the policy will prevent loading.
::LoadLibraryW(L"winmm.dll"); ::LoadLibraryW(L"winmm.dll");
if (*sandboxingKind == SandboxingKind::UTILITY_AUDIO_DECODING) { if (*sandboxingKind == SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC) {
UtilityAudioDecoderParent::PreloadForSandbox(); UtilityAudioDecoderParent::GenericPreloadForSandbox();
}
if (*sandboxingKind == SandboxingKind::UTILITY_AUDIO_DECODING_WMF) {
UtilityAudioDecoderParent::WMFPreloadForSandbox();
} }
// Go for it // Go for it

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

@ -263,18 +263,18 @@ RefPtr<GenericNonExclusivePromise> UtilityProcessManager::StartUtility(
} }
RefPtr<UtilityProcessManager::AudioDecodingPromise> RefPtr<UtilityProcessManager::AudioDecodingPromise>
UtilityProcessManager::StartAudioDecoding(base::ProcessId aOtherProcess) { UtilityProcessManager::StartAudioDecoding(base::ProcessId aOtherProcess,
SandboxingKind aSandbox) {
RefPtr<UtilityProcessManager> self = this; RefPtr<UtilityProcessManager> self = this;
RefPtr<UtilityAudioDecoderChild> uadc = RefPtr<UtilityAudioDecoderChild> uadc =
UtilityAudioDecoderChild::GetSingleton(); UtilityAudioDecoderChild::GetSingleton(aSandbox);
MOZ_ASSERT(uadc, "Unable to get a singleton for UtilityAudioDecoderChild"); MOZ_ASSERT(uadc, "Unable to get a singleton for UtilityAudioDecoderChild");
return StartUtility(uadc, SandboxingKind::UTILITY_AUDIO_DECODING) return StartUtility(uadc, aSandbox)
->Then( ->Then(
GetMainThreadSerialEventTarget(), __func__, GetMainThreadSerialEventTarget(), __func__,
[self, uadc, aOtherProcess]() { [self, uadc, aOtherProcess, aSandbox]() {
base::ProcessId process = base::ProcessId process =
self->GetProcessParent(SandboxingKind::UTILITY_AUDIO_DECODING) self->GetProcessParent(aSandbox)->OtherPid();
->OtherPid();
if (!uadc->CanSend()) { if (!uadc->CanSend()) {
MOZ_ASSERT(false, "UtilityAudioDecoderChild lost in the middle"); MOZ_ASSERT(false, "UtilityAudioDecoderChild lost in the middle");

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

@ -46,8 +46,8 @@ class UtilityProcessManager final : public UtilityProcessHost::Listener {
RefPtr<GenericNonExclusivePromise> StartUtility(RefPtr<Actor> aActor, RefPtr<GenericNonExclusivePromise> StartUtility(RefPtr<Actor> aActor,
SandboxingKind aSandbox); SandboxingKind aSandbox);
RefPtr<AudioDecodingPromise> StartAudioDecoding( RefPtr<AudioDecodingPromise> StartAudioDecoding(base::ProcessId aOtherProcess,
base::ProcessId aOtherProcess); SandboxingKind aSandbox);
void OnProcessUnexpectedShutdown(UtilityProcessHost* aHost); void OnProcessUnexpectedShutdown(UtilityProcessHost* aHost);

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

@ -16,9 +16,15 @@ namespace ipc {
// to be updated as well. // to be updated as well.
enum SandboxingKind : uint64_t { enum SandboxingKind : uint64_t {
GENERIC_UTILITY, GENERIC_UTILITY = 0,
UTILITY_AUDIO_DECODING, UTILITY_AUDIO_DECODING_GENERIC = 1,
#ifdef MOZ_APPLEMEDIA
UTILITY_AUDIO_DECODING_APPLE_MEDIA = 2,
#endif
#ifdef XP_WIN
UTILITY_AUDIO_DECODING_WMF = 3,
#endif
COUNT, COUNT,

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

@ -3,22 +3,25 @@
"use strict"; "use strict";
async function getAudioDecoderPid() { async function getAudioDecoderPid(expectation) {
info("Finding a running AudioDecoder"); info("Finding a running AudioDecoder");
const actor = expectation.replace("Utility ", "");
let audioDecoderProcess = (await ChromeUtils.requestProcInfo()).children.find( let audioDecoderProcess = (await ChromeUtils.requestProcInfo()).children.find(
p => p =>
p.type === "utility" && p.type === "utility" &&
p.utilityActors.find(a => a.actorName === "audioDecoder") p.utilityActors.find(a => a.actorName === `audioDecoder_${actor}`)
); );
ok( ok(
audioDecoderProcess, audioDecoderProcess,
`Found the AudioDecoder process at ${audioDecoderProcess.pid}` `Found the AudioDecoder ${actor} process at ${audioDecoderProcess.pid}`
); );
return audioDecoderProcess.pid; return audioDecoderProcess.pid;
} }
async function crashDecoder() { async function crashDecoder(expectation) {
const audioPid = await getAudioDecoderPid(); const audioPid = await getAudioDecoderPid(expectation);
ok(audioPid > 0, `Found an audio decoder ${audioPid}`); ok(audioPid > 0, `Found an audio decoder ${audioPid}`);
const ProcessTools = Cc["@mozilla.org/processtools-service;1"].getService( const ProcessTools = Cc["@mozilla.org/processtools-service;1"].getService(
@ -27,15 +30,15 @@ async function crashDecoder() {
ProcessTools.kill(audioPid); ProcessTools.kill(audioPid);
} }
async function runTest(src, withClose) { async function runTest(src, withClose, expectation) {
info(`Add media tabs: ${src}`); info(`Add media tabs: ${src}`);
let tab = await addMediaTab(src); let tab = await addMediaTab(src);
info("Play tab"); info("Play tab");
await play(tab, true /* expectUtility */); await play(tab, expectation);
info("Crash decoder"); info("Crash decoder");
await crashDecoder(); await crashDecoder(expectation);
if (withClose) { if (withClose) {
info("Stop tab"); info("Stop tab");
@ -49,7 +52,7 @@ async function runTest(src, withClose) {
} }
info("Play tab again"); info("Play tab again");
await play(tab, true); await play(tab, expectation);
info("Stop tab"); info("Stop tab");
await stop(tab); await stop(tab);
@ -69,13 +72,15 @@ async function testAudioCrash(withClose) {
SimpleTest.expectChildProcessCrash(); SimpleTest.expectChildProcessCrash();
for (let src of [ const platform = Services.appinfo.OS;
"small-shot.ogg",
"small-shot.mp3", for (let { src, expectations } of audioTestData()) {
"small-shot.m4a", if (!(platform in expectations)) {
"small-shot.flac", info(`Skipping ${src} for ${platform}`);
]) { continue;
await runTest(src, withClose); }
await runTest(src, withClose, expectations[platform]);
} }
} }

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

@ -16,19 +16,21 @@ async function runTest(expectUtility) {
}); });
} }
for (let src of [ const platform = Services.appinfo.OS;
"small-shot.ogg",
"small-shot.mp3", for (let { src, expectations } of audioTestData()) {
"small-shot.m4a", if (!(platform in expectations)) {
"small-shot.flac", info(`Skipping ${src} for ${platform}`);
]) { continue;
}
info(`Add media tabs: ${src}`); info(`Add media tabs: ${src}`);
let tabs = [await addMediaTab(src), await addMediaTab(src)]; let tabs = [await addMediaTab(src), await addMediaTab(src)];
let playback = []; let playback = [];
info("Play tabs"); info("Play tabs");
for (let tab of tabs) { for (let tab of tabs) {
playback.push(play(tab, expectUtility)); playback.push(play(tab, expectUtility ? expectations[platform] : "RDD"));
} }
info("Wait all playback"); info("Wait all playback");

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

@ -40,6 +40,49 @@ async function cleanUtilityProcessShutdown(utilityPid) {
ok(!subject.hasKey("dumpID"), "There should be no dumpID"); ok(!subject.hasKey("dumpID"), "There should be no dumpID");
} }
function audioTestData() {
return [
{
src: "small-shot.ogg",
expectations: {
Android: "Utility Generic",
Linux: "Utility Generic",
WINNT: "Utility Generic",
Darwin: "Utility Generic",
},
},
{
src: "small-shot.mp3",
expectations: {
Android: "Utility Generic",
Linux: "Utility Generic",
WINNT: SpecialPowers.getBoolPref("media.ffvpx.mp3.enabled")
? "Utility Generic"
: "Utility WMF",
Darwin: "Utility Generic",
},
},
{
src: "small-shot.m4a",
expectations: {
// Add Android after Bug 1771196
Linux: "Utility Generic",
WINNT: "Utility WMF",
Darwin: "Utility AppleMedia",
},
},
{
src: "small-shot.flac",
expectations: {
Android: "Utility Generic",
Linux: "Utility Generic",
WINNT: "Utility Generic",
Darwin: "Utility Generic",
},
},
];
}
async function addMediaTab(src) { async function addMediaTab(src) {
const tab = BrowserTestUtils.addTab(gBrowser, "about:blank", { const tab = BrowserTestUtils.addTab(gBrowser, "about:blank", {
forceNewProcess: true, forceNewProcess: true,
@ -50,11 +93,16 @@ async function addMediaTab(src) {
return tab; return tab;
} }
async function play(tab, expectUtility, expectContent = false) { async function play(
tab,
expectUtility,
expectContent = false,
expectJava = false
) {
let browser = tab.linkedBrowser; let browser = tab.linkedBrowser;
return SpecialPowers.spawn( return SpecialPowers.spawn(
browser, browser,
[expectUtility, expectContent], [expectUtility, expectContent, expectJava],
checkAudioDecoder checkAudioDecoder
); );
} }
@ -77,25 +125,28 @@ async function createAudioElement(src) {
doc.body.appendChild(audio); doc.body.appendChild(audio);
} }
async function checkAudioDecoder(expectUtility, expectContent = false) { async function checkAudioDecoder(
expectedProcess,
expectContent = false,
expectJava = false
) {
const doc = typeof content !== "undefined" ? content.document : document; const doc = typeof content !== "undefined" ? content.document : document;
let audio = doc.querySelector("audio"); let audio = doc.querySelector("audio");
const checkPromise = new Promise((resolve, reject) => { const checkPromise = new Promise((resolve, reject) => {
const timeUpdateHandler = async ev => { const timeUpdateHandler = async ev => {
const debugInfo = await SpecialPowers.wrap(audio).mozRequestDebugInfo(); const debugInfo = await SpecialPowers.wrap(audio).mozRequestDebugInfo();
const audioDecoderName = debugInfo.decoder.reader.audioDecoderName; const audioDecoderName = debugInfo.decoder.reader.audioDecoderName;
const isUtility = audioDecoderName.indexOf("(Utility remote)") > 0; const isExpected =
const isRDD = audioDecoderName.indexOf("(RDD remote)") > 0; audioDecoderName.indexOf(`(${expectedProcess} remote)`) > 0;
const isJavaRemote = audioDecoderName.indexOf("(remote)") > 0; const isJavaRemote = audioDecoderName.indexOf("(remote)") > 0;
const isContent = !isUtility && !isRDD;
const isOk = const isOk =
(expectUtility === true && isUtility && !isJavaRemote) || (isExpected && !isJavaRemote && !expectContent && !expectJava) || // Running in Utility/RDD
(expectUtility === false && isRDD && !isJavaRemote) || (expectJava && !isExpected && isJavaRemote) || // Running in Java remote
(expectContent === true && isContent); (expectContent && !isExpected && !isJavaRemote); // Running in Content
ok( ok(
isOk, isOk,
`playback ${audio.src} was from expected decoder ${audioDecoderName}` `playback ${audio.src} was from decoder '${audioDecoderName}', expected '${expectedProcess}'`
); );
if (isOk) { if (isOk) {
@ -120,7 +171,7 @@ async function checkAudioDecoder(expectUtility, expectContent = false) {
async function runMochitestUtilityAudio( async function runMochitestUtilityAudio(
src, src,
{ expectUtility, expectContent = false } = {} { expectUtility, expectContent = false, expectJava = false } = {}
) { ) {
info(`Add media: ${src}`); info(`Add media: ${src}`);
await createAudioElement(src); await createAudioElement(src);
@ -128,7 +179,7 @@ async function runMochitestUtilityAudio(
ok(audio, "Found an audio element created"); ok(audio, "Found an audio element created");
info(`Play media: ${src}`); info(`Play media: ${src}`);
await checkAudioDecoder(expectUtility, expectContent); await checkAudioDecoder(expectUtility, expectContent, expectJava);
info(`Pause media: ${src}`); info(`Pause media: ${src}`);
await audio.pause(); await audio.pause();

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

@ -12,14 +12,25 @@
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
(async function() { (async function() {
const platform = SpecialPowers.Services.appinfo.OS;
for (let {src, expectations} of audioTestData()) {
if (!(platform in expectations)) {
info(`Skipping ${src} for ${platform}`);
continue;
}
try {
await runMochitestUtilityAudio(src, { expectUtility: "", expectContent: true, expectJava: false });
} catch (ex) {
ok(false, "Failure");
}
}
for (let src of [ for (let src of [
"small-shot.ogg",
"small-shot.mp3",
"small-shot.m4a", "small-shot.m4a",
"small-shot.flac",
]) { ]) {
try { try {
await runMochitestUtilityAudio(src, { expectUtility: false, expectContent: true }); await runMochitestUtilityAudio(src, { expectUtility: "", expectContent: false, expectJava: true });
} catch (ex) { } catch (ex) {
ok(false, "Failure"); ok(false, "Failure");
} }

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

@ -12,13 +12,15 @@
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
(async function() { (async function() {
for (let src of [ const platform = SpecialPowers.Services.appinfo.OS;
"small-shot.ogg", for (let {src, expectations} of audioTestData()) {
"small-shot.mp3", if (!(platform in expectations)) {
"small-shot.flac" info(`Skipping ${src} for ${platform}`);
]) { continue;
}
try { try {
await runMochitestUtilityAudio(src, { expectUtility: true, expectContent: false }); await runMochitestUtilityAudio(src, { expectUtility: expectations[platform], expectContent: false, expectJava: false });
} catch (ex) { } catch (ex) {
ok(false, "Failure"); ok(false, "Failure");
} }
@ -29,7 +31,7 @@ SimpleTest.waitForExplicitFinish();
"small-shot.m4a", "small-shot.m4a",
]) { ]) {
try { try {
await runMochitestUtilityAudio(src, { expectUtility: false, expectContent: true }); await runMochitestUtilityAudio(src, { expectUtility: "", expectContent: false, expectJava: true });
} catch (ex) { } catch (ex) {
ok(false, "Failure"); ok(false, "Failure");
} }

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

@ -89,8 +89,14 @@ void SandboxTestingChild::Bind(Endpoint<PSandboxTestingChild>&& aEndpoint) {
RunTestsGenericUtility(this); RunTestsGenericUtility(this);
break; break;
case ipc::SandboxingKind::UTILITY_AUDIO_DECODING: case ipc::SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC:
RunTestsUtilityAudioDecoder(this); #ifdef MOZ_APPLEMEDIA
case ipc::SandboxingKind::UTILITY_AUDIO_DECODING_APPLE_MEDIA:
#endif
#ifdef XP_WIN
case ipc::SandboxingKind::UTILITY_AUDIO_DECODING_WMF:
#endif
RunTestsUtilityAudioDecoder(this, s->mSandbox);
break; break;
default: default:

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

@ -764,7 +764,8 @@ void RunTestsGenericUtility(SandboxTestingChild* child) {
#endif // XP_MACOSX #endif // XP_MACOSX
} }
void RunTestsUtilityAudioDecoder(SandboxTestingChild* child) { void RunTestsUtilityAudioDecoder(SandboxTestingChild* child,
ipc::SandboxingKind aSandbox) {
MOZ_ASSERT(child, "No SandboxTestingChild*?"); MOZ_ASSERT(child, "No SandboxTestingChild*?");
RunGenericTests(child); RunGenericTests(child);
@ -796,7 +797,9 @@ void RunTestsUtilityAudioDecoder(SandboxTestingChild* child) {
# elif XP_MACOSX // XP_LINUX # elif XP_MACOSX // XP_LINUX
RunMacTestLaunchProcess(child); RunMacTestLaunchProcess(child);
RunMacTestWindowServer(child); RunMacTestWindowServer(child);
RunMacTestAudioAPI(child, true); RunMacTestAudioAPI(
child,
aSandbox == ipc::SandboxingKind::UTILITY_AUDIO_DECODING_APPLE_MEDIA);
# endif // XP_MACOSX # endif // XP_MACOSX
#else // XP_UNIX #else // XP_UNIX
# ifdef XP_WIN # ifdef XP_WIN

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

@ -754,7 +754,7 @@ void SetUtilitySandbox(int aBroker, ipc::SandboxingKind aKind) {
policy = GetUtilitySandboxPolicy(sBroker); policy = GetUtilitySandboxPolicy(sBroker);
break; break;
case ipc::SandboxingKind::UTILITY_AUDIO_DECODING: case ipc::SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC:
policy = GetUtilityAudioDecoderSandboxPolicy(sBroker); policy = GetUtilityAudioDecoderSandboxPolicy(sBroker);
break; break;

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

@ -288,11 +288,12 @@ bool StartMacSandbox(MacSandboxInfo const& aInfo, std::string& aErrorMessage) {
switch (aInfo.utilityKind) { switch (aInfo.utilityKind) {
case ipc::SandboxingKind::GENERIC_UTILITY: case ipc::SandboxingKind::GENERIC_UTILITY:
case ipc::SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC:
// Nothing to do here specifically // Nothing to do here specifically
break; break;
case ipc::SandboxingKind::UTILITY_AUDIO_DECODING: { case ipc::SandboxingKind::UTILITY_AUDIO_DECODING_APPLE_MEDIA: {
profile.append(SandboxPolicyUtilityAudioDecoderAddend); profile.append(SandboxPolicyUtilityAudioDecoderAppleMediaAddend);
params.push_back("MAC_OS_VERSION"); params.push_back("MAC_OS_VERSION");
params.push_back(combinedVersion.c_str()); params.push_back(combinedVersion.c_str());
} break; } break;

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

@ -68,8 +68,9 @@ static const char SandboxPolicyUtility[] = R"SANDBOX_LITERAL(
(global-name "com.apple.coreservices.launchservicesd")) (global-name "com.apple.coreservices.launchservicesd"))
)SANDBOX_LITERAL"; )SANDBOX_LITERAL";
static const char SandboxPolicyUtilityAudioDecoderAddend[] = R"SANDBOX_LITERAL( static const char SandboxPolicyUtilityAudioDecoderAppleMediaAddend[] =
; For Utility AudioDecoder R"SANDBOX_LITERAL(
; For Utility AudioDecoder AppleMedia codecs
(define macosVersion (string->number (param "MAC_OS_VERSION"))) (define macosVersion (string->number (param "MAC_OS_VERSION")))
(if (>= macosVersion 1013) (if (>= macosVersion 1013)
(allow mach-lookup (allow mach-lookup

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

@ -1273,7 +1273,7 @@ bool SandboxBroker::SetSecurityLevelForUtilityProcess(
"SetJobLevel should never fail with these arguments, what happened?"); "SetJobLevel should never fail with these arguments, what happened?");
auto lockdownLevel = sandbox::USER_LOCKDOWN; auto lockdownLevel = sandbox::USER_LOCKDOWN;
if (aSandbox == mozilla::ipc::SandboxingKind::UTILITY_AUDIO_DECODING) { if (aSandbox == mozilla::ipc::SandboxingKind::UTILITY_AUDIO_DECODING_WMF) {
lockdownLevel = sandbox::USER_LIMITED; lockdownLevel = sandbox::USER_LIMITED;
} }
result = mPolicy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS, result = mPolicy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
@ -1339,11 +1339,15 @@ bool SandboxBroker::SetSecurityLevelForUtilityProcess(
// Investigate also why it crashes (no idea where exactly) for MinGW64 builds // Investigate also why it crashes (no idea where exactly) for MinGW64 builds
// //
// TODO: Bug 1773005 - AAC seems to not work on Windows < 1703 // TODO: Bug 1773005 - AAC seems to not work on Windows < 1703
if (aSandbox != mozilla::ipc::SandboxingKind::UTILITY_AUDIO_DECODING_WMF) {
mitigations |= sandbox::MITIGATION_DYNAMIC_CODE_DISABLE;
} else {
if (IsWin10CreatorsUpdateOrLater()) { if (IsWin10CreatorsUpdateOrLater()) {
#if defined(_M_X64) && !defined(__MINGW64__) #if defined(_M_X64) && !defined(__MINGW64__)
mitigations |= sandbox::MITIGATION_DYNAMIC_CODE_DISABLE; mitigations |= sandbox::MITIGATION_DYNAMIC_CODE_DISABLE;
#endif // defined(_M_X64) && !defined(__MINGW64__) #endif // defined(_M_X64) && !defined(__MINGW64__)
} }
}
if (exceptionModules.isNothing()) { if (exceptionModules.isNothing()) {
mitigations |= sandbox::MITIGATION_FORCE_MS_SIGNED_BINS; mitigations |= sandbox::MITIGATION_FORCE_MS_SIGNED_BINS;
@ -1373,7 +1377,8 @@ bool SandboxBroker::SetSecurityLevelForUtilityProcess(
switch (aSandbox) { switch (aSandbox) {
case mozilla::ipc::SandboxingKind::GENERIC_UTILITY: case mozilla::ipc::SandboxingKind::GENERIC_UTILITY:
case mozilla::ipc::SandboxingKind::UTILITY_AUDIO_DECODING: case mozilla::ipc::SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC:
case mozilla::ipc::SandboxingKind::UTILITY_AUDIO_DECODING_WMF:
// Nothing specific to perform yet? // Nothing specific to perform yet?
break; break;

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

@ -864,8 +864,16 @@ var View = {
let fluentName; let fluentName;
let fluentArgs = {}; let fluentArgs = {};
switch (data.actorName) { switch (data.actorName) {
case "audioDecoder": case "audioDecoder_Generic":
fluentName = "about-processes-utility-actor-audio-decoder"; fluentName = "about-processes-utility-actor-audio-decoder-generic";
break;
case "audioDecoder_AppleMedia":
fluentName = "about-processes-utility-actor-audio-decoder-applemedia";
break;
case "audioDecoder_WMF":
fluentName = "about-processes-utility-actor-audio-decoder-wmf";
break; break;
default: default:

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

@ -609,7 +609,7 @@ async function testAboutProcessesWithConfig({ showAllFrames, showThreads }) {
row.classList.contains("process") && row.classList.contains("process") &&
row.nextSibling && row.nextSibling &&
row.nextSibling.classList.contains("actor") && row.nextSibling.classList.contains("actor") &&
row.nextSibling.actor.actorName === "audioDecoder", row.nextSibling.actor.actorName === "audioDecoder_Generic",
}, },
]; ];
for (let finder of processesToBeFound) { for (let finder of processesToBeFound) {

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

@ -70,7 +70,9 @@ enum class ProcType {
enum class UtilityActorName { enum class UtilityActorName {
Unknown, Unknown,
AudioDecoder, AudioDecoder_Generic,
AudioDecoder_AppleMedia,
AudioDecoder_WMF
}; };
/* Get the CPU frequency to use to convert cycle time values to actual time. /* Get the CPU frequency to use to convert cycle time values to actual time.

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

@ -122,9 +122,12 @@ about-processes-frame-name-one = Subframe: { $url }
# $shortUrl (String) The shared prefix for the subframes in the group. # $shortUrl (String) The shared prefix for the subframes in the group.
about-processes-frame-name-many = Subframes ({ $number }): { $shortUrl } about-processes-frame-name-many = Subframes ({ $number }): { $shortUrl }
# Utility process actor names ## Utility process actor names
about-processes-utility-actor-unknown = Unknown actor about-processes-utility-actor-unknown = Unknown actor
about-processes-utility-actor-audio-decoder = Audio Decoder about-processes-utility-actor-audio-decoder-generic = Generic Audio Decoder
about-processes-utility-actor-audio-decoder-applemedia = Apple Media Audio Decoder
about-processes-utility-actor-audio-decoder-wmf = Windows Media Framework Audio Decoder
## Displaying CPU (percentage and total) ## Displaying CPU (percentage and total)
## Variables: ## Variables: