зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
bbf9109b68
Коммит
b135ca0732
|
@ -1033,14 +1033,17 @@ static WebIDLUtilityActorName UtilityActorNameToWebIDL(
|
|||
mozilla::UtilityActorName aType) {
|
||||
// Max is the value of the last enum, not the length, so add one.
|
||||
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, "
|
||||
"UtilityActorName must match UtilityActorName exactly");
|
||||
|
||||
// These must match the similar ones in ProcInfo.h and ChromeUtils.webidl
|
||||
switch (aType) {
|
||||
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");
|
||||
|
|
|
@ -706,7 +706,9 @@ dictionary WindowInfoDictionary {
|
|||
*/
|
||||
enum WebIDLUtilityActorName {
|
||||
"unknown",
|
||||
"audioDecoder",
|
||||
"audioDecoder_Generic",
|
||||
"audioDecoder_AppleMedia",
|
||||
"audioDecoder_WMF",
|
||||
};
|
||||
|
||||
dictionary UtilityActorsDictionary {
|
||||
|
|
|
@ -4906,7 +4906,7 @@ bool StartOpenBSDSandbox(GeckoProcessType type, ipc::SandboxingKind kind) {
|
|||
MOZ_RELEASE_ASSERT(kind <= SandboxingKind::COUNT,
|
||||
"Should define a sandbox");
|
||||
switch (kind) {
|
||||
case ipc::SandboxingKind::UTILITY_AUDIO_DECODING:
|
||||
case ipc::SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC:
|
||||
OpenBSDFindPledgeUnveilFilePath("pledge.utility-audioDecoder",
|
||||
pledgeFile);
|
||||
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 "mozilla/RemoteDecodeUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
RemoteDecoderChild::RemoteDecoderChild(RemoteDecodeIn aLocation)
|
||||
|
@ -99,13 +101,11 @@ RefPtr<MediaDataDecoder::InitPromise> RemoteDecoderChild::Init() {
|
|||
return;
|
||||
}
|
||||
const auto& initResponse = aResponse.get_InitCompletionIPDL();
|
||||
mDescription =
|
||||
initResponse.decoderDescription() +
|
||||
(GetManager()->Location() == RemoteDecodeIn::UtilityProcess
|
||||
? " (Utility remote)"_ns
|
||||
: GetManager()->Location() == RemoteDecodeIn::RddProcess
|
||||
? " (RDD remote)"_ns
|
||||
: " (GPU remote)"_ns);
|
||||
mDescription = initResponse.decoderDescription();
|
||||
mDescription.Append(" (");
|
||||
mDescription.Append(RemoteDecodeInToStr(GetManager()->Location()));
|
||||
mDescription.Append(" remote)");
|
||||
|
||||
mIsHardwareAccelerated = initResponse.hardware();
|
||||
mHardwareAcceleratedReason = initResponse.hardwareReason();
|
||||
mConversion = initResponse.conversion();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
#include "mozilla/ipc/Endpoint.h"
|
||||
#include "mozilla/layers/ISurfaceAllocator.h"
|
||||
#include "mozilla/ipc/UtilityAudioDecoderChild.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "mozilla/StaticPrefs_media.h"
|
||||
|
@ -192,7 +193,9 @@ RemoteDecoderManagerChild* RemoteDecoderManagerChild::GetSingleton(
|
|||
switch (aLocation) {
|
||||
case RemoteDecodeIn::GpuProcess:
|
||||
case RemoteDecodeIn::RddProcess:
|
||||
case RemoteDecodeIn::UtilityProcess:
|
||||
case RemoteDecodeIn::UtilityProcess_Generic:
|
||||
case RemoteDecodeIn::UtilityProcess_AppleMedia:
|
||||
case RemoteDecodeIn::UtilityProcess_WMF:
|
||||
return sRemoteDecoderManagerChildForProcesses[aLocation];
|
||||
default:
|
||||
MOZ_CRASH("Unexpected RemoteDecode variant");
|
||||
|
@ -214,7 +217,9 @@ bool RemoteDecoderManagerChild::Supports(
|
|||
switch (aLocation) {
|
||||
case RemoteDecodeIn::GpuProcess:
|
||||
case RemoteDecodeIn::RddProcess:
|
||||
case RemoteDecodeIn::UtilityProcess: {
|
||||
case RemoteDecodeIn::UtilityProcess_AppleMedia:
|
||||
case RemoteDecodeIn::UtilityProcess_Generic:
|
||||
case RemoteDecodeIn::UtilityProcess_WMF: {
|
||||
StaticMutexAutoLock lock(sProcessSupportedMutex);
|
||||
supported = sProcessSupported[aLocation];
|
||||
break;
|
||||
|
@ -225,8 +230,10 @@ bool RemoteDecoderManagerChild::Supports(
|
|||
if (!supported) {
|
||||
// We haven't received the correct information yet from either the GPU or
|
||||
// the RDD process nor the Utility process.
|
||||
if (aLocation == RemoteDecodeIn::UtilityProcess) {
|
||||
LaunchUtilityProcessIfNeeded();
|
||||
if (aLocation == RemoteDecodeIn::UtilityProcess_Generic ||
|
||||
aLocation == RemoteDecodeIn::UtilityProcess_AppleMedia ||
|
||||
aLocation == RemoteDecodeIn::UtilityProcess_WMF) {
|
||||
LaunchUtilityProcessIfNeeded(aLocation);
|
||||
}
|
||||
if (aLocation == RemoteDecodeIn::RddProcess) {
|
||||
// Ensure the RDD process got started.
|
||||
|
@ -274,10 +281,13 @@ RemoteDecoderManagerChild::CreateAudioDecoder(
|
|||
__func__);
|
||||
}
|
||||
|
||||
bool useUtilityAudioDecoding = StaticPrefs::media_utility_process_enabled() &&
|
||||
aLocation == RemoteDecodeIn::UtilityProcess;
|
||||
bool useUtilityAudioDecoding =
|
||||
StaticPrefs::media_utility_process_enabled() &&
|
||||
(aLocation == RemoteDecodeIn::UtilityProcess_Generic ||
|
||||
aLocation == RemoteDecodeIn::UtilityProcess_AppleMedia ||
|
||||
aLocation == RemoteDecodeIn::UtilityProcess_WMF);
|
||||
RefPtr<GenericNonExclusivePromise> launchPromise =
|
||||
useUtilityAudioDecoding ? LaunchUtilityProcessIfNeeded()
|
||||
useUtilityAudioDecoding ? LaunchUtilityProcessIfNeeded(aLocation)
|
||||
: LaunchRDDProcessIfNeeded();
|
||||
|
||||
return launchPromise->Then(
|
||||
|
@ -482,7 +492,8 @@ RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded() {
|
|||
|
||||
/* static */
|
||||
RefPtr<GenericNonExclusivePromise>
|
||||
RemoteDecoderManagerChild::LaunchUtilityProcessIfNeeded() {
|
||||
RemoteDecoderManagerChild::LaunchUtilityProcessIfNeeded(
|
||||
RemoteDecodeIn aLocation) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(XRE_IsContentProcess(),
|
||||
"Only supported from a content process.");
|
||||
|
||||
|
@ -494,7 +505,7 @@ RemoteDecoderManagerChild::LaunchUtilityProcessIfNeeded() {
|
|||
}
|
||||
|
||||
StaticMutexAutoLock lock(sLaunchMutex);
|
||||
auto& utilityLaunchPromise = sLaunchPromises[RemoteDecodeIn::UtilityProcess];
|
||||
auto& utilityLaunchPromise = sLaunchPromises[aLocation];
|
||||
|
||||
if (utilityLaunchPromise) {
|
||||
return utilityLaunchPromise;
|
||||
|
@ -515,8 +526,9 @@ RemoteDecoderManagerChild::LaunchUtilityProcessIfNeeded() {
|
|||
// IPC connections between *this* content process and the Utility process.
|
||||
|
||||
RefPtr<GenericNonExclusivePromise> p = InvokeAsync(
|
||||
managerThread, __func__, []() -> RefPtr<GenericNonExclusivePromise> {
|
||||
auto* rps = GetSingleton(RemoteDecodeIn::UtilityProcess);
|
||||
managerThread, __func__,
|
||||
[aLocation]() -> RefPtr<GenericNonExclusivePromise> {
|
||||
auto* rps = GetSingleton(aLocation);
|
||||
if (rps && rps->CanSend()) {
|
||||
return GenericNonExclusivePromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
@ -528,36 +540,37 @@ RemoteDecoderManagerChild::LaunchUtilityProcessIfNeeded() {
|
|||
__func__);
|
||||
}
|
||||
|
||||
return bgActor->SendEnsureUtilityProcessAndCreateBridge()->Then(
|
||||
managerThread, __func__,
|
||||
[](ipc::PBackgroundChild::
|
||||
EnsureUtilityProcessAndCreateBridgePromise::
|
||||
ResolveOrRejectValue&& aResult)
|
||||
-> RefPtr<GenericNonExclusivePromise> {
|
||||
nsCOMPtr<nsISerialEventTarget> managerThread = GetManagerThread();
|
||||
if (!managerThread || aResult.IsReject()) {
|
||||
// The parent process died or we got shutdown
|
||||
return GenericNonExclusivePromise::CreateAndReject(
|
||||
NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
nsresult rv = Get<0>(aResult.ResolveValue());
|
||||
if (NS_FAILED(rv)) {
|
||||
return GenericNonExclusivePromise::CreateAndReject(rv,
|
||||
__func__);
|
||||
}
|
||||
OpenRemoteDecoderManagerChildForProcess(
|
||||
Get<1>(std::move(aResult.ResolveValue())),
|
||||
RemoteDecodeIn::UtilityProcess);
|
||||
return GenericNonExclusivePromise::CreateAndResolve(true,
|
||||
__func__);
|
||||
});
|
||||
return bgActor->SendEnsureUtilityProcessAndCreateBridge(aLocation)
|
||||
->Then(managerThread, __func__,
|
||||
[aLocation](ipc::PBackgroundChild::
|
||||
EnsureUtilityProcessAndCreateBridgePromise::
|
||||
ResolveOrRejectValue&& aResult)
|
||||
-> RefPtr<GenericNonExclusivePromise> {
|
||||
nsCOMPtr<nsISerialEventTarget> managerThread =
|
||||
GetManagerThread();
|
||||
if (!managerThread || aResult.IsReject()) {
|
||||
// The parent process died or we got shutdown
|
||||
return GenericNonExclusivePromise::CreateAndReject(
|
||||
NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
nsresult rv = Get<0>(aResult.ResolveValue());
|
||||
if (NS_FAILED(rv)) {
|
||||
return GenericNonExclusivePromise::CreateAndReject(
|
||||
rv, __func__);
|
||||
}
|
||||
OpenRemoteDecoderManagerChildForProcess(
|
||||
Get<1>(std::move(aResult.ResolveValue())), aLocation);
|
||||
return GenericNonExclusivePromise::CreateAndResolve(
|
||||
true, __func__);
|
||||
});
|
||||
});
|
||||
|
||||
p = p->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[](const GenericNonExclusivePromise::ResolveOrRejectValue& aResult) {
|
||||
[aLocation](
|
||||
const GenericNonExclusivePromise::ResolveOrRejectValue& aResult) {
|
||||
StaticMutexAutoLock lock(sLaunchMutex);
|
||||
sLaunchPromises[RemoteDecodeIn::UtilityProcess] = nullptr;
|
||||
sLaunchPromises[aLocation] = nullptr;
|
||||
return GenericNonExclusivePromise::CreateAndResolveOrReject(aResult,
|
||||
__func__);
|
||||
});
|
||||
|
@ -598,7 +611,9 @@ TrackSupportSet RemoteDecoderManagerChild::GetTrackSupport(
|
|||
#endif
|
||||
return s;
|
||||
}
|
||||
case RemoteDecodeIn::UtilityProcess:
|
||||
case RemoteDecodeIn::UtilityProcess_Generic:
|
||||
case RemoteDecodeIn::UtilityProcess_AppleMedia:
|
||||
case RemoteDecodeIn::UtilityProcess_WMF:
|
||||
return StaticPrefs::media_utility_process_enabled()
|
||||
? TrackSupportSet{TrackSupport::Audio}
|
||||
: TrackSupportSet{TrackSupport::None};
|
||||
|
@ -647,7 +662,9 @@ RemoteDecoderManagerChild::RemoteDecoderManagerChild(RemoteDecodeIn aLocation)
|
|||
: mLocation(aLocation) {
|
||||
MOZ_ASSERT(mLocation == RemoteDecodeIn::GpuProcess ||
|
||||
mLocation == RemoteDecodeIn::RddProcess ||
|
||||
mLocation == RemoteDecodeIn::UtilityProcess);
|
||||
mLocation == RemoteDecodeIn::UtilityProcess_Generic ||
|
||||
mLocation == RemoteDecodeIn::UtilityProcess_AppleMedia ||
|
||||
mLocation == RemoteDecodeIn::UtilityProcess_WMF);
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
@ -809,7 +826,9 @@ void RemoteDecoderManagerChild::SetSupported(
|
|||
switch (aLocation) {
|
||||
case RemoteDecodeIn::GpuProcess:
|
||||
case RemoteDecodeIn::RddProcess:
|
||||
case RemoteDecodeIn::UtilityProcess: {
|
||||
case RemoteDecodeIn::UtilityProcess_AppleMedia:
|
||||
case RemoteDecodeIn::UtilityProcess_Generic:
|
||||
case RemoteDecodeIn::UtilityProcess_WMF: {
|
||||
StaticMutexAutoLock lock(sProcessSupportedMutex);
|
||||
sProcessSupported[aLocation] = Some(aSupported);
|
||||
break;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "mozilla/EnumTypeTraits.h"
|
||||
#include "mozilla/PRemoteDecoderManagerChild.h"
|
||||
#include "mozilla/layers/VideoBridgeUtils.h"
|
||||
#include "mozilla/ipc/UtilityProcessSandboxing.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -22,7 +23,9 @@ enum class RemoteDecodeIn {
|
|||
Unspecified,
|
||||
RddProcess,
|
||||
GpuProcess,
|
||||
UtilityProcess,
|
||||
UtilityProcess_Generic,
|
||||
UtilityProcess_AppleMedia,
|
||||
UtilityProcess_WMF,
|
||||
|
||||
SENTINEL,
|
||||
};
|
||||
|
@ -127,7 +130,8 @@ class RemoteDecoderManagerChild final
|
|||
static void OpenRemoteDecoderManagerChildForProcess(
|
||||
Endpoint<PRemoteDecoderManagerChild>&& aEndpoint,
|
||||
RemoteDecodeIn aLocation);
|
||||
static RefPtr<GenericNonExclusivePromise> LaunchUtilityProcessIfNeeded();
|
||||
static RefPtr<GenericNonExclusivePromise> LaunchUtilityProcessIfNeeded(
|
||||
RemoteDecodeIn aLocation);
|
||||
|
||||
RefPtr<RemoteDecoderManagerChild> mIPDLSelfRef;
|
||||
// The location for decoding, Rdd or Gpu process.
|
||||
|
|
|
@ -26,6 +26,7 @@ EXPORTS.mozilla += [
|
|||
"RemoteDecoderManagerParent.h",
|
||||
"RemoteDecoderModule.h",
|
||||
"RemoteDecoderParent.h",
|
||||
"RemoteDecodeUtils.h",
|
||||
"RemoteImageHolder.h",
|
||||
"RemoteMediaData.h",
|
||||
"RemoteMediaDataDecoder.h",
|
||||
|
@ -48,6 +49,7 @@ SOURCES += [
|
|||
"RemoteDecoderManagerParent.cpp",
|
||||
"RemoteDecoderModule.cpp",
|
||||
"RemoteDecoderParent.cpp",
|
||||
"RemoteDecodeUtils.cpp",
|
||||
"RemoteImageHolder.cpp",
|
||||
"RemoteMediaData.cpp",
|
||||
"RemoteMediaDataDecoder.cpp",
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include "nsIXULRuntime.h" // for BrowserTabsRemoteAutostart
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
#include "mozilla/ipc/UtilityAudioDecoderParent.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
# include "WMFDecoderModule.h"
|
||||
# include "mozilla/WindowsVersion.h"
|
||||
|
@ -562,38 +564,44 @@ void PDMFactory::CreateRddPDMs() {
|
|||
}
|
||||
|
||||
void PDMFactory::CreateUtilityPDMs() {
|
||||
const ipc::SandboxingKind aKind =
|
||||
ipc::UtilityAudioDecoderParent::GetSandboxingKind();
|
||||
#ifdef XP_WIN
|
||||
if (StaticPrefs::media_wmf_enabled() &&
|
||||
StaticPrefs::media_utility_wmf_enabled()) {
|
||||
StaticPrefs::media_utility_wmf_enabled() &&
|
||||
aKind == ipc::SandboxingKind::UTILITY_AUDIO_DECODING_WMF) {
|
||||
CreateAndStartupPDM<WMFDecoderModule>();
|
||||
}
|
||||
#endif
|
||||
#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>();
|
||||
}
|
||||
#endif
|
||||
if (aKind == ipc::SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC) {
|
||||
#ifdef MOZ_FFVPX
|
||||
if (StaticPrefs::media_ffvpx_enabled() &&
|
||||
StaticPrefs::media_utility_ffvpx_enabled()) {
|
||||
CreateAndStartupPDM<FFVPXRuntimeLinker>();
|
||||
}
|
||||
if (StaticPrefs::media_ffvpx_enabled() &&
|
||||
StaticPrefs::media_utility_ffvpx_enabled()) {
|
||||
CreateAndStartupPDM<FFVPXRuntimeLinker>();
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_FFMPEG
|
||||
if (StaticPrefs::media_ffmpeg_enabled() &&
|
||||
StaticPrefs::media_utility_ffmpeg_enabled() &&
|
||||
!CreateAndStartupPDM<FFmpegRuntimeLinker>()) {
|
||||
mFailureFlags += GetFailureFlagBasedOnFFmpegStatus(
|
||||
FFmpegRuntimeLinker::LinkStatusCode());
|
||||
}
|
||||
if (StaticPrefs::media_ffmpeg_enabled() &&
|
||||
StaticPrefs::media_utility_ffmpeg_enabled() &&
|
||||
!CreateAndStartupPDM<FFmpegRuntimeLinker>()) {
|
||||
mFailureFlags += GetFailureFlagBasedOnFFmpegStatus(
|
||||
FFmpegRuntimeLinker::LinkStatusCode());
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (StaticPrefs::media_utility_android_media_codec_enabled()) {
|
||||
StartupPDM(AndroidDecoderModule::Create(),
|
||||
StaticPrefs::media_android_media_codec_preferred());
|
||||
}
|
||||
if (StaticPrefs::media_utility_android_media_codec_enabled()) {
|
||||
StartupPDM(AndroidDecoderModule::Create(),
|
||||
StaticPrefs::media_android_media_codec_preferred());
|
||||
}
|
||||
#endif
|
||||
CreateAndStartupPDM<AgnosticDecoderModule>();
|
||||
CreateAndStartupPDM<AgnosticDecoderModule>();
|
||||
}
|
||||
}
|
||||
|
||||
void PDMFactory::CreateContentPDMs() {
|
||||
|
@ -606,7 +614,18 @@ void PDMFactory::CreateContentPDMs() {
|
|||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
# include "mozilla/EnumSet.h"
|
||||
# include "mozilla/MozPromise.h"
|
||||
# include "mozilla/RefPtr.h"
|
||||
# include "mozilla/ipc/UtilityProcessSandboxing.h"
|
||||
# include "nsISupports.h"
|
||||
# include "nsStringFwd.h"
|
||||
# include "nsTArray.h"
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/RDDProcessManager.h"
|
||||
#include "mozilla/ipc/UtilityProcessManager.h"
|
||||
#include "mozilla/RemoteDecodeUtils.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/BackgroundSessionStorageServiceParent.h"
|
||||
#include "mozilla/dom/ClientManagerActors.h"
|
||||
|
@ -1372,6 +1373,7 @@ BackgroundParentImpl::RecvEnsureRDDProcessAndCreateBridge(
|
|||
|
||||
mozilla::ipc::IPCResult
|
||||
BackgroundParentImpl::RecvEnsureUtilityProcessAndCreateBridge(
|
||||
const RemoteDecodeIn& aLocation,
|
||||
EnsureUtilityProcessAndCreateBridgeResolver&& aResolver) {
|
||||
base::ProcessId otherPid = OtherPid();
|
||||
nsCOMPtr<nsISerialEventTarget> managerThread = GetCurrentSerialEventTarget();
|
||||
|
@ -1380,7 +1382,7 @@ BackgroundParentImpl::RecvEnsureUtilityProcessAndCreateBridge(
|
|||
}
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction(
|
||||
"BackgroundParentImpl::RecvEnsureUtilityProcessAndCreateBridge()",
|
||||
[aResolver, managerThread, otherPid]() {
|
||||
[aResolver, managerThread, otherPid, aLocation]() {
|
||||
RefPtr<UtilityProcessManager> upm =
|
||||
UtilityProcessManager::GetSingleton();
|
||||
using Type = Tuple<const nsresult&,
|
||||
|
@ -1389,18 +1391,20 @@ BackgroundParentImpl::RecvEnsureUtilityProcessAndCreateBridge(
|
|||
aResolver(Type(NS_ERROR_NOT_AVAILABLE,
|
||||
Endpoint<PRemoteDecoderManagerChild>()));
|
||||
} else {
|
||||
upm->StartAudioDecoding(otherPid)->Then(
|
||||
managerThread, __func__,
|
||||
[resolver = std::move(aResolver)](
|
||||
mozilla::ipc::UtilityProcessManager::AudioDecodingPromise::
|
||||
ResolveOrRejectValue&& aValue) mutable {
|
||||
if (aValue.IsReject()) {
|
||||
resolver(Type(aValue.RejectValue(),
|
||||
Endpoint<PRemoteDecoderManagerChild>()));
|
||||
return;
|
||||
}
|
||||
resolver(Type(NS_OK, std::move(aValue.ResolveValue())));
|
||||
});
|
||||
SandboxingKind sbKind = GetSandboxingKindFromLocation(aLocation);
|
||||
upm->StartAudioDecoding(otherPid, sbKind)
|
||||
->Then(managerThread, __func__,
|
||||
[resolver = aResolver](
|
||||
mozilla::ipc::UtilityProcessManager::
|
||||
AudioDecodingPromise::ResolveOrRejectValue&&
|
||||
aValue) mutable {
|
||||
if (aValue.IsReject()) {
|
||||
resolver(Type(aValue.RejectValue(),
|
||||
Endpoint<PRemoteDecoderManagerChild>()));
|
||||
return;
|
||||
}
|
||||
resolver(Type(NS_OK, std::move(aValue.ResolveValue())));
|
||||
});
|
||||
}
|
||||
}));
|
||||
return IPC_OK();
|
||||
|
|
|
@ -386,6 +386,7 @@ class BackgroundParentImpl : public PBackgroundParent {
|
|||
EnsureRDDProcessAndCreateBridgeResolver&& aResolver) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvEnsureUtilityProcessAndCreateBridge(
|
||||
const RemoteDecodeIn& aLocation,
|
||||
EnsureUtilityProcessAndCreateBridgeResolver&& aResolver) override;
|
||||
|
||||
bool DeallocPEndpointForReportParent(
|
||||
|
|
|
@ -76,6 +76,8 @@ using mozilla::dom::cache::Namespace
|
|||
|
||||
using class mozilla::dom::SSCacheCopy from "mozilla/dom/PBackgroundSessionStorageCache.h";
|
||||
|
||||
using mozilla::RemoteDecodeIn from "mozilla/RemoteDecoderManagerChild.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
|
@ -297,7 +299,7 @@ parent:
|
|||
async EnsureRDDProcessAndCreateBridge()
|
||||
returns (nsresult rv, Endpoint<PRemoteDecoderManagerChild> aEndpoint);
|
||||
|
||||
async EnsureUtilityProcessAndCreateBridge()
|
||||
async EnsureUtilityProcessAndCreateBridge(RemoteDecodeIn aLocation)
|
||||
returns (nsresult rv, Endpoint<PRemoteDecoderManagerChild> aEndpoint);
|
||||
|
||||
async PWebSocketConnection(uint32_t aListenerId);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
include protocol PRemoteDecoderManager;
|
||||
|
||||
using mozilla::media::MediaCodecsSupported from "MediaCodecsSupport.h";
|
||||
using mozilla::RemoteDecodeIn from "mozilla/RemoteDecoderManagerChild.h";
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -20,7 +21,7 @@ parent:
|
|||
Endpoint<PRemoteDecoderManagerParent> endpoint);
|
||||
|
||||
child:
|
||||
async UpdateMediaCodecsSupported(MediaCodecsSupported aSupported);
|
||||
async UpdateMediaCodecsSupported(RemoteDecodeIn aLocation, MediaCodecsSupported aSupported);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -6,20 +6,24 @@
|
|||
|
||||
#include "UtilityAudioDecoderChild.h"
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "mozilla/AppShutdown.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void UtilityAudioDecoderChild::ActorDestroy(ActorDestroyReason aReason) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
sAudioDecoderChild = nullptr;
|
||||
sAudioDecoderChilds[mSandbox] = nullptr;
|
||||
}
|
||||
|
||||
void UtilityAudioDecoderChild::Bind(
|
||||
|
@ -29,20 +33,22 @@ void UtilityAudioDecoderChild::Bind(
|
|||
}
|
||||
|
||||
/* static */
|
||||
RefPtr<UtilityAudioDecoderChild> UtilityAudioDecoderChild::GetSingleton() {
|
||||
RefPtr<UtilityAudioDecoderChild> UtilityAudioDecoderChild::GetSingleton(
|
||||
SandboxingKind aKind) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
bool shutdown = AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMWillShutdown);
|
||||
if (!sAudioDecoderChild && !shutdown) {
|
||||
sAudioDecoderChild = new UtilityAudioDecoderChild();
|
||||
if (!sAudioDecoderChilds[aKind] && !shutdown) {
|
||||
sAudioDecoderChilds[aKind] = new UtilityAudioDecoderChild(aKind);
|
||||
}
|
||||
return sAudioDecoderChild;
|
||||
return sAudioDecoderChilds[aKind];
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
UtilityAudioDecoderChild::RecvUpdateMediaCodecsSupported(
|
||||
const RemoteDecodeIn& aLocation,
|
||||
const media::MediaCodecsSupported& aSupported) {
|
||||
dom::ContentParent::BroadcastMediaCodecsSupportedUpdate(
|
||||
RemoteDecodeIn::UtilityProcess, aSupported);
|
||||
dom::ContentParent::BroadcastMediaCodecsSupportedUpdate(aLocation,
|
||||
aSupported);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "mozilla/ipc/Endpoint.h"
|
||||
#include "mozilla/ipc/UtilityProcessParent.h"
|
||||
#include "mozilla/ipc/UtilityProcessSandboxing.h"
|
||||
#include "mozilla/ipc/PUtilityAudioDecoderChild.h"
|
||||
|
||||
#include "PDMFactory.h"
|
||||
|
@ -24,9 +25,25 @@ class UtilityAudioDecoderChild final : public PUtilityAudioDecoderChild {
|
|||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UtilityAudioDecoderChild, override);
|
||||
|
||||
mozilla::ipc::IPCResult RecvUpdateMediaCodecsSupported(
|
||||
const RemoteDecodeIn& aLocation,
|
||||
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) {
|
||||
Endpoint<PUtilityAudioDecoderChild> utilityAudioDecoderChildEnd;
|
||||
|
@ -54,11 +71,13 @@ class UtilityAudioDecoderChild final : public PUtilityAudioDecoderChild {
|
|||
|
||||
void Bind(Endpoint<PUtilityAudioDecoderChild>&& aEndpoint);
|
||||
|
||||
static RefPtr<UtilityAudioDecoderChild> GetSingleton();
|
||||
static RefPtr<UtilityAudioDecoderChild> GetSingleton(SandboxingKind aKind);
|
||||
|
||||
private:
|
||||
UtilityAudioDecoderChild();
|
||||
explicit UtilityAudioDecoderChild(SandboxingKind aKind);
|
||||
~UtilityAudioDecoderChild() = default;
|
||||
|
||||
const SandboxingKind mSandbox;
|
||||
};
|
||||
|
||||
} // namespace mozilla::ipc
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
# include "AndroidDecoderModule.h"
|
||||
#endif
|
||||
|
||||
#include "mozilla/ipc/UtilityProcessChild.h"
|
||||
#include "mozilla/RemoteDecodeUtils.h"
|
||||
|
||||
namespace mozilla::ipc {
|
||||
|
||||
UtilityAudioDecoderParent::UtilityAudioDecoderParent() {
|
||||
|
@ -33,14 +36,18 @@ UtilityAudioDecoderParent::UtilityAudioDecoderParent() {
|
|||
}
|
||||
|
||||
/* static */
|
||||
void UtilityAudioDecoderParent::PreloadForSandbox() {
|
||||
void UtilityAudioDecoderParent::GenericPreloadForSandbox() {
|
||||
#if defined(MOZ_SANDBOX) && defined(OS_WIN)
|
||||
// Preload AV dlls so we can enable Binary Signature Policy
|
||||
// to restrict further dll loads.
|
||||
::LoadLibraryW(L"mozavcodec.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"mf.dll");
|
||||
|
||||
|
@ -56,6 +63,15 @@ void UtilityAudioDecoderParent::PreloadForSandbox() {
|
|||
#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(
|
||||
Endpoint<PUtilityAudioDecoderParent>&& aEndpoint) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
@ -71,7 +87,8 @@ void UtilityAudioDecoderParent::Start(
|
|||
#endif
|
||||
|
||||
auto supported = PDMFactory::Supported();
|
||||
Unused << SendUpdateMediaCodecsSupported(std::move(supported));
|
||||
Unused << SendUpdateMediaCodecsSupported(
|
||||
GetRemoteDecodeInFromKind(GetSandboxingKind()), supported);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include "mozilla/ipc/Endpoint.h"
|
||||
#include "mozilla/ipc/PUtilityAudioDecoderParent.h"
|
||||
|
||||
#include "mozilla/ipc/UtilityProcessSandboxing.h"
|
||||
|
||||
#include "nsThreadManager.h"
|
||||
|
||||
namespace mozilla::ipc {
|
||||
|
@ -24,13 +26,16 @@ class UtilityAudioDecoderParent final : public PUtilityAudioDecoderParent {
|
|||
|
||||
UtilityAudioDecoderParent();
|
||||
|
||||
static void PreloadForSandbox();
|
||||
static void GenericPreloadForSandbox();
|
||||
static void WMFPreloadForSandbox();
|
||||
|
||||
void Start(Endpoint<PUtilityAudioDecoderParent>&& aEndpoint);
|
||||
|
||||
mozilla::ipc::IPCResult RecvNewContentRemoteDecoderManager(
|
||||
Endpoint<PRemoteDecoderManagerParent>&& aEndpoint);
|
||||
|
||||
static SandboxingKind GetSandboxingKind();
|
||||
|
||||
private:
|
||||
~UtilityAudioDecoderParent() = default;
|
||||
};
|
||||
|
|
|
@ -197,7 +197,7 @@ void UtilityProcessHost::InitAfterConnect(bool aSucceeded) {
|
|||
UniquePtr<SandboxBroker::Policy> policy;
|
||||
switch (mSandbox) {
|
||||
case SandboxingKind::GENERIC_UTILITY:
|
||||
case SandboxingKind::UTILITY_AUDIO_DECODING: // TODO: NEW POLICY?
|
||||
case SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC:
|
||||
policy = SandboxBrokerPolicyFactory::GetUtilityProcessPolicy(
|
||||
GetActor()->OtherPid());
|
||||
break;
|
||||
|
|
|
@ -38,8 +38,12 @@ bool UtilityProcessImpl::Init(int aArgc, char* aArgv[]) {
|
|||
// lower the sandbox in processes where the policy will prevent loading.
|
||||
::LoadLibraryW(L"winmm.dll");
|
||||
|
||||
if (*sandboxingKind == SandboxingKind::UTILITY_AUDIO_DECODING) {
|
||||
UtilityAudioDecoderParent::PreloadForSandbox();
|
||||
if (*sandboxingKind == SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC) {
|
||||
UtilityAudioDecoderParent::GenericPreloadForSandbox();
|
||||
}
|
||||
|
||||
if (*sandboxingKind == SandboxingKind::UTILITY_AUDIO_DECODING_WMF) {
|
||||
UtilityAudioDecoderParent::WMFPreloadForSandbox();
|
||||
}
|
||||
|
||||
// Go for it
|
||||
|
|
|
@ -263,18 +263,18 @@ RefPtr<GenericNonExclusivePromise> UtilityProcessManager::StartUtility(
|
|||
}
|
||||
|
||||
RefPtr<UtilityProcessManager::AudioDecodingPromise>
|
||||
UtilityProcessManager::StartAudioDecoding(base::ProcessId aOtherProcess) {
|
||||
UtilityProcessManager::StartAudioDecoding(base::ProcessId aOtherProcess,
|
||||
SandboxingKind aSandbox) {
|
||||
RefPtr<UtilityProcessManager> self = this;
|
||||
RefPtr<UtilityAudioDecoderChild> uadc =
|
||||
UtilityAudioDecoderChild::GetSingleton();
|
||||
UtilityAudioDecoderChild::GetSingleton(aSandbox);
|
||||
MOZ_ASSERT(uadc, "Unable to get a singleton for UtilityAudioDecoderChild");
|
||||
return StartUtility(uadc, SandboxingKind::UTILITY_AUDIO_DECODING)
|
||||
return StartUtility(uadc, aSandbox)
|
||||
->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[self, uadc, aOtherProcess]() {
|
||||
[self, uadc, aOtherProcess, aSandbox]() {
|
||||
base::ProcessId process =
|
||||
self->GetProcessParent(SandboxingKind::UTILITY_AUDIO_DECODING)
|
||||
->OtherPid();
|
||||
self->GetProcessParent(aSandbox)->OtherPid();
|
||||
|
||||
if (!uadc->CanSend()) {
|
||||
MOZ_ASSERT(false, "UtilityAudioDecoderChild lost in the middle");
|
||||
|
|
|
@ -46,8 +46,8 @@ class UtilityProcessManager final : public UtilityProcessHost::Listener {
|
|||
RefPtr<GenericNonExclusivePromise> StartUtility(RefPtr<Actor> aActor,
|
||||
SandboxingKind aSandbox);
|
||||
|
||||
RefPtr<AudioDecodingPromise> StartAudioDecoding(
|
||||
base::ProcessId aOtherProcess);
|
||||
RefPtr<AudioDecodingPromise> StartAudioDecoding(base::ProcessId aOtherProcess,
|
||||
SandboxingKind aSandbox);
|
||||
|
||||
void OnProcessUnexpectedShutdown(UtilityProcessHost* aHost);
|
||||
|
||||
|
|
|
@ -16,9 +16,15 @@ namespace ipc {
|
|||
// to be updated as well.
|
||||
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,
|
||||
|
||||
|
|
|
@ -3,22 +3,25 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
async function getAudioDecoderPid() {
|
||||
async function getAudioDecoderPid(expectation) {
|
||||
info("Finding a running AudioDecoder");
|
||||
|
||||
const actor = expectation.replace("Utility ", "");
|
||||
|
||||
let audioDecoderProcess = (await ChromeUtils.requestProcInfo()).children.find(
|
||||
p =>
|
||||
p.type === "utility" &&
|
||||
p.utilityActors.find(a => a.actorName === "audioDecoder")
|
||||
p.utilityActors.find(a => a.actorName === `audioDecoder_${actor}`)
|
||||
);
|
||||
ok(
|
||||
audioDecoderProcess,
|
||||
`Found the AudioDecoder process at ${audioDecoderProcess.pid}`
|
||||
`Found the AudioDecoder ${actor} process at ${audioDecoderProcess.pid}`
|
||||
);
|
||||
return audioDecoderProcess.pid;
|
||||
}
|
||||
|
||||
async function crashDecoder() {
|
||||
const audioPid = await getAudioDecoderPid();
|
||||
async function crashDecoder(expectation) {
|
||||
const audioPid = await getAudioDecoderPid(expectation);
|
||||
ok(audioPid > 0, `Found an audio decoder ${audioPid}`);
|
||||
|
||||
const ProcessTools = Cc["@mozilla.org/processtools-service;1"].getService(
|
||||
|
@ -27,15 +30,15 @@ async function crashDecoder() {
|
|||
ProcessTools.kill(audioPid);
|
||||
}
|
||||
|
||||
async function runTest(src, withClose) {
|
||||
async function runTest(src, withClose, expectation) {
|
||||
info(`Add media tabs: ${src}`);
|
||||
let tab = await addMediaTab(src);
|
||||
|
||||
info("Play tab");
|
||||
await play(tab, true /* expectUtility */);
|
||||
await play(tab, expectation);
|
||||
|
||||
info("Crash decoder");
|
||||
await crashDecoder();
|
||||
await crashDecoder(expectation);
|
||||
|
||||
if (withClose) {
|
||||
info("Stop tab");
|
||||
|
@ -49,7 +52,7 @@ async function runTest(src, withClose) {
|
|||
}
|
||||
|
||||
info("Play tab again");
|
||||
await play(tab, true);
|
||||
await play(tab, expectation);
|
||||
|
||||
info("Stop tab");
|
||||
await stop(tab);
|
||||
|
@ -69,13 +72,15 @@ async function testAudioCrash(withClose) {
|
|||
|
||||
SimpleTest.expectChildProcessCrash();
|
||||
|
||||
for (let src of [
|
||||
"small-shot.ogg",
|
||||
"small-shot.mp3",
|
||||
"small-shot.m4a",
|
||||
"small-shot.flac",
|
||||
]) {
|
||||
await runTest(src, withClose);
|
||||
const platform = Services.appinfo.OS;
|
||||
|
||||
for (let { src, expectations } of audioTestData()) {
|
||||
if (!(platform in expectations)) {
|
||||
info(`Skipping ${src} for ${platform}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
await runTest(src, withClose, expectations[platform]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,19 +16,21 @@ async function runTest(expectUtility) {
|
|||
});
|
||||
}
|
||||
|
||||
for (let src of [
|
||||
"small-shot.ogg",
|
||||
"small-shot.mp3",
|
||||
"small-shot.m4a",
|
||||
"small-shot.flac",
|
||||
]) {
|
||||
const platform = Services.appinfo.OS;
|
||||
|
||||
for (let { src, expectations } of audioTestData()) {
|
||||
if (!(platform in expectations)) {
|
||||
info(`Skipping ${src} for ${platform}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
info(`Add media tabs: ${src}`);
|
||||
let tabs = [await addMediaTab(src), await addMediaTab(src)];
|
||||
let playback = [];
|
||||
|
||||
info("Play tabs");
|
||||
for (let tab of tabs) {
|
||||
playback.push(play(tab, expectUtility));
|
||||
playback.push(play(tab, expectUtility ? expectations[platform] : "RDD"));
|
||||
}
|
||||
|
||||
info("Wait all playback");
|
||||
|
|
|
@ -40,6 +40,49 @@ async function cleanUtilityProcessShutdown(utilityPid) {
|
|||
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) {
|
||||
const tab = BrowserTestUtils.addTab(gBrowser, "about:blank", {
|
||||
forceNewProcess: true,
|
||||
|
@ -50,11 +93,16 @@ async function addMediaTab(src) {
|
|||
return tab;
|
||||
}
|
||||
|
||||
async function play(tab, expectUtility, expectContent = false) {
|
||||
async function play(
|
||||
tab,
|
||||
expectUtility,
|
||||
expectContent = false,
|
||||
expectJava = false
|
||||
) {
|
||||
let browser = tab.linkedBrowser;
|
||||
return SpecialPowers.spawn(
|
||||
browser,
|
||||
[expectUtility, expectContent],
|
||||
[expectUtility, expectContent, expectJava],
|
||||
checkAudioDecoder
|
||||
);
|
||||
}
|
||||
|
@ -77,25 +125,28 @@ async function createAudioElement(src) {
|
|||
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;
|
||||
let audio = doc.querySelector("audio");
|
||||
const checkPromise = new Promise((resolve, reject) => {
|
||||
const timeUpdateHandler = async ev => {
|
||||
const debugInfo = await SpecialPowers.wrap(audio).mozRequestDebugInfo();
|
||||
const audioDecoderName = debugInfo.decoder.reader.audioDecoderName;
|
||||
const isUtility = audioDecoderName.indexOf("(Utility remote)") > 0;
|
||||
const isRDD = audioDecoderName.indexOf("(RDD remote)") > 0;
|
||||
const isExpected =
|
||||
audioDecoderName.indexOf(`(${expectedProcess} remote)`) > 0;
|
||||
const isJavaRemote = audioDecoderName.indexOf("(remote)") > 0;
|
||||
const isContent = !isUtility && !isRDD;
|
||||
const isOk =
|
||||
(expectUtility === true && isUtility && !isJavaRemote) ||
|
||||
(expectUtility === false && isRDD && !isJavaRemote) ||
|
||||
(expectContent === true && isContent);
|
||||
(isExpected && !isJavaRemote && !expectContent && !expectJava) || // Running in Utility/RDD
|
||||
(expectJava && !isExpected && isJavaRemote) || // Running in Java remote
|
||||
(expectContent && !isExpected && !isJavaRemote); // Running in Content
|
||||
|
||||
ok(
|
||||
isOk,
|
||||
`playback ${audio.src} was from expected decoder ${audioDecoderName}`
|
||||
`playback ${audio.src} was from decoder '${audioDecoderName}', expected '${expectedProcess}'`
|
||||
);
|
||||
|
||||
if (isOk) {
|
||||
|
@ -120,7 +171,7 @@ async function checkAudioDecoder(expectUtility, expectContent = false) {
|
|||
|
||||
async function runMochitestUtilityAudio(
|
||||
src,
|
||||
{ expectUtility, expectContent = false } = {}
|
||||
{ expectUtility, expectContent = false, expectJava = false } = {}
|
||||
) {
|
||||
info(`Add media: ${src}`);
|
||||
await createAudioElement(src);
|
||||
|
@ -128,7 +179,7 @@ async function runMochitestUtilityAudio(
|
|||
ok(audio, "Found an audio element created");
|
||||
|
||||
info(`Play media: ${src}`);
|
||||
await checkAudioDecoder(expectUtility, expectContent);
|
||||
await checkAudioDecoder(expectUtility, expectContent, expectJava);
|
||||
|
||||
info(`Pause media: ${src}`);
|
||||
await audio.pause();
|
||||
|
|
|
@ -12,14 +12,25 @@
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
(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 [
|
||||
"small-shot.ogg",
|
||||
"small-shot.mp3",
|
||||
"small-shot.m4a",
|
||||
"small-shot.flac",
|
||||
]) {
|
||||
try {
|
||||
await runMochitestUtilityAudio(src, { expectUtility: false, expectContent: true });
|
||||
await runMochitestUtilityAudio(src, { expectUtility: "", expectContent: false, expectJava: true });
|
||||
} catch (ex) {
|
||||
ok(false, "Failure");
|
||||
}
|
||||
|
|
|
@ -12,13 +12,15 @@
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
(async function() {
|
||||
for (let src of [
|
||||
"small-shot.ogg",
|
||||
"small-shot.mp3",
|
||||
"small-shot.flac"
|
||||
]) {
|
||||
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: true, expectContent: false });
|
||||
await runMochitestUtilityAudio(src, { expectUtility: expectations[platform], expectContent: false, expectJava: false });
|
||||
} catch (ex) {
|
||||
ok(false, "Failure");
|
||||
}
|
||||
|
@ -29,7 +31,7 @@ SimpleTest.waitForExplicitFinish();
|
|||
"small-shot.m4a",
|
||||
]) {
|
||||
try {
|
||||
await runMochitestUtilityAudio(src, { expectUtility: false, expectContent: true });
|
||||
await runMochitestUtilityAudio(src, { expectUtility: "", expectContent: false, expectJava: true });
|
||||
} catch (ex) {
|
||||
ok(false, "Failure");
|
||||
}
|
||||
|
|
|
@ -89,8 +89,14 @@ void SandboxTestingChild::Bind(Endpoint<PSandboxTestingChild>&& aEndpoint) {
|
|||
RunTestsGenericUtility(this);
|
||||
break;
|
||||
|
||||
case ipc::SandboxingKind::UTILITY_AUDIO_DECODING:
|
||||
RunTestsUtilityAudioDecoder(this);
|
||||
case ipc::SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC:
|
||||
#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;
|
||||
|
||||
default:
|
||||
|
|
|
@ -764,7 +764,8 @@ void RunTestsGenericUtility(SandboxTestingChild* child) {
|
|||
#endif // XP_MACOSX
|
||||
}
|
||||
|
||||
void RunTestsUtilityAudioDecoder(SandboxTestingChild* child) {
|
||||
void RunTestsUtilityAudioDecoder(SandboxTestingChild* child,
|
||||
ipc::SandboxingKind aSandbox) {
|
||||
MOZ_ASSERT(child, "No SandboxTestingChild*?");
|
||||
|
||||
RunGenericTests(child);
|
||||
|
@ -796,7 +797,9 @@ void RunTestsUtilityAudioDecoder(SandboxTestingChild* child) {
|
|||
# elif XP_MACOSX // XP_LINUX
|
||||
RunMacTestLaunchProcess(child);
|
||||
RunMacTestWindowServer(child);
|
||||
RunMacTestAudioAPI(child, true);
|
||||
RunMacTestAudioAPI(
|
||||
child,
|
||||
aSandbox == ipc::SandboxingKind::UTILITY_AUDIO_DECODING_APPLE_MEDIA);
|
||||
# endif // XP_MACOSX
|
||||
#else // XP_UNIX
|
||||
# ifdef XP_WIN
|
||||
|
|
|
@ -754,7 +754,7 @@ void SetUtilitySandbox(int aBroker, ipc::SandboxingKind aKind) {
|
|||
policy = GetUtilitySandboxPolicy(sBroker);
|
||||
break;
|
||||
|
||||
case ipc::SandboxingKind::UTILITY_AUDIO_DECODING:
|
||||
case ipc::SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC:
|
||||
policy = GetUtilityAudioDecoderSandboxPolicy(sBroker);
|
||||
break;
|
||||
|
||||
|
|
|
@ -288,11 +288,12 @@ bool StartMacSandbox(MacSandboxInfo const& aInfo, std::string& aErrorMessage) {
|
|||
|
||||
switch (aInfo.utilityKind) {
|
||||
case ipc::SandboxingKind::GENERIC_UTILITY:
|
||||
case ipc::SandboxingKind::UTILITY_AUDIO_DECODING_GENERIC:
|
||||
// Nothing to do here specifically
|
||||
break;
|
||||
|
||||
case ipc::SandboxingKind::UTILITY_AUDIO_DECODING: {
|
||||
profile.append(SandboxPolicyUtilityAudioDecoderAddend);
|
||||
case ipc::SandboxingKind::UTILITY_AUDIO_DECODING_APPLE_MEDIA: {
|
||||
profile.append(SandboxPolicyUtilityAudioDecoderAppleMediaAddend);
|
||||
params.push_back("MAC_OS_VERSION");
|
||||
params.push_back(combinedVersion.c_str());
|
||||
} break;
|
||||
|
|
|
@ -68,8 +68,9 @@ static const char SandboxPolicyUtility[] = R"SANDBOX_LITERAL(
|
|||
(global-name "com.apple.coreservices.launchservicesd"))
|
||||
)SANDBOX_LITERAL";
|
||||
|
||||
static const char SandboxPolicyUtilityAudioDecoderAddend[] = R"SANDBOX_LITERAL(
|
||||
; For Utility AudioDecoder
|
||||
static const char SandboxPolicyUtilityAudioDecoderAppleMediaAddend[] =
|
||||
R"SANDBOX_LITERAL(
|
||||
; For Utility AudioDecoder AppleMedia codecs
|
||||
(define macosVersion (string->number (param "MAC_OS_VERSION")))
|
||||
(if (>= macosVersion 1013)
|
||||
(allow mach-lookup
|
||||
|
|
|
@ -1273,7 +1273,7 @@ bool SandboxBroker::SetSecurityLevelForUtilityProcess(
|
|||
"SetJobLevel should never fail with these arguments, what happened?");
|
||||
|
||||
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;
|
||||
}
|
||||
result = mPolicy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
|
||||
|
@ -1339,10 +1339,14 @@ bool SandboxBroker::SetSecurityLevelForUtilityProcess(
|
|||
// Investigate also why it crashes (no idea where exactly) for MinGW64 builds
|
||||
//
|
||||
// TODO: Bug 1773005 - AAC seems to not work on Windows < 1703
|
||||
if (IsWin10CreatorsUpdateOrLater()) {
|
||||
#if defined(_M_X64) && !defined(__MINGW64__)
|
||||
if (aSandbox != mozilla::ipc::SandboxingKind::UTILITY_AUDIO_DECODING_WMF) {
|
||||
mitigations |= sandbox::MITIGATION_DYNAMIC_CODE_DISABLE;
|
||||
} else {
|
||||
if (IsWin10CreatorsUpdateOrLater()) {
|
||||
#if defined(_M_X64) && !defined(__MINGW64__)
|
||||
mitigations |= sandbox::MITIGATION_DYNAMIC_CODE_DISABLE;
|
||||
#endif // defined(_M_X64) && !defined(__MINGW64__)
|
||||
}
|
||||
}
|
||||
|
||||
if (exceptionModules.isNothing()) {
|
||||
|
@ -1373,7 +1377,8 @@ bool SandboxBroker::SetSecurityLevelForUtilityProcess(
|
|||
|
||||
switch (aSandbox) {
|
||||
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?
|
||||
break;
|
||||
|
||||
|
|
|
@ -864,8 +864,16 @@ var View = {
|
|||
let fluentName;
|
||||
let fluentArgs = {};
|
||||
switch (data.actorName) {
|
||||
case "audioDecoder":
|
||||
fluentName = "about-processes-utility-actor-audio-decoder";
|
||||
case "audioDecoder_Generic":
|
||||
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;
|
||||
|
||||
default:
|
||||
|
|
|
@ -609,7 +609,7 @@ async function testAboutProcessesWithConfig({ showAllFrames, showThreads }) {
|
|||
row.classList.contains("process") &&
|
||||
row.nextSibling &&
|
||||
row.nextSibling.classList.contains("actor") &&
|
||||
row.nextSibling.actor.actorName === "audioDecoder",
|
||||
row.nextSibling.actor.actorName === "audioDecoder_Generic",
|
||||
},
|
||||
];
|
||||
for (let finder of processesToBeFound) {
|
||||
|
|
|
@ -70,7 +70,9 @@ enum class ProcType {
|
|||
|
||||
enum class UtilityActorName {
|
||||
Unknown,
|
||||
AudioDecoder,
|
||||
AudioDecoder_Generic,
|
||||
AudioDecoder_AppleMedia,
|
||||
AudioDecoder_WMF
|
||||
};
|
||||
|
||||
/* 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.
|
||||
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-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)
|
||||
## Variables:
|
||||
|
|
Загрузка…
Ссылка в новой задаче