зеркало из 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) {
|
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:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче