зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1692385 move SourceListener logic needed for testing window existence into EnumerateDevicesImpl() r=pehrsons
so that EnumerateDevicesImpl() callers don't need to care about this. This also provides a SourceListener::Stop() call to fix a leak from the logic in GetSinkDevice(). Differential Revision: https://phabricator.services.mozilla.com/D105252
This commit is contained in:
Родитель
fdc299027d
Коммит
43c550087c
|
@ -2644,7 +2644,7 @@ RefPtr<MediaManager::StreamPromise> MediaManager::GetUserMedia(
|
|||
|
||||
RefPtr<MediaManager> self = this;
|
||||
auto devices = MakeRefPtr<MediaDeviceSetRefCnt>();
|
||||
return EnumerateDevicesImpl(windowID, videoType, audioType,
|
||||
return EnumerateDevicesImpl(aWindow, videoType, audioType,
|
||||
MediaSinkEnum::Other, videoEnumerationType,
|
||||
audioEnumerationType, true, devices)
|
||||
->Then(
|
||||
|
@ -2898,21 +2898,21 @@ already_AddRefed<nsIWritableVariant> MediaManager::ToJSArray(
|
|||
}
|
||||
|
||||
RefPtr<MediaManager::MgrPromise> MediaManager::EnumerateDevicesImpl(
|
||||
uint64_t aWindowId, MediaSourceEnum aVideoInputType,
|
||||
nsPIDOMWindowInner* aWindow, MediaSourceEnum aVideoInputType,
|
||||
MediaSourceEnum aAudioInputType, MediaSinkEnum aAudioOutputType,
|
||||
DeviceEnumerationType aVideoInputEnumType,
|
||||
DeviceEnumerationType aAudioInputEnumType, bool aForceNoPermRequest,
|
||||
const RefPtr<MediaDeviceSetRefCnt>& aOutDevices) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
LOG("%s: aWindowId=%" PRIu64 ", aVideoInputType=%" PRIu8
|
||||
uint64_t windowId = aWindow->WindowID();
|
||||
LOG("%s: windowId=%" PRIu64 ", aVideoInputType=%" PRIu8
|
||||
", aAudioInputType=%" PRIu8 ", aVideoInputEnumType=%" PRIu8
|
||||
", aAudioInputEnumType=%" PRIu8,
|
||||
__func__, aWindowId, static_cast<uint8_t>(aVideoInputType),
|
||||
__func__, windowId, static_cast<uint8_t>(aVideoInputType),
|
||||
static_cast<uint8_t>(aAudioInputType),
|
||||
static_cast<uint8_t>(aVideoInputEnumType),
|
||||
static_cast<uint8_t>(aAudioInputEnumType));
|
||||
auto* window = nsGlobalWindowInner::GetInnerWindowWithId(aWindowId);
|
||||
|
||||
// To get a device list anonymized for a particular origin, we must:
|
||||
// 1. Get an origin-key (for either regular or private browsing)
|
||||
|
@ -2920,7 +2920,7 @@ RefPtr<MediaManager::MgrPromise> MediaManager::EnumerateDevicesImpl(
|
|||
// 3. Anonymize the raw list with the origin-key.
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
nsGlobalWindowInner::Cast(window)->GetPrincipal();
|
||||
nsGlobalWindowInner::Cast(aWindow)->GetPrincipal();
|
||||
MOZ_ASSERT(principal);
|
||||
|
||||
ipc::PrincipalInfo principalInfo;
|
||||
|
@ -2931,7 +2931,17 @@ RefPtr<MediaManager::MgrPromise> MediaManager::EnumerateDevicesImpl(
|
|||
__func__);
|
||||
}
|
||||
|
||||
bool persist = IsActivelyCapturingOrHasAPermission(aWindowId);
|
||||
// Add the window id here to check for that and abort silently if no longer
|
||||
// exists.
|
||||
RefPtr<GetUserMediaWindowListener> windowListener =
|
||||
GetOrMakeWindowListener(aWindow);
|
||||
MOZ_ASSERT(windowListener);
|
||||
// Create an inactive SourceListener to act as a placeholder, so the
|
||||
// window listener doesn't clean itself up until we're done.
|
||||
auto sourceListener = MakeRefPtr<SourceListener>();
|
||||
windowListener->Register(sourceListener);
|
||||
|
||||
bool persist = IsActivelyCapturingOrHasAPermission(windowId);
|
||||
|
||||
// GetPrincipalKey is an async API that returns a promise. We use .Then() to
|
||||
// pass in a lambda to run back on this same thread later once
|
||||
|
@ -2941,20 +2951,20 @@ RefPtr<MediaManager::MgrPromise> MediaManager::EnumerateDevicesImpl(
|
|||
return media::GetPrincipalKey(principalInfo, persist)
|
||||
->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[aWindowId, aVideoInputType, aAudioInputType, aAudioOutputType,
|
||||
[windowId, aVideoInputType, aAudioInputType, aAudioOutputType,
|
||||
aVideoInputEnumType, aAudioInputEnumType, aForceNoPermRequest,
|
||||
aOutDevices, originKey](const nsCString& aOriginKey) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
originKey->Assign(aOriginKey);
|
||||
MediaManager* mgr = MediaManager::GetIfExists();
|
||||
MOZ_ASSERT(mgr);
|
||||
if (!mgr->IsWindowStillActive(aWindowId)) {
|
||||
if (!mgr->IsWindowStillActive(windowId)) {
|
||||
return MgrPromise::CreateAndReject(
|
||||
MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
|
||||
__func__);
|
||||
}
|
||||
return mgr->EnumerateRawDevices(
|
||||
aWindowId, aVideoInputType, aAudioInputType, aAudioOutputType,
|
||||
windowId, aVideoInputType, aAudioInputType, aAudioOutputType,
|
||||
aVideoInputEnumType, aAudioInputEnumType, aForceNoPermRequest,
|
||||
aOutDevices);
|
||||
},
|
||||
|
@ -2968,15 +2978,20 @@ RefPtr<MediaManager::MgrPromise> MediaManager::EnumerateDevicesImpl(
|
|||
})
|
||||
->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[aWindowId, originKey, aVideoInputEnumType, aAudioInputEnumType,
|
||||
aOutDevices](bool) {
|
||||
[windowId, sourceListener, originKey, aVideoInputEnumType,
|
||||
aAudioInputEnumType, aOutDevices](bool) {
|
||||
// Only run if window is still on our active list.
|
||||
MediaManager* mgr = MediaManager::GetIfExists();
|
||||
if (!mgr || !mgr->IsWindowStillActive(aWindowId)) {
|
||||
if (!mgr || !mgr->IsWindowStillActive(windowId)) {
|
||||
// The listener has already been removed if the window is no
|
||||
// longer active.
|
||||
MOZ_ASSERT(sourceListener->Stopped());
|
||||
return MgrPromise::CreateAndReject(
|
||||
MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
|
||||
__func__);
|
||||
}
|
||||
MOZ_ASSERT(!sourceListener->Stopped());
|
||||
sourceListener->Stop();
|
||||
|
||||
for (auto& device : *aOutDevices) {
|
||||
if (device->mKind == MediaDeviceKind::Audiooutput ||
|
||||
|
@ -2991,10 +3006,14 @@ RefPtr<MediaManager::MgrPromise> MediaManager::EnumerateDevicesImpl(
|
|||
MOZ_ALWAYS_TRUE(mgr->mDeviceIDs.put(std::move(id)));
|
||||
}
|
||||
}
|
||||
MediaManager::AnonymizeDevices(*aOutDevices, *originKey, aWindowId);
|
||||
MediaManager::AnonymizeDevices(*aOutDevices, *originKey, windowId);
|
||||
return MgrPromise::CreateAndResolve(false, __func__);
|
||||
},
|
||||
[](RefPtr<MediaMgrError>&& aError) {
|
||||
[sourceListener](RefPtr<MediaMgrError>&& aError) {
|
||||
// EnumerateDevicesImpl may fail if a new doc has been set, in which
|
||||
// case the OnNavigation() method should have removed all previous
|
||||
// active listeners.
|
||||
MOZ_ASSERT(sourceListener->Stopped());
|
||||
return MgrPromise::CreateAndReject(std::move(aError), __func__);
|
||||
});
|
||||
}
|
||||
|
@ -3008,16 +3027,8 @@ RefPtr<MediaManager::DevicesPromise> MediaManager::EnumerateDevices(
|
|||
"In shutdown"),
|
||||
__func__);
|
||||
}
|
||||
uint64_t windowId = aWindow->WindowID();
|
||||
Document* doc = aWindow->GetExtantDoc();
|
||||
MOZ_ASSERT(doc);
|
||||
RefPtr<GetUserMediaWindowListener> windowListener =
|
||||
GetOrMakeWindowListener(aWindow);
|
||||
MOZ_ASSERT(windowListener);
|
||||
// Create an inactive SourceListener to act as a placeholder, so the
|
||||
// window listener doesn't clean itself up until we're done.
|
||||
auto sourceListener = MakeRefPtr<SourceListener>();
|
||||
windowListener->Register(sourceListener);
|
||||
|
||||
DeviceEnumerationType videoEnumerationType = DeviceEnumerationType::Normal;
|
||||
DeviceEnumerationType audioEnumerationType = DeviceEnumerationType::Normal;
|
||||
|
@ -3076,22 +3087,15 @@ RefPtr<MediaManager::DevicesPromise> MediaManager::EnumerateDevices(
|
|||
}
|
||||
}
|
||||
|
||||
return EnumerateDevicesImpl(windowId, videoType, audioType, audioOutputType,
|
||||
return EnumerateDevicesImpl(aWindow, videoType, audioType, audioOutputType,
|
||||
videoEnumerationType, audioEnumerationType, false,
|
||||
devices)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[sourceListener, devices](bool) {
|
||||
// The listener may have already been removed if the window is no
|
||||
// longer active.
|
||||
sourceListener->Stop();
|
||||
[devices](bool) {
|
||||
return DevicesPromise::CreateAndResolve(devices, __func__);
|
||||
},
|
||||
[sourceListener](RefPtr<MediaMgrError>&& aError) {
|
||||
// EnumerateDevices may fail if a new doc has been set, in which
|
||||
// case the OnNavigation() method should have removed all previous
|
||||
// active listeners.
|
||||
MOZ_ASSERT(sourceListener->Stopped());
|
||||
[](RefPtr<MediaMgrError>&& aError) {
|
||||
return DevicesPromise::CreateAndReject(std::move(aError), __func__);
|
||||
});
|
||||
}
|
||||
|
@ -3135,19 +3139,9 @@ RefPtr<SinkInfoPromise> MediaManager::GetSinkDevice(nsPIDOMWindowInner* aWindow,
|
|||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aWindow);
|
||||
|
||||
// We have to add the window id here because enumerate methods
|
||||
// check for that and abort silently if it does not exist.
|
||||
RefPtr<GetUserMediaWindowListener> windowListener =
|
||||
GetOrMakeWindowListener(aWindow);
|
||||
MOZ_ASSERT(windowListener);
|
||||
// Create an inactive SourceListener to act as a placeholder, so the
|
||||
// window listener doesn't clean itself up until we're done.
|
||||
auto sourceListener = MakeRefPtr<SourceListener>();
|
||||
windowListener->Register(sourceListener);
|
||||
|
||||
bool isSecure = aWindow->IsSecureContext();
|
||||
auto devices = MakeRefPtr<MediaDeviceSetRefCnt>();
|
||||
return EnumerateDevicesImpl(aWindow->WindowID(), MediaSourceEnum::Other,
|
||||
return EnumerateDevicesImpl(aWindow, MediaSourceEnum::Other,
|
||||
MediaSourceEnum::Other, MediaSinkEnum::Speaker,
|
||||
DeviceEnumerationType::Normal,
|
||||
DeviceEnumerationType::Normal, true, devices)
|
||||
|
|
|
@ -307,7 +307,7 @@ class MediaManager final : public nsIMediaManagerService, public nsIObserver {
|
|||
const RefPtr<MediaDeviceSetRefCnt>& aOutDevices);
|
||||
|
||||
RefPtr<MgrPromise> EnumerateDevicesImpl(
|
||||
uint64_t aWindowId, dom::MediaSourceEnum aVideoInputType,
|
||||
nsPIDOMWindowInner* aWindow, dom::MediaSourceEnum aVideoInputType,
|
||||
dom::MediaSourceEnum aAudioInputType, MediaSinkEnum aAudioOutputType,
|
||||
DeviceEnumerationType aVideoInputEnumType,
|
||||
DeviceEnumerationType aAudioInputEnumType, bool aForceNoPermRequest,
|
||||
|
|
Загрузка…
Ссылка в новой задаче