Diff
Modified: trunk/LayoutTests/ChangeLog (235085 => 235086)
--- trunk/LayoutTests/ChangeLog 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/LayoutTests/ChangeLog 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,3 +1,14 @@
+2018-08-20 Eric Carlson <[email protected]>
+
+ [MediaStream] Move capture device monitoring to WebKit
+ https://bugs.webkit.org/show_bug.cgi?id=188521
+ <rdar://problem/43251787>
+
+ Reviewed by Youenn Fablet.
+
+ * fast/mediastream/device-change-event-2-expected.txt: Updated.
+ * fast/mediastream/device-change-event-2.html: Updated.
+
2018-08-20 Rob Buis <[email protected]>
Throw an exception if window.open() gets passed a URL that cannot be parsed
Modified: trunk/LayoutTests/fast/mediastream/device-change-event-2-expected.txt (235085 => 235086)
--- trunk/LayoutTests/fast/mediastream/device-change-event-2-expected.txt 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/LayoutTests/fast/mediastream/device-change-event-2-expected.txt 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,3 +1,6 @@
PASS 'devicechange' event fired when device list changes
+PASS 'devicechange' events fired quickly are coalesced
+PASS 'devicechange' event is not fired when the document doesn't has focus or permission to capture
+PASS 'devicechange' event is fired when the document doesn't has focus but has permission to capture
Modified: trunk/LayoutTests/fast/mediastream/device-change-event-2.html (235085 => 235086)
--- trunk/LayoutTests/fast/mediastream/device-change-event-2.html 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/LayoutTests/fast/mediastream/device-change-event-2.html 2018-08-20 18:10:22 UTC (rev 235086)
@@ -6,8 +6,9 @@
<script src=""
<script src=""
<script>
- let deviceIds = [];
- promise_test(async (test) => {
+ let stream = null;
+
+ let setup = async (test) => {
if (!window.testRunner)
return Promise.reject("test requires internal API");
@@ -14,9 +15,17 @@
test.add_cleanup(() => { testRunner.resetMockMediaDevices(); });
testRunner.setUserMediaPermission(true);
+
+ stream = null;
+ }
- await navigator.mediaDevices.getUserMedia({ audio:true, video:true });
+ promise_test(async (test) => {
+
+ await setup(test);
+ await navigator.mediaDevices.getUserMedia({ audio:true, video:true })
+ .then(s => stream = s)
+
let devices = await navigator.mediaDevices.enumerateDevices();
assert_true(!!devices.length, "check there are some devices");
@@ -29,7 +38,7 @@
await new Promise((resolve, reject) => {
navigator.mediaDevices._ondevicechange_ = resolve;
setTimeout(() => {
- console.log("event 1 taking a long time");
+ console.log("event 1 took too long");
resolve();
}, 5000);
testRunner.addMockCameraDevice("id1", "my camera");
@@ -41,7 +50,7 @@
await new Promise((resolve, reject) => {
navigator.mediaDevices._ondevicechange_ = resolve;
setTimeout(() => {
- console.log("event 2 taking a long time");
+ console.log("event 2 took too long");
resolve();
}, 5000);
testRunner.addMockMicrophoneDevice("id2", "my mic");
@@ -51,6 +60,102 @@
assert_equals(devices[0].label, "my mic");
}, "'devicechange' event fired when device list changes");
+
+ promise_test(async (test) => {
+
+ await setup(test);
+
+ let eventCount = 0;
+ await new Promise((resolve, reject) => {
+ navigator.mediaDevices._ondevicechange_ = (evt) => {
+ ++eventCount;
+ setTimeout(() => {
+ resolve();
+ }, 500);
+ }
+
+ setTimeout(() => {
+ console.log("navigator.mediaDevices.ondevicechange took too long");
+ resolve();
+ }, 4000);
+
+ testRunner.addMockMicrophoneDevice("id4", "microphone 3");
+ testRunner.addMockMicrophoneDevice("id5", "microphone 4");
+ });
+ assert_equals(eventCount, 1, "one event fired");
+
+ }, "'devicechange' events fired quickly are coalesced");
+
+
+ promise_test(async (test) => {
+
+ await setup(test);
+
+ await new Promise((resolve, reject) => {
+ let timeout = setTimeout(() => {
+ console.log("window.onblur took too long");
+ resolve();
+ }, 5000);
+
+ window._onblur_ = () => {
+ clearTimeout(timeout);
+ resolve();
+ }
+
+ internals.setPageIsFocusedAndActive(false);
+ });
+
+ await new Promise((resolve, reject) => {
+ assert_false(document.hasFocus(), "document.hasFocus()");
+
+ navigator.mediaDevices._ondevicechange_ = () => {
+ assert_true(document.hasFocus(), "devicechange should only fire when the document is focused and active");
+ resolve();
+ };
+
+ setTimeout(() => {
+ internals.setPageIsFocusedAndActive(true);
+ }, 200);
+
+ testRunner.addMockMicrophoneDevice("id3", "microphone 2");
+ });
+
+ }, "'devicechange' event is not fired when the document doesn't has focus or permission to capture");
+
+ promise_test(async (test) => {
+
+ await setup(test);
+
+ await navigator.mediaDevices.getUserMedia({ audio:true, video:true })
+ .then(s => stream = s);
+
+ await new Promise((resolve, reject) => {
+ let timeout = setTimeout(() => {
+ console.log("window.onblur took too long");
+ resolve();
+ }, 5000);
+
+ window._onblur_ = () => {
+ clearTimeout(timeout);
+ resolve();
+ }
+
+ internals.setPageIsFocusedAndActive(false);
+ });
+
+ await new Promise((resolve, reject) => {
+ assert_false(document.hasFocus(), "document.hasFocus()");
+
+ navigator.mediaDevices._ondevicechange_ = () => {
+ assert_false(document.hasFocus(), "devicechange should fire when the document is not focused but can capture");
+ resolve();
+ };
+
+ testRunner.addMockMicrophoneDevice("id3", "microphone 2");
+ });
+
+ }, "'devicechange' event is fired when the document doesn't has focus but has permission to capture");
+
</script>
</head>
<body>
Modified: trunk/Source/WebCore/ChangeLog (235085 => 235086)
--- trunk/Source/WebCore/ChangeLog 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/ChangeLog 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,3 +1,67 @@
+2018-08-20 Eric Carlson <[email protected]>
+
+ [MediaStream] Move capture device monitoring to WebKit
+ https://bugs.webkit.org/show_bug.cgi?id=188521
+ <rdar://problem/43251787>
+
+ Reviewed by Youenn Fablet.
+
+ No new tests, updated fast/mediastream/device-change-event-2.html for the changes.
+
+ * Modules/mediastream/MediaDevices.cpp:
+ (WebCore::MediaDevices::MediaDevices): Device change listener is added in addEventListener.
+ (WebCore::MediaDevices::stop): Device change listener is on the user media controller.
+ (WebCore::MediaDevices::addEventListener): Add the device change listener only once the first
+ event handler is added.
+ * Modules/mediastream/MediaDevices.h:
+
+ * Modules/mediastream/UserMediaClient.h:
+ * Modules/mediastream/UserMediaController.h:
+ (WebCore::UserMediaController::addDeviceChangeObserver): Pass through to the client.
+ (WebCore::UserMediaController::removeDeviceChangeObserver): Ditto.
+
+ * platform/mediastream/CaptureDeviceManager.cpp:
+ (CaptureDeviceManager::deviceChanged): Notify RealtimeMediaSourceCenter.
+ (nextObserverToken): Deleted.
+ (CaptureDeviceManager::addCaptureDeviceChangedObserver): Deleted.
+ (CaptureDeviceManager::removeCaptureDeviceChangedObserver): Deleted.
+ * platform/mediastream/CaptureDeviceManager.h:
+
+ * platform/mediastream/RealtimeMediaSourceCenter.cpp:
+ (WebCore::RealtimeMediaSourceCenter::setDevicesChangedObserver):
+ (WebCore::RealtimeMediaSourceCenter::captureDevicesChanged):
+ (WebCore::observerMap): Deleted.
+ (WebCore::RealtimeMediaSourceCenter::addDevicesChangedObserver): Deleted.
+ (WebCore::RealtimeMediaSourceCenter::removeDevicesChangedObserver): Deleted.
+ * platform/mediastream/RealtimeMediaSourceCenter.h:
+
+ * platform/mediastream/ios/AVAudioSessionCaptureDeviceManager.mm:
+ (WebCore::AVAudioSessionCaptureDeviceManager::refreshAudioCaptureDevices): Call base class.
+
+ * platform/mediastream/mac/AVCaptureDeviceManager.mm:
+ (WebCore::AVCaptureDeviceManager::deviceConnected): Ditto.
+ (WebCore::AVCaptureDeviceManager::deviceDisconnected): Ditto.
+
+ * platform/mediastream/mac/CoreAudioCaptureDeviceManager.cpp:
+ (WebCore::deviceHasInputStreams): Drive-by fix, check the number of buffers to see if the
+ device has input streams.
+ (WebCore::CoreAudioCaptureDeviceManager::coreAudioCaptureDevices): Use new bool parameter
+ added to refreshAudioCaptureDevices so we won't trigger a device change event on the first scan.
+ (WebCore::CoreAudioCaptureDeviceManager::refreshAudioCaptureDevices): Add param.
+ (WebCore::CoreAudioCaptureDeviceManager::devicesChanged): Use new param.
+ * platform/mediastream/mac/CoreAudioCaptureDeviceManager.h:
+
+ * platform/mock/MockRealtimeMediaSourceCenter.cpp:
+ (WebCore::MockRealtimeMediaSourceCenter::setDevices): Don't need to call captureDevicesChanged,
+ it is done in the UI process.
+ (WebCore::MockRealtimeMediaSourceCenter::addDevice): Ditto.
+ (WebCore::MockRealtimeMediaSourceCenter::removeDevice): Ditto.
+
+ * testing/InternalSettings.cpp:
+ (WebCore::InternalSettings::setPageIsFocusedAndActive): New, used by updated test.
+ * testing/Internals.h:
+ * testing/Internals.idl:
+
2018-08-20 Rob Buis <[email protected]>
Throw an exception if window.open() gets passed a URL that cannot be parsed
Modified: trunk/Source/WebCore/Modules/mediastream/MediaDevices.cpp (235085 => 235086)
--- trunk/Source/WebCore/Modules/mediastream/MediaDevices.cpp 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/Modules/mediastream/MediaDevices.cpp 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2015 Ericsson AB. All rights reserved.
- * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -41,6 +41,7 @@
#include "MediaTrackSupportedConstraints.h"
#include "RealtimeMediaSourceSettings.h"
#include "RuntimeEnabledFeatures.h"
+#include "UserMediaController.h"
#include "UserMediaRequest.h"
#include <wtf/RandomNumber.h>
@@ -51,17 +52,6 @@
, m_scheduledEventTimer(*this, &MediaDevices::scheduledEventTimerFired)
, m_eventNames(eventNames())
{
- m_deviceChangedToken = RealtimeMediaSourceCenter::singleton().addDevicesChangedObserver([weakThis = makeWeakPtr(*this), this]() {
-
- if (!weakThis)
- return;
-
- // FIXME: We should only dispatch an event if the user has been granted access to the type of
- // device that was added or removed.
- if (!m_scheduledEventTimer.isActive())
- m_scheduledEventTimer.startOneShot(Seconds(randomNumber() / 2));
- });
-
suspendIfNeeded();
static_assert(static_cast<size_t>(MediaDevices::DisplayCaptureSurfaceType::Monitor) == static_cast<size_t>(RealtimeMediaSourceSettings::DisplaySurfaceType::Monitor), "MediaDevices::DisplayCaptureSurfaceType::Monitor is not equal to RealtimeMediaSourceSettings::DisplaySurfaceType::Monitor as expected");
@@ -74,8 +64,12 @@
void MediaDevices::stop()
{
- if (m_deviceChangedToken)
- RealtimeMediaSourceCenter::singleton().removeDevicesChangedObserver(m_deviceChangedToken);
+ if (m_deviceChangeToken) {
+ auto* document = this->document();
+ auto* controller = document ? UserMediaController::from(document->page()) : nullptr;
+ if (document && controller)
+ controller->removeDeviceChangeObserver(m_deviceChangeToken);
+ }
}
Ref<MediaDevices> MediaDevices::create(Document& document)
@@ -181,6 +175,27 @@
return true;
}
+bool MediaDevices::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options)
+{
+ if (!m_listeningForDeviceChanges && eventType == eventNames().devicechangeEvent) {
+ auto* document = this->document();
+ auto* controller = document ? UserMediaController::from(document->page()) : nullptr;
+ if (document && controller) {
+ m_listeningForDeviceChanges = true;
+
+ m_deviceChangeToken = controller->addDeviceChangeObserver([weakThis = makeWeakPtr(*this), this]() {
+
+ if (!weakThis || m_scheduledEventTimer.isActive())
+ return;
+
+ m_scheduledEventTimer.startOneShot(Seconds(randomNumber() / 2));
+ });
+ }
+ }
+
+ return EventTargetWithInlineData::addEventListener(eventType, WTFMove(listener), options);
+}
+
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
Modified: trunk/Source/WebCore/Modules/mediastream/MediaDevices.h (235085 => 235086)
--- trunk/Source/WebCore/Modules/mediastream/MediaDevices.h 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/Modules/mediastream/MediaDevices.h 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2015 Ericsson AB. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -41,11 +41,11 @@
#include "MediaTrackConstraints.h"
#include "RealtimeMediaSourceCenter.h"
#include "Timer.h"
+#include "UserMediaClient.h"
#include <wtf/WeakPtr.h>
namespace WebCore {
-class Document;
class MediaDeviceInfo;
class MediaStream;
@@ -85,6 +85,7 @@
explicit MediaDevices(Document&);
void scheduledEventTimerFired();
+ bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override;
friend class JSMediaDevicesOwner;
@@ -101,8 +102,9 @@
void derefEventTarget() final { deref(); }
Timer m_scheduledEventTimer;
- RealtimeMediaSourceCenter::DevicesChangedObserverToken m_deviceChangedToken;
+ UserMediaClient::DeviceChangeObserverToken m_deviceChangeToken;
const EventNames& m_eventNames; // Need to cache this so we can use it from GC threads.
+ bool m_listeningForDeviceChanges { false };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/mediastream/UserMediaClient.h (235085 => 235086)
--- trunk/Source/WebCore/Modules/mediastream/UserMediaClient.h 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaClient.h 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 Ericsson AB. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,6 +33,8 @@
#if ENABLE(MEDIA_STREAM)
+#include <wtf/ObjectIdentifier.h>
+
namespace WebCore {
class MediaDevicesEnumerationRequest;
@@ -49,6 +51,11 @@
virtual void enumerateMediaDevices(MediaDevicesEnumerationRequest&) = 0;
virtual void cancelMediaDevicesEnumerationRequest(MediaDevicesEnumerationRequest&) = 0;
+ enum DeviceChangeObserverTokenType { };
+ using DeviceChangeObserverToken = ObjectIdentifier<DeviceChangeObserverTokenType>;
+ virtual DeviceChangeObserverToken addDeviceChangeObserver(WTF::Function<void()>&&) = 0;
+ virtual void removeDeviceChangeObserver(DeviceChangeObserverToken) = 0;
+
protected:
virtual ~UserMediaClient() = default;
};
Modified: trunk/Source/WebCore/Modules/mediastream/UserMediaController.h (235085 => 235086)
--- trunk/Source/WebCore/Modules/mediastream/UserMediaController.h 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaController.h 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -48,6 +48,9 @@
void enumerateMediaDevices(MediaDevicesEnumerationRequest&);
void cancelMediaDevicesEnumerationRequest(MediaDevicesEnumerationRequest&);
+ UserMediaClient::DeviceChangeObserverToken addDeviceChangeObserver(WTF::Function<void()>&&);
+ void removeDeviceChangeObserver(UserMediaClient::DeviceChangeObserverToken);
+
WEBCORE_EXPORT static const char* supplementName();
static UserMediaController* from(Page* page) { return static_cast<UserMediaController*>(Supplement<Page>::from(page, supplementName())); }
@@ -75,6 +78,16 @@
m_client->cancelMediaDevicesEnumerationRequest(request);
}
+inline UserMediaClient::DeviceChangeObserverToken UserMediaController::addDeviceChangeObserver(WTF::Function<void()>&& observer)
+{
+ return m_client->addDeviceChangeObserver(WTFMove(observer));
+}
+
+inline void UserMediaController::removeDeviceChangeObserver(UserMediaClient::DeviceChangeObserverToken token)
+{
+ m_client->removeDeviceChangeObserver(token);
+}
+
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
Modified: trunk/Source/WebCore/page/Page.h (235085 => 235086)
--- trunk/Source/WebCore/page/Page.h 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/page/Page.h 2018-08-20 18:10:22 UTC (rev 235086)
@@ -434,8 +434,8 @@
void setIsRestoringCachedPage(bool value) { m_isRestoringCachedPage = value; }
bool isRestoringCachedPage() const { return m_isRestoringCachedPage; }
- void addActivityStateChangeObserver(ActivityStateChangeObserver&);
- void removeActivityStateChangeObserver(ActivityStateChangeObserver&);
+ WEBCORE_EXPORT void addActivityStateChangeObserver(ActivityStateChangeObserver&);
+ WEBCORE_EXPORT void removeActivityStateChangeObserver(ActivityStateChangeObserver&);
WEBCORE_EXPORT void suspendScriptedAnimations();
WEBCORE_EXPORT void resumeScriptedAnimations();
Modified: trunk/Source/WebCore/platform/mediastream/CaptureDeviceManager.cpp (235085 => 235086)
--- trunk/Source/WebCore/platform/mediastream/CaptureDeviceManager.cpp 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/platform/mediastream/CaptureDeviceManager.cpp 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -50,24 +50,14 @@
return { };
}
-static CaptureDeviceManager::ObserverToken nextObserverToken()
+void CaptureDeviceManager::deviceChanged()
{
- static CaptureDeviceManager::ObserverToken nextToken = 0;
- return ++nextToken;
-}
+ callOnMainThread([weakThis = makeWeakPtr(*this)] {
+ if (!weakThis)
+ return;
-CaptureDeviceManager::ObserverToken CaptureDeviceManager::addCaptureDeviceChangedObserver(CaptureDeviceChangedCallback&& observer)
-{
- auto token = nextObserverToken();
- m_observers.set(token, WTFMove(observer));
- return token;
+ RealtimeMediaSourceCenter::singleton().captureDevicesChanged();
+ });
}
-void CaptureDeviceManager::removeCaptureDeviceChangedObserver(ObserverToken token)
-{
- ASSERT(m_observers.contains(token));
- m_observers.remove(token);
-}
-
-
#endif // ENABLE(MEDIA_STREAM)
Modified: trunk/Source/WebCore/platform/mediastream/CaptureDeviceManager.h (235085 => 235086)
--- trunk/Source/WebCore/platform/mediastream/CaptureDeviceManager.h 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/platform/mediastream/CaptureDeviceManager.h 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,16 +29,12 @@
#include "CaptureDevice.h"
#include "RealtimeMediaSource.h"
+#include <wtf/WeakPtr.h>
namespace WebCore {
-class CaptureDeviceManager {
+class CaptureDeviceManager : public CanMakeWeakPtr<CaptureDeviceManager> {
public:
- using CaptureDeviceChangedCallback = WTF::Function<void()>;
- using ObserverToken = uint32_t;
- virtual ObserverToken addCaptureDeviceChangedObserver(CaptureDeviceChangedCallback&&);
- virtual void removeCaptureDeviceChangedObserver(ObserverToken);
-
virtual const Vector<CaptureDevice>& captureDevices() = 0;
virtual std::optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType, const String&) { return std::nullopt; }
@@ -45,7 +41,7 @@
protected:
virtual ~CaptureDeviceManager();
CaptureDevice captureDeviceFromPersistentID(const String& captureDeviceID);
- HashMap<ObserverToken, CaptureDeviceChangedCallback> m_observers;
+ void deviceChanged();
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp (235085 => 235086)
--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp 2018-08-20 18:10:22 UTC (rev 235086)
@@ -246,10 +246,8 @@
}
distance = std::min(distance, constraintDistance);
- if (widthConstraint->isMandatory()) {
- auto range = capabilities.width();
- width = widthConstraint->valueForCapabilityRange(size().width(), range.rangeMin().asInt, range.rangeMax().asInt);
- }
+ auto range = capabilities.width();
+ width = widthConstraint->valueForCapabilityRange(size().width(), range.rangeMin().asInt, range.rangeMax().asInt);
}
std::optional<int> height;
@@ -261,10 +259,8 @@
}
distance = std::min(distance, constraintDistance);
- if (heightConstraint->isMandatory()) {
- auto range = capabilities.height();
- height = heightConstraint->valueForCapabilityRange(size().height(), range.rangeMin().asInt, range.rangeMax().asInt);
- }
+ auto range = capabilities.height();
+ height = heightConstraint->valueForCapabilityRange(size().height(), range.rangeMin().asInt, range.rangeMax().asInt);
}
std::optional<double> frameRate;
@@ -276,10 +272,8 @@
}
distance = std::min(distance, constraintDistance);
- if (frameRateConstraint->isMandatory()) {
- auto range = capabilities.frameRate();
- frameRate = frameRateConstraint->valueForCapabilityRange(this->frameRate(), range.rangeMin().asDouble, range.rangeMax().asDouble);
- }
+ auto range = capabilities.frameRate();
+ frameRate = frameRateConstraint->valueForCapabilityRange(this->frameRate(), range.rangeMin().asDouble, range.rangeMax().asDouble);
}
// Each of the non-null values is supported individually, see if they all can be applied at the same time.
Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp (235085 => 235086)
--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2011 Ericsson AB. All rights reserved.
* Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -53,12 +53,6 @@
return override;
}
-static HashMap<unsigned, std::function<void()>>& observerMap()
-{
- static NeverDestroyed<HashMap<unsigned, std::function<void()>>> map;
- return map;
-}
-
RealtimeMediaSourceCenter& RealtimeMediaSourceCenter::singleton()
{
RealtimeMediaSourceCenter* override = mediaStreamCenterOverride();
@@ -199,25 +193,18 @@
return Exception { NotFoundError };
}
-RealtimeMediaSourceCenter::DevicesChangedObserverToken RealtimeMediaSourceCenter::addDevicesChangedObserver(std::function<void()>&& observer)
+void RealtimeMediaSourceCenter::setDevicesChangedObserver(std::function<void()>&& observer)
{
- static DevicesChangedObserverToken nextToken = 0;
- observerMap().set(++nextToken, WTFMove(observer));
- return nextToken;
+ ASSERT(isMainThread());
+ ASSERT(!m_deviceChangedObserver);
+ m_deviceChangedObserver = WTFMove(observer);
}
-void RealtimeMediaSourceCenter::removeDevicesChangedObserver(DevicesChangedObserverToken token)
-{
- bool wasRemoved = observerMap().remove(token);
- ASSERT_UNUSED(wasRemoved, wasRemoved);
-}
-
void RealtimeMediaSourceCenter::captureDevicesChanged()
{
- // Copy the hash map because the observer callback may call back in and modify the map.
- auto callbacks = observerMap();
- for (auto& it : callbacks)
- it.value();
+ ASSERT(isMainThread());
+ if (m_deviceChangedObserver)
+ m_deviceChangedObserver();
}
void RealtimeMediaSourceCenter::validateRequestConstraints(ValidConstraintsHandler&& validHandler, InvalidConstraintsHandler&& invalidHandler, const MediaStreamRequest& request, String&& deviceIdentifierHashSalt)
Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h (235085 => 235086)
--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2011 Ericsson AB. All rights reserved.
* Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -85,22 +85,22 @@
WEBCORE_EXPORT CaptureDevice captureDeviceWithUniqueID(const String& id, const String& hashSalt);
WEBCORE_EXPORT ExceptionOr<void> setDeviceEnabled(const String&, bool);
- using DevicesChangedObserverToken = unsigned;
- DevicesChangedObserverToken addDevicesChangedObserver(std::function<void()>&&);
- void removeDevicesChangedObserver(DevicesChangedObserverToken);
+ WEBCORE_EXPORT void setDevicesChangedObserver(std::function<void()>&&);
void setVideoCapturePageState(bool, bool);
+ void captureDevicesChanged();
+
protected:
RealtimeMediaSourceCenter();
- void captureDevicesChanged();
-
static RealtimeMediaSourceCenter& platformCenter();
RealtimeMediaSourceSupportedConstraints m_supportedConstraints;
CaptureDeviceManager* m_audioCaptureDeviceManager { nullptr };
CaptureDeviceManager* m_videoCaptureDeviceManager { nullptr };
+
+ WTF::Function<void()> m_deviceChangedObserver;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/mediastream/ios/AVAudioSessionCaptureDeviceManager.mm (235085 => 235086)
--- trunk/Source/WebCore/platform/mediastream/ios/AVAudioSessionCaptureDeviceManager.mm 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/platform/mediastream/ios/AVAudioSessionCaptureDeviceManager.mm 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
#if ENABLE(MEDIA_STREAM) && PLATFORM(IOS)
#include "AVAudioSessionCaptureDevice.h"
+#include "RealtimeMediaSourceCenter.h"
#include <AVFoundation/AVAudioSession.h>
#include <wtf/SoftLinking.h>
#include <wtf/Vector.h>
@@ -141,8 +142,7 @@
m_audioSessionCaptureDevices = WTFMove(newAudioDevices);
m_devices = WTFMove(newDevices);
- for (auto& observer : m_observers.values())
- observer();
+ deviceChanged();
}
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm (235085 => 235086)
--- trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -179,9 +179,7 @@
void AVCaptureDeviceManager::deviceConnected()
{
refreshCaptureDevices();
-
- for (auto& observer : m_observers.values())
- observer();
+ deviceChanged();
}
void AVCaptureDeviceManager::deviceDisconnected(AVCaptureDeviceTypedef* device)
@@ -200,8 +198,7 @@
}
}
- for (auto& observer : m_observers.values())
- observer();
+ deviceChanged();
}
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureDeviceManager.cpp (235085 => 235086)
--- trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureDeviceManager.cpp 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureDeviceManager.cpp 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,6 +30,7 @@
#include "CoreAudioCaptureDevice.h"
#include "Logging.h"
+#include "RealtimeMediaSourceCenter.h"
#include <AudioUnit/AudioUnit.h>
#include <CoreMedia/CMSync.h>
#include <wtf/Assertions.h>
@@ -64,10 +65,17 @@
static bool deviceHasInputStreams(AudioObjectID deviceID)
{
UInt32 dataSize = 0;
- AudioObjectPropertyAddress address = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeInput, kAudioObjectPropertyElementMaster };
+ AudioObjectPropertyAddress address = { kAudioDevicePropertyStreamConfiguration, kAudioDevicePropertyScopeInput, kAudioObjectPropertyElementMaster };
auto err = AudioObjectGetPropertyDataSize(deviceID, &address, 0, nullptr, &dataSize);
- return !err && dataSize;
+ if (err || !dataSize)
+ return false;
+
+ auto bufferList = std::unique_ptr<AudioBufferList>((AudioBufferList*) ::operator new (dataSize));
+ memset(bufferList.get(), 0, dataSize);
+ err = AudioObjectGetPropertyData(deviceID, &address, 0, nullptr, &dataSize, bufferList.get());
+
+ return !err && bufferList->mNumberBuffers;
}
static bool isValidCaptureDevice(const CoreAudioCaptureDevice& device)
@@ -81,7 +89,7 @@
static bool initialized;
if (!initialized) {
initialized = true;
- refreshAudioCaptureDevices();
+ refreshAudioCaptureDevices(DoNotNotify);
AudioObjectPropertyAddress address = { kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
auto err = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &address, devicesChanged, this);
@@ -102,7 +110,7 @@
}
-void CoreAudioCaptureDeviceManager::refreshAudioCaptureDevices()
+void CoreAudioCaptureDeviceManager::refreshAudioCaptureDevices(NotifyIfDevicesHaveChanged notify)
{
AudioObjectPropertyAddress address = { kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
UInt32 dataSize = 0;
@@ -156,13 +164,13 @@
m_devices.append(captureDevice);
}
- for (auto& observer : m_observers.values())
- observer();
+ if (notify == Notify)
+ deviceChanged();
}
OSStatus CoreAudioCaptureDeviceManager::devicesChanged(AudioObjectID, UInt32, const AudioObjectPropertyAddress*, void* userData)
{
- static_cast<CoreAudioCaptureDeviceManager*>(userData)->refreshAudioCaptureDevices();
+ static_cast<CoreAudioCaptureDeviceManager*>(userData)->refreshAudioCaptureDevices(Notify);
return 0;
}
Modified: trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureDeviceManager.h (235085 => 235086)
--- trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureDeviceManager.h 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureDeviceManager.h 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -55,7 +55,8 @@
static OSStatus devicesChanged(AudioObjectID, UInt32, const AudioObjectPropertyAddress*, void*);
Vector<CoreAudioCaptureDevice>& coreAudioCaptureDevices();
- void refreshAudioCaptureDevices();
+ enum NotifyIfDevicesHaveChanged { Notify, DoNotNotify };
+ void refreshAudioCaptureDevices(NotifyIfDevicesHaveChanged);
Vector<CaptureDevice> m_devices;
Vector<CoreAudioCaptureDevice> m_coreAudioCaptureDevices;
Modified: trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp (235085 => 235086)
--- trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp 2018-08-20 18:10:22 UTC (rev 235086)
@@ -97,6 +97,7 @@
void MockRealtimeMediaSource::resetDevices()
{
setDevices(defaultDevices());
+ RealtimeMediaSourceCenter::singleton().captureDevicesChanged();
}
void MockRealtimeMediaSource::setDevices(Vector<MockMediaDevice>&& newMockDevices)
@@ -115,6 +116,7 @@
map.add(device.persistentId, device);
createCaptureDevice(device);
}
+ RealtimeMediaSourceCenter::singleton().captureDevicesChanged();
}
void MockRealtimeMediaSource::addDevice(const MockMediaDevice& device)
@@ -122,6 +124,7 @@
devices().append(device);
deviceMap().set(device.persistentId, device);
createCaptureDevice(device);
+ RealtimeMediaSourceCenter::singleton().captureDevicesChanged();
}
void MockRealtimeMediaSource::removeDevice(const String& persistentId)
@@ -140,6 +143,7 @@
});
map.remove(iterator);
+ RealtimeMediaSourceCenter::singleton().captureDevicesChanged();
}
std::optional<CaptureDevice> MockRealtimeMediaSource::captureDeviceWithPersistentID(CaptureDevice::DeviceType type, const String& id)
Modified: trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp (235085 => 235086)
--- trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2013 Google Inc. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
* Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
*
* Redistribution and use in source and binary forms, with or without
@@ -55,19 +55,16 @@
void MockRealtimeMediaSourceCenter::setDevices(Vector<MockMediaDevice>&& newMockDevices)
{
MockRealtimeMediaSource::setDevices(WTFMove(newMockDevices));
- singleton().captureDevicesChanged();
}
void MockRealtimeMediaSourceCenter::addDevice(const MockMediaDevice& device)
{
MockRealtimeMediaSource::addDevice(device);
- singleton().captureDevicesChanged();
}
void MockRealtimeMediaSourceCenter::removeDevice(const String& persistentId)
{
MockRealtimeMediaSource::removeDevice(persistentId);
- singleton().captureDevicesChanged();
}
} // namespace WebCore
Modified: trunk/Source/WebCore/testing/Internals.cpp (235085 => 235086)
--- trunk/Source/WebCore/testing/Internals.cpp 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/testing/Internals.cpp 2018-08-20 18:10:22 UTC (rev 235086)
@@ -29,6 +29,7 @@
#include "AXObjectCache.h"
#include "ActiveDOMCallbackMicrotask.h"
+#include "ActivityState.h"
#include "AnimationTimeline.h"
#include "ApplicationCacheStorage.h"
#include "AudioSession.h"
@@ -4345,6 +4346,22 @@
page.setActivityState(state);
}
+void Internals::setPageIsFocusedAndActive(bool isFocusedAndActive)
+{
+ auto* document = contextDocument();
+ if (!document || !document->page())
+ return;
+ auto& page = *document->page();
+ auto state = page.activityState();
+
+ if (!isFocusedAndActive)
+ state -= { ActivityState::IsFocused, ActivityState::WindowIsActive };
+ else
+ state |= { ActivityState::IsFocused, ActivityState::WindowIsActive };
+
+ page.setActivityState(state);
+}
+
#if ENABLE(WEB_RTC)
void Internals::setH264HardwareEncoderAllowed(bool allowed)
{
Modified: trunk/Source/WebCore/testing/Internals.h (235085 => 235086)
--- trunk/Source/WebCore/testing/Internals.h 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/testing/Internals.h 2018-08-20 18:10:22 UTC (rev 235086)
@@ -645,7 +645,9 @@
#endif
void setPageVisibility(bool isVisible);
+ void setPageIsFocusedAndActive(bool);
+
#if ENABLE(WEB_RTC)
void setH264HardwareEncoderAllowed(bool allowed);
#endif
Modified: trunk/Source/WebCore/testing/Internals.idl (235085 => 235086)
--- trunk/Source/WebCore/testing/Internals.idl 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebCore/testing/Internals.idl 2018-08-20 18:10:22 UTC (rev 235086)
@@ -604,6 +604,7 @@
[Conditional=WEBGL] void failNextGPUStatusCheck(WebGLRenderingContext context);
void setPageVisibility(boolean isVisible);
+ void setPageIsFocusedAndActive(boolean isFocused);
[Conditional=WEB_RTC] void setH264HardwareEncoderAllowed(boolean allowed);
[Conditional=WEB_RTC] void applyRotationForOutgoingVideoSources(RTCPeerConnection connection);
Modified: trunk/Source/WebKit/ChangeLog (235085 => 235086)
--- trunk/Source/WebKit/ChangeLog 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/ChangeLog 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,3 +1,57 @@
+2018-08-20 Eric Carlson <[email protected]>
+
+ [MediaStream] Move capture device monitoring to WebKit
+ https://bugs.webkit.org/show_bug.cgi?id=188521
+ <rdar://problem/43251787>
+
+ Reviewed by Youenn Fablet.
+
+ * UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
+ (WebKit::UserMediaPermissionRequestManagerProxy::captureDevicesChanged): Notify as appropriate.
+ (WebKit::UserMediaPermissionRequestManagerProxy::viewIsBecomingVisible): Change name from
+ viewIsBecomingVisible. Call captureDevicesChanged if a change happened when not visible.
+ (WebKit::UserMediaPermissionRequestManagerProxy::watchdogTimerFired): Clear m_pendingDeviceChangeEvent.
+ (WebKit::UserMediaPermissionRequestManagerProxy::processPregrantedRequests): Deleted.
+ * UIProcess/UserMediaPermissionRequestManagerProxy.h:
+
+ * UIProcess/UserMediaProcessManager.cpp:
+ (WebKit::UserMediaProcessManager::UserMediaProcessManager): Initialize timer.
+ (WebKit::UserMediaProcessManager::captureDevicesChanged): New, notify each manager.
+ (WebKit::UserMediaProcessManager::beginMonitoringCaptureDevices): Cache the device list and
+ register device change listener the first time it is called.
+ * UIProcess/UserMediaProcessManager.h:
+
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::viewIsBecomingVisible):
+ (WebKit::WebPageProxy::beginMonitoringCaptureDevices):
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/WebPageProxy.messages.in:
+
+ * WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp:
+ (WebKit::UserMediaPermissionRequestManager::addDeviceChangeObserver): Add listener, tell page
+ to start monitoring device changes.
+ (WebKit::UserMediaPermissionRequestManager::removeDeviceChangeObserver): Remove listener.
+ (WebKit::UserMediaPermissionRequestManager::captureDevicesChanged): Call listeners.
+ * WebProcess/MediaStream/UserMediaPermissionRequestManager.h:
+
+ * WebProcess/WebCoreSupport/WebUserMediaClient.cpp:
+ (WebKit::WebUserMediaClient::addDeviceChangeObserver):
+ (WebKit::WebUserMediaClient::removeDeviceChangeObserver):
+ * WebProcess/WebCoreSupport/WebUserMediaClient.h:
+
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::captureDevicesChanged):
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in:
+
+ * WebProcess/WebProcess.cpp:
+ (WebKit::WebProcess::addMockMediaDevice):
+ (WebKit::WebProcess::clearMockMediaDevices):
+ (WebKit::WebProcess::removeMockMediaDevice):
+ (WebKit::WebProcess::resetMockMediaDevices):
+ (WebKit::WebProcess::captureDevicesChanged):
+ * WebProcess/WebProcess.h:
+
2018-08-20 Carlos Garcia Campos <[email protected]>
Unreviewed. Fix GTK/WPE cookie API tests after r234396.
Modified: trunk/Source/WebKit/Scripts/webkit/messages.py (235085 => 235086)
--- trunk/Source/WebKit/Scripts/webkit/messages.py 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/Scripts/webkit/messages.py 2018-08-20 18:10:22 UTC (rev 235086)
@@ -419,6 +419,7 @@
'WebCore::SelectionRect': ['"EditorState.h"'],
'WebKit::ActivityStateChangeID': ['"DrawingAreaInfo.h"'],
'WebKit::BackForwardListItemState': ['"SessionState.h"'],
+ 'WebKit::DeviceAccessState': ['"UserMediaPermissionRequestManager.h"'],
'WebKit::LayerHostingMode': ['"LayerTreeContext.h"'],
'WebKit::PageState': ['"SessionState.h"'],
'WebKit::WebGestureEvent': ['"WebEvent.h"'],
Modified: trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp (235085 => 235086)
--- trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 Igalia S.L.
- * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,6 +22,7 @@
#include "APISecurityOrigin.h"
#include "APIUIClient.h"
+#include "UserMediaPermissionRequestManager.h"
#include "UserMediaProcessManager.h"
#include "WebAutomationSession.h"
#include "WebPageMessages.h"
@@ -77,6 +78,15 @@
m_page.stopMediaCapture();
}
+void UserMediaPermissionRequestManagerProxy::captureDevicesChanged()
+{
+#if ENABLE(MEDIA_STREAM)
+ // FIXME: a page with persistent access should always get device change notifications.
+ auto accessState = m_grantedRequests.isEmpty() ? DeviceAccessState::NoAccess : DeviceAccessState::SessionAccess;
+ m_page.process().send(Messages::WebPage::CaptureDevicesChanged(accessState), m_page.pageID());
+#endif
+}
+
void UserMediaPermissionRequestManagerProxy::clearCachedState()
{
invalidatePendingRequests();
@@ -434,7 +444,7 @@
#endif
}
-void UserMediaPermissionRequestManagerProxy::processPregrantedRequests()
+void UserMediaPermissionRequestManagerProxy::viewIsBecomingVisible()
{
for (auto& request : m_pregrantedRequests)
request->allow();
Modified: trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h (235085 => 235086)
--- trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 Igalia S.L.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -50,7 +50,7 @@
void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, const WebCore::MediaStreamRequest&);
void resetAccess(uint64_t mainFrameID);
- void processPregrantedRequests();
+ void viewIsBecomingVisible();
void userMediaAccessWasGranted(uint64_t, WebCore::CaptureDevice&& audioDevice, WebCore::CaptureDevice&& videoDevice);
void userMediaAccessWasDenied(uint64_t, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason);
@@ -61,6 +61,7 @@
void scheduleNextRejection();
void rejectionTimerFired();
void clearCachedState();
+ void captureDevicesChanged();
void captureStateChanged(WebCore::MediaProducer::MediaStateFlags oldState, WebCore::MediaProducer::MediaStateFlags newState);
Modified: trunk/Source/WebKit/UIProcess/UserMediaProcessManager.cpp (235085 => 235086)
--- trunk/Source/WebKit/UIProcess/UserMediaProcessManager.cpp 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/UIProcess/UserMediaProcessManager.cpp 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,6 +25,7 @@
#include "WebPageMessages.h"
#include "WebPageProxy.h"
#include "WebProcessProxy.h"
+#include <WebCore/RealtimeMediaSourceCenter.h>
#include <wtf/HashMap.h>
#include <wtf/NeverDestroyed.h>
@@ -35,6 +36,8 @@
static const ASCIILiteral videoExtensionPath { "com.apple.webkit.camera"_s };
#endif
+static const Seconds deviceChangeDebounceTimerInterval { 200_ms };
+
class ProcessState {
public:
ProcessState() { }
@@ -101,6 +104,11 @@
return manager;
}
+UserMediaProcessManager::UserMediaProcessManager()
+ : m_debounceTimer(RunLoop::main(), this, &UserMediaProcessManager::captureDevicesChanged)
+{
+}
+
void UserMediaProcessManager::addUserMediaPermissionRequestManagerProxy(UserMediaPermissionRequestManagerProxy& proxy)
{
processState(proxy.page().process()).addRequestManager(proxy);
@@ -254,6 +262,58 @@
}
}
+void UserMediaProcessManager::captureDevicesChanged()
+{
+ auto& map = stateMap();
+ for (auto& state : map) {
+ auto* process = state.key;
+ for (auto& manager : state.value->managers()) {
+ if (map.find(process) == map.end())
+ break;
+ manager->captureDevicesChanged();
+ }
+ }
+}
+
+void UserMediaProcessManager::beginMonitoringCaptureDevices()
+{
+ static std::once_flag onceFlag;
+
+ std::call_once(onceFlag, [this] {
+ m_captureDevices = WebCore::RealtimeMediaSourceCenter::singleton().getMediaStreamDevices();
+
+ WebCore::RealtimeMediaSourceCenter::singleton().setDevicesChangedObserver([this]() {
+ auto oldDevices = WTFMove(m_captureDevices);
+ m_captureDevices = WebCore::RealtimeMediaSourceCenter::singleton().getMediaStreamDevices();
+
+ if (m_captureDevices.size() == oldDevices.size()) {
+ bool haveChanges = false;
+ for (auto &newDevice : m_captureDevices) {
+ if (newDevice.type() != WebCore::CaptureDevice::DeviceType::Camera && newDevice.type() != WebCore::CaptureDevice::DeviceType::Microphone)
+ continue;
+
+ auto index = oldDevices.findMatching([&newDevice] (auto& oldDevice) {
+ return newDevice.persistentId() == oldDevice.persistentId() && newDevice.enabled() != oldDevice.enabled();
+ });
+
+ if (index == notFound) {
+ haveChanges = true;
+ break;
+ }
+ }
+
+ if (!haveChanges)
+ return;
+ }
+
+ // When a device with camera and microphone is attached or detached, the CaptureDevice notification for
+ // the different devices won't arrive at the same time so delay a bit so we can coalesce the callbacks.
+ if (!m_debounceTimer.isActive())
+ m_debounceTimer.startOneShot(deviceChangeDebounceTimerInterval);
+ });
+ });
+}
+
} // namespace WebKit
#endif
Modified: trunk/Source/WebKit/UIProcess/UserMediaProcessManager.h (235085 => 235086)
--- trunk/Source/WebKit/UIProcess/UserMediaProcessManager.h 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/UIProcess/UserMediaProcessManager.h 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,6 +21,8 @@
#if ENABLE(MEDIA_STREAM)
#include "UserMediaPermissionRequestManagerProxy.h"
+#include <WebCore/CaptureDevice.h>
+#include <wtf/RunLoop.h>
namespace WebKit {
@@ -31,6 +33,8 @@
static UserMediaProcessManager& singleton();
+ UserMediaProcessManager();
+
void addUserMediaPermissionRequestManagerProxy(UserMediaPermissionRequestManagerProxy&);
void removeUserMediaPermissionRequestManagerProxy(UserMediaPermissionRequestManagerProxy&);
@@ -45,7 +49,13 @@
void denyNextUserMediaRequest() { m_denyNextRequest = true; }
+ void beginMonitoringCaptureDevices();
+
private:
+ void captureDevicesChanged();
+
+ Vector<WebCore::CaptureDevice> m_captureDevices;
+ RunLoop::Timer<UserMediaProcessManager> m_debounceTimer;
bool m_captureEnabled { true };
bool m_denyNextRequest { false };
};
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (235085 => 235086)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2018-08-20 18:10:22 UTC (rev 235086)
@@ -3842,7 +3842,7 @@
void WebPageProxy::viewIsBecomingVisible()
{
#if ENABLE(MEDIA_STREAM)
- userMediaPermissionRequestManager().processPregrantedRequests();
+ userMediaPermissionRequestManager().viewIsBecomingVisible();
#endif
}
@@ -6459,6 +6459,13 @@
#endif
}
+void WebPageProxy::beginMonitoringCaptureDevices()
+{
+#if ENABLE(MEDIA_STREAM)
+ UserMediaProcessManager::singleton().beginMonitoringCaptureDevices();
+#endif
+}
+
void WebPageProxy::clearUserMediaState()
{
#if ENABLE(MEDIA_STREAM)
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (235085 => 235086)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1487,6 +1487,7 @@
#endif
void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, const WebCore::SecurityOriginData& userMediaDocumentOriginIdentifier, const WebCore::SecurityOriginData& topLevelDocumentOriginIdentifier, const WebCore::MediaStreamRequest&);
void enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, const WebCore::SecurityOriginData& userMediaDocumentOriginData, const WebCore::SecurityOriginData& topLevelDocumentOriginData);
+ void beginMonitoringCaptureDevices();
void runModal();
void notifyScrollerThumbIsVisibleInRect(const WebCore::IntRect&);
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in (235085 => 235086)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2018-08-20 18:10:22 UTC (rev 235086)
@@ -287,6 +287,7 @@
# MediaSteam messages
RequestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, struct WebCore::SecurityOriginData userMediaDocumentOriginIdentifier, struct WebCore::SecurityOriginData topLevelDocumentOriginIdentifier, struct WebCore::MediaStreamRequest request)
EnumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, struct WebCore::SecurityOriginData userMediaDocumentOriginIdentifier, struct WebCore::SecurityOriginData topLevelDocumentOriginIdentifier)
+ BeginMonitoringCaptureDevices()
#endif
# Notification messages
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (235085 => 235086)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2018-08-20 18:10:22 UTC (rev 235086)
@@ -85,6 +85,7 @@
074E75FE1DF2211900D318EC /* UserMediaProcessManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 074E75FB1DF1FD1300D318EC /* UserMediaProcessManager.h */; };
074E76021DF707BE00D318EC /* MediaDeviceSandboxExtensions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 074E76001DF7075D00D318EC /* MediaDeviceSandboxExtensions.cpp */; };
076E884E1A13CADF005E90FC /* APIContextMenuClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 076E884D1A13CADF005E90FC /* APIContextMenuClient.h */; };
+ 0772811D21234FF600C8EF2E /* UserMediaPermissionRequestManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A410F4319AF7B27002EBAB5 /* UserMediaPermissionRequestManager.h */; };
07A5EBBB1C7BA43E00B9CA69 /* WKFrameHandleRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A5EBB91C7BA43E00B9CA69 /* WKFrameHandleRef.cpp */; };
07A5EBBC1C7BA43E00B9CA69 /* WKFrameHandleRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 07A5EBBA1C7BA43E00B9CA69 /* WKFrameHandleRef.h */; settings = {ATTRIBUTES = (Private, ); }; };
0E97D74D200E900400BF6643 /* SafeBrowsingSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E97D74C200E8FF300BF6643 /* SafeBrowsingSPI.h */; };
@@ -9716,6 +9717,7 @@
CD491B131E73482100009066 /* UserMediaCaptureManagerProxy.h in Headers */,
CD491B181E73525500009066 /* UserMediaCaptureManagerProxyMessages.h in Headers */,
07297F9F1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.h in Headers */,
+ 0772811D21234FF600C8EF2E /* UserMediaPermissionRequestManager.h in Headers */,
4A3CC18B19B0640F00D14AEF /* UserMediaPermissionRequestManagerProxy.h in Headers */,
4A3CC18D19B0641900D14AEF /* UserMediaPermissionRequestProxy.h in Headers */,
074E75FE1DF2211900D318EC /* UserMediaProcessManager.h in Headers */,
Modified: trunk/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp (235085 => 235086)
--- trunk/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 Igalia S.L.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -40,6 +40,8 @@
using namespace WebCore;
+static constexpr OptionSet<WebCore::ActivityState::Flag> focusedActiveWindow = { WebCore::ActivityState::IsFocused, WebCore::ActivityState::WindowIsActive };
+
static uint64_t generateRequestID()
{
static uint64_t uniqueRequestID = 1;
@@ -53,6 +55,8 @@
UserMediaPermissionRequestManager::~UserMediaPermissionRequestManager()
{
+ if (m_monitoringActivityStateChange)
+ m_page.corePage()->removeActivityStateChangeObserver(*this);
for (auto& sandboxExtension : m_userMediaDeviceSandboxExtensions)
sandboxExtension.value->revoke();
}
@@ -222,6 +226,77 @@
}
}
+UserMediaClient::DeviceChangeObserverToken UserMediaPermissionRequestManager::addDeviceChangeObserver(WTF::Function<void()>&& observer)
+{
+ auto identifier = generateObjectIdentifier<WebCore::UserMediaClient::DeviceChangeObserverTokenType>();
+ m_deviceChangeObserverMap.add(identifier, WTFMove(observer));
+
+ if (!m_monitoringDeviceChange) {
+ m_monitoringDeviceChange = true;
+ m_page.send(Messages::WebPageProxy::BeginMonitoringCaptureDevices());
+ }
+ return identifier;
+}
+
+void UserMediaPermissionRequestManager::removeDeviceChangeObserver(UserMediaClient::DeviceChangeObserverToken token)
+{
+ bool wasRemoved = m_deviceChangeObserverMap.remove(token);
+ ASSERT_UNUSED(wasRemoved, wasRemoved);
+}
+
+void UserMediaPermissionRequestManager::captureDevicesChanged(DeviceAccessState accessState)
+{
+ // When new media input and/or output devices are made available, or any available input and/or
+ // output device becomes unavailable, the User Agent MUST run the following steps in browsing
+ // contexts where at least one of the following criteria are met, but in no other contexts:
+
+ // * The permission state of the "device-info" permission is "granted",
+ // * any of the input devices are attached to an active MediaStream in the browsing context, or
+ // * the active document is fully active and has focus.
+
+ bool isActive = (m_page.corePage()->activityState() & focusedActiveWindow) == focusedActiveWindow;
+ if (!isActive && accessState == DeviceAccessState::NoAccess) {
+ if (!isActive) {
+ if (!m_monitoringActivityStateChange) {
+ m_monitoringActivityStateChange = true;
+ m_page.corePage()->addActivityStateChangeObserver(*this);
+ }
+ m_pendingDeviceChangeEvent = true;
+ m_accessStateWhenDevicesChanged = accessState;
+ }
+ return;
+ }
+
+ auto identifiers = m_deviceChangeObserverMap.keys();
+ for (auto& identifier : identifiers) {
+ auto iterator = m_deviceChangeObserverMap.find(identifier);
+ if (iterator != m_deviceChangeObserverMap.end())
+ (iterator->value)();
+ }
+}
+
+void UserMediaPermissionRequestManager::activityStateDidChange(OptionSet<WebCore::ActivityState::Flag> oldActivityState, OptionSet<WebCore::ActivityState::Flag> newActivityState)
+{
+ if ((newActivityState & focusedActiveWindow) != focusedActiveWindow)
+ return;
+
+ RunLoop::main().dispatch([this, weakThis = makeWeakPtr(*this)]() mutable {
+ if (!weakThis || !m_monitoringActivityStateChange)
+ return;
+
+ m_monitoringActivityStateChange = false;
+ m_page.corePage()->removeActivityStateChangeObserver(*this);
+ });
+
+ if (!m_pendingDeviceChangeEvent)
+ return;
+
+ m_pendingDeviceChangeEvent = false;
+ auto accessState = m_accessStateWhenDevicesChanged;
+ m_accessStateWhenDevicesChanged = DeviceAccessState::NoAccess;
+ captureDevicesChanged(accessState);
+}
+
} // namespace WebKit
#endif // ENABLE(MEDIA_STREAM)
Modified: trunk/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.h (235085 => 235086)
--- trunk/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.h 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.h 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 Igalia S.L.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -24,6 +24,7 @@
#include "MediaDeviceSandboxExtensions.h"
#include "SandboxExtension.h"
+#include <WebCore/ActivityStateChangeObserver.h>
#include <WebCore/MediaCanStartListener.h>
#include <WebCore/MediaConstraints.h>
#include <WebCore/MediaDevicesEnumerationRequest.h>
@@ -37,8 +38,9 @@
class WebPage;
-class UserMediaPermissionRequestManager
- : private WebCore::MediaCanStartListener {
+enum class DeviceAccessState { NoAccess, SessionAccess, PersistentAccess };
+
+class UserMediaPermissionRequestManager : public CanMakeWeakPtr<UserMediaPermissionRequestManager>, private WebCore::MediaCanStartListener, private WebCore::ActivityStateChangeObserver {
public:
explicit UserMediaPermissionRequestManager(WebPage&);
~UserMediaPermissionRequestManager();
@@ -55,12 +57,20 @@
void grantUserMediaDeviceSandboxExtensions(MediaDeviceSandboxExtensions&&);
void revokeUserMediaDeviceSandboxExtensions(const Vector<String>&);
+ WebCore::UserMediaClient::DeviceChangeObserverToken addDeviceChangeObserver(WTF::Function<void()>&&);
+ void removeDeviceChangeObserver(WebCore::UserMediaClient::DeviceChangeObserverToken);
+
+ void captureDevicesChanged(DeviceAccessState);
+
private:
void sendUserMediaRequest(WebCore::UserMediaRequest&);
// WebCore::MediaCanStartListener
- void mediaCanStart(WebCore::Document&) override;
+ void mediaCanStart(WebCore::Document&) final;
+ // WebCore::ActivityStateChangeObserver
+ void activityStateDidChange(OptionSet<WebCore::ActivityState::Flag> oldActivityState, OptionSet<WebCore::ActivityState::Flag> newActivityState) final;
+
void removeMediaRequestFromMaps(WebCore::UserMediaRequest&);
WebPage& m_page;
@@ -73,10 +83,29 @@
HashMap<RefPtr<WebCore::MediaDevicesEnumerationRequest>, uint64_t> m_mediaDevicesEnumerationRequestToIDMap;
HashMap<String, RefPtr<SandboxExtension>> m_userMediaDeviceSandboxExtensions;
+
+ HashMap<WebCore::UserMediaClient::DeviceChangeObserverToken, WTF::Function<void()>> m_deviceChangeObserverMap;
+ DeviceAccessState m_accessStateWhenDevicesChanged { DeviceAccessState::NoAccess };
+ bool m_monitoringDeviceChange { false };
+ bool m_pendingDeviceChangeEvent { false };
+ bool m_monitoringActivityStateChange { false };
};
} // namespace WebKit
+namespace WTF {
+
+template<> struct EnumTraits<WebKit::DeviceAccessState> {
+ using values = EnumValues<
+ WebKit::DeviceAccessState,
+ WebKit::DeviceAccessState::NoAccess,
+ WebKit::DeviceAccessState::SessionAccess,
+ WebKit::DeviceAccessState::PersistentAccess
+ >;
+};
+
+} // namespace WTF
+
#endif // ENABLE(MEDIA_STREAM)
#endif // UserMediaPermissionRequestManager_h
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.cpp (235085 => 235086)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.cpp 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.cpp 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 Igalia S.L.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -62,6 +62,16 @@
m_page.userMediaPermissionRequestManager().cancelMediaDevicesEnumeration(request);
}
+WebUserMediaClient::DeviceChangeObserverToken WebUserMediaClient::addDeviceChangeObserver(WTF::Function<void()>&& observer)
+{
+ return m_page.userMediaPermissionRequestManager().addDeviceChangeObserver(WTFMove(observer));
+}
+
+void WebUserMediaClient::removeDeviceChangeObserver(DeviceChangeObserverToken token)
+{
+ m_page.userMediaPermissionRequestManager().removeDeviceChangeObserver(token);
+}
+
} // namespace WebKit;
#endif // MEDIA_STREAM
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.h (235085 => 235086)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.h 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.h 2018-08-20 18:10:22 UTC (rev 235086)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 Igalia S.L.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,6 +42,9 @@
void enumerateMediaDevices(WebCore::MediaDevicesEnumerationRequest&) final;
void cancelMediaDevicesEnumerationRequest(WebCore::MediaDevicesEnumerationRequest&) final;
+ DeviceChangeObserverToken addDeviceChangeObserver(WTF::Function<void()>&&) final;
+ void removeDeviceChangeObserver(DeviceChangeObserverToken) final;
+
void initializeFactories();
WebPage& m_page;
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (235085 => 235086)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2018-08-20 18:10:22 UTC (rev 235086)
@@ -3739,6 +3739,12 @@
{
m_userMediaPermissionRequestManager->didCompleteMediaDeviceEnumeration(userMediaID, devices, WTFMove(deviceIdentifierHashSalt), originHasPersistentAccess);
}
+
+void WebPage::captureDevicesChanged(DeviceAccessState accessState)
+{
+ m_userMediaPermissionRequestManager->captureDevicesChanged(accessState);
+}
+
#if ENABLE(SANDBOX_EXTENSIONS)
void WebPage::grantUserMediaDeviceSandboxExtensions(MediaDeviceSandboxExtensions&& extensions)
{
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (235085 => 235086)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2018-08-20 18:10:22 UTC (rev 235086)
@@ -228,6 +228,7 @@
class WebCredentialsMessenger;
class RemoteLayerTreeTransaction;
+enum class DeviceAccessState;
enum FindOptions : uint16_t;
enum class DragControllerAction;
@@ -565,6 +566,7 @@
#if ENABLE(MEDIA_STREAM)
UserMediaPermissionRequestManager& userMediaPermissionRequestManager() { return *m_userMediaPermissionRequestManager; }
void prepareToSendUserMediaPermissionRequest();
+ void captureDevicesChanged(DeviceAccessState);
#endif
void elementDidFocus(WebCore::Node*);
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (235085 => 235086)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2018-08-20 17:41:23 UTC (rev 235085)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2018-08-20 18:10:22 UTC (rev 235086)
@@ -318,6 +318,7 @@
UserMediaAccessWasGranted(uint64_t userMediaID, WebCore::CaptureDevice audioDevice, WebCore::CaptureDevice videoDevice, String mediaDeviceIdentifierHashSalt)
UserMediaAccessWasDenied(uint64_t userMediaID, uint64_t reason, String invalidConstraint)
DidCompleteMediaDeviceEnumeration(uint64_t userMediaID, Vector<WebCore::CaptureDevice> devices, String mediaDeviceIdentifierHashSalt, bool hasPersistentAccess)
+ CaptureDevicesChanged(enum WebKit::DeviceAccessState accessState)
#if ENABLE(SANDBOX_EXTENSIONS)
GrantUserMediaDeviceSandboxExtensions(WebKit::MediaDeviceSandboxExtensions sandboxExtensions)
RevokeUserMediaDeviceSandboxExtensions(Vector<String> sandboxExtensionIDs)