Diff
Modified: trunk/LayoutTests/ChangeLog (233161 => 233162)
--- trunk/LayoutTests/ChangeLog 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/LayoutTests/ChangeLog 2018-06-25 19:19:06 UTC (rev 233162)
@@ -1,3 +1,13 @@
+2018-06-25 Youenn Fablet <you...@apple.com>
+
+ Add API to control mock media devices
+ https://bugs.webkit.org/show_bug.cgi?id=186958
+
+ Reviewed by Eric Carlson.
+
+ * fast/mediastream/device-change-event-2-expected.txt: Added.
+ * fast/mediastream/device-change-event-2.html: Added.
+
2018-06-25 Antoine Quint <grao...@apple.com>
[Web Animations] Make imported/mozilla/css-animations/test_animation-pausing.html pass reliably
Added: trunk/LayoutTests/fast/mediastream/device-change-event-2-expected.txt (0 => 233162)
--- trunk/LayoutTests/fast/mediastream/device-change-event-2-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/mediastream/device-change-event-2-expected.txt 2018-06-25 19:19:06 UTC (rev 233162)
@@ -0,0 +1,3 @@
+
+PASS 'devicechange' event fired when device list changes
+
Added: trunk/LayoutTests/fast/mediastream/device-change-event-2.html (0 => 233162)
--- trunk/LayoutTests/fast/mediastream/device-change-event-2.html (rev 0)
+++ trunk/LayoutTests/fast/mediastream/device-change-event-2.html 2018-06-25 19:19:06 UTC (rev 233162)
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Testing local audio capture playback causes "playing" event to fire</title>
+ <script src=""
+ <script src=""
+ <script>
+ let deviceIds = [];
+ promise_test(async (test) => {
+ if (!window.testRunner)
+ return Promise.reject("test requires internal API");
+
+ test.add_cleanup(() => { testRunner.resetMockMediaDevices(); });
+
+ testRunner.setUserMediaPermission(true);
+
+ await navigator.mediaDevices.getUserMedia({ audio:true, video:true });
+
+ let devices = await navigator.mediaDevices.enumerateDevices();
+
+ assert_true(!!devices.length, "check there are some devices");
+
+ testRunner.clearMockMediaDevices();
+
+ devices = await navigator.mediaDevices.enumerateDevices();
+ assert_false(!!devices.length, "check there are no more devices");
+
+ await new Promise((resolve, reject) => {
+ navigator.mediaDevices._ondevicechange_ = resolve;
+ setTimeout(() => {
+ console.log("event 1 taking a long time");
+ resolve();
+ }, 5000);
+ testRunner.addMockCameraDevice("id1", "my camera");
+ });
+ devices = await navigator.mediaDevices.enumerateDevices();
+ assert_equals(devices[0].kind, "videoinput");
+ assert_equals(devices[0].label, "my camera");
+
+ await new Promise((resolve, reject) => {
+ navigator.mediaDevices._ondevicechange_ = resolve;
+ setTimeout(() => {
+ console.log("event 2 taking a long time");
+ resolve();
+ }, 5000);
+ testRunner.addMockMicrophoneDevice("id2", "my mic");
+ });
+ devices = await navigator.mediaDevices.enumerateDevices();
+ assert_equals(devices[0].kind, "audioinput");
+ assert_equals(devices[0].label, "my mic");
+
+ }, "'devicechange' event fired when device list changes");
+ </script>
+</head>
+<body>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (233161 => 233162)
--- trunk/Source/WebCore/ChangeLog 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebCore/ChangeLog 2018-06-25 19:19:06 UTC (rev 233162)
@@ -1,3 +1,82 @@
+2018-06-25 Youenn Fablet <you...@apple.com>
+
+ Add API to control mock media devices
+ https://bugs.webkit.org/show_bug.cgi?id=186958
+
+ Reviewed by Eric Carlson.
+
+ Refactor code to introduce a MockDevice structure that can be used in multiple processes.
+ Update mock sources and center to use MockDevice.
+ Add API to update mock media devices.
+
+ Make MediaDevices an ActiveDOMObject so that it does not get collected when ondevicechange is set.
+
+ Test: fast/mediastream/device-change-event-2.html
+
+ * Modules/mediastream/MediaDevices.cpp:
+ (WebCore::MediaDevices::MediaDevices):
+ (WebCore::MediaDevices::stop):
+ (WebCore::MediaDevices::scheduledEventTimerFired):
+ (WebCore::MediaDevices::hasPendingActivity const):
+ (WebCore::MediaDevices::activeDOMObjectName const):
+ (WebCore::MediaDevices::canSuspendForDocumentSuspension const):
+ * Modules/mediastream/MediaDevices.h:
+ * Modules/mediastream/MediaDevices.idl:
+ * WebCore.xcodeproj/project.pbxproj:
+ * platform/mediastream/RealtimeMediaSourceCenter.h:
+ * platform/mock/MockMediaDevice.h: Added.
+ (WebCore::MockMicrophoneProperties::encode const):
+ (WebCore::MockMicrophoneProperties::decode):
+ (WebCore::MockCameraProperties::encode const):
+ (WebCore::MockCameraProperties::decode):
+ (WebCore::MockDisplayProperties::encode const):
+ (WebCore::MockDisplayProperties::decode):
+ (WebCore::MockMediaDevice::isMicrophone const):
+ (WebCore::MockMediaDevice::isCamera const):
+ (WebCore::MockMediaDevice::isDisplay const):
+ (WebCore::MockMediaDevice::type const):
+ (WebCore::MockMediaDevice::encode const):
+ (WebCore::MockMediaDevice::decodeMockMediaDevice):
+ (WebCore::MockMediaDevice::decode):
+ * platform/mock/MockRealtimeAudioSource.cpp:
+ (WebCore::MockRealtimeAudioSource::startProducingData):
+ * platform/mock/MockRealtimeMediaSource.cpp:
+ (WebCore::defaultDevices):
+ (WebCore::devices):
+ (WebCore::deviceMap):
+ (WebCore::deviceListForDevice):
+ (WebCore::MockRealtimeMediaSource::createCaptureDevice):
+ (WebCore::MockRealtimeMediaSource::resetDevices):
+ (WebCore::MockRealtimeMediaSource::setDevices):
+ (WebCore::MockRealtimeMediaSource::addDevice):
+ (WebCore::MockRealtimeMediaSource::removeDevice):
+ (WebCore::MockRealtimeMediaSource::captureDeviceWithPersistentID):
+ (WebCore::MockRealtimeMediaSource::audioDevices):
+ (WebCore::MockRealtimeMediaSource::videoDevices):
+ (WebCore::MockRealtimeMediaSource::displayDevices):
+ (WebCore::MockRealtimeMediaSource::MockRealtimeMediaSource):
+ (WebCore::MockRealtimeMediaSource::initializeCapabilities):
+ (WebCore::MockRealtimeMediaSource::initializeSettings):
+ (WebCore::MockRealtimeMediaSource::settings const):
+ (WebCore::MockRealtimeMediaSource::supportedConstraints):
+ * platform/mock/MockRealtimeMediaSource.h:
+ (WebCore::MockRealtimeMediaSource::device const):
+ * platform/mock/MockRealtimeMediaSourceCenter.cpp:
+ (WebCore::MockRealtimeMediaSourceCenter::singleton):
+ (WebCore::MockRealtimeMediaSourceCenter::setMockRealtimeMediaSourceCenterEnabled):
+ (WebCore::MockRealtimeMediaSourceCenter::setDevices):
+ (WebCore::MockRealtimeMediaSourceCenter::addDevice):
+ (WebCore::MockRealtimeMediaSourceCenter::removeDevice):
+ * platform/mock/MockRealtimeMediaSourceCenter.h:
+ * platform/mock/MockRealtimeVideoSource.cpp:
+ (WebCore::MockRealtimeVideoSource::MockRealtimeVideoSource):
+ (WebCore::MockRealtimeVideoSource::initializeCapabilities):
+ (WebCore::MockRealtimeVideoSource::drawText):
+ (WebCore::MockRealtimeVideoSource::generateFrame):
+ * platform/mock/MockRealtimeVideoSource.h:
+ (WebCore::MockRealtimeVideoSource::mockCamera const):
+ (WebCore::MockRealtimeVideoSource::mockScreen const):
+
2018-06-25 Simon Fraser <simon.fra...@apple.com>
AutoTableLayout wastes 52KB of Vector capacity on nytimes.com
Modified: trunk/Source/WebCore/Modules/mediastream/MediaDevices.cpp (233161 => 233162)
--- trunk/Source/WebCore/Modules/mediastream/MediaDevices.cpp 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebCore/Modules/mediastream/MediaDevices.cpp 2018-06-25 19:19:06 UTC (rev 233162)
@@ -47,8 +47,9 @@
namespace WebCore {
inline MediaDevices::MediaDevices(Document& document)
- : ContextDestructionObserver(&document)
+ : ActiveDOMObject(&document)
, m_scheduledEventTimer(*this, &MediaDevices::scheduledEventTimerFired)
+ , m_eventNames(eventNames())
{
m_deviceChangedToken = RealtimeMediaSourceCenter::singleton().addDevicesChangedObserver([weakThis = makeWeakPtr(*this), this]() {
@@ -61,6 +62,8 @@
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");
static_assert(static_cast<size_t>(MediaDevices::DisplayCaptureSurfaceType::Window) == static_cast<size_t>(RealtimeMediaSourceSettings::DisplaySurfaceType::Window), "MediaDevices::DisplayCaptureSurfaceType::Window is not RealtimeMediaSourceSettings::DisplaySurfaceType::Window as expected");
static_assert(static_cast<size_t>(MediaDevices::DisplayCaptureSurfaceType::Application) == static_cast<size_t>(RealtimeMediaSourceSettings::DisplaySurfaceType::Application), "MediaDevices::DisplayCaptureSurfaceType::Application is not RealtimeMediaSourceSettings::DisplaySurfaceType::Application as expected");
@@ -67,10 +70,12 @@
static_assert(static_cast<size_t>(MediaDevices::DisplayCaptureSurfaceType::Browser) == static_cast<size_t>(RealtimeMediaSourceSettings::DisplaySurfaceType::Browser), "MediaDevices::DisplayCaptureSurfaceType::Browser is not RealtimeMediaSourceSettings::DisplaySurfaceType::Browser as expected");
}
-MediaDevices::~MediaDevices()
+MediaDevices::~MediaDevices() = default;
+
+void MediaDevices::stop()
{
if (m_deviceChangedToken)
- RealtimeMediaSourceCenter::singleton().removeDevicesChangedObserver(m_deviceChangedToken.value());
+ RealtimeMediaSourceCenter::singleton().removeDevicesChangedObserver(m_deviceChangedToken);
}
Ref<MediaDevices> MediaDevices::create(Document& document)
@@ -157,9 +162,25 @@
void MediaDevices::scheduledEventTimerFired()
{
- dispatchEvent(Event::create(eventNames().devicechangeEvent, false, false));
+ if (scriptExecutionContext())
+ dispatchEvent(Event::create(eventNames().devicechangeEvent, false, false));
}
+bool MediaDevices::hasPendingActivity() const
+{
+ return scriptExecutionContext() && hasEventListeners(m_eventNames.devicechangeEvent);
+}
+
+const char* MediaDevices::activeDOMObjectName() const
+{
+ return "MediaDevices";
+}
+
+bool MediaDevices::canSuspendForDocumentSuspension() const
+{
+ return true;
+}
+
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
Modified: trunk/Source/WebCore/Modules/mediastream/MediaDevices.h (233161 => 233162)
--- trunk/Source/WebCore/Modules/mediastream/MediaDevices.h 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebCore/Modules/mediastream/MediaDevices.h 2018-06-25 19:19:06 UTC (rev 233162)
@@ -33,6 +33,8 @@
#if ENABLE(MEDIA_STREAM)
+#include "ActiveDOMObject.h"
+#include "EventNames.h"
#include "EventTarget.h"
#include "ExceptionOr.h"
#include "JSDOMPromiseDeferred.h"
@@ -49,7 +51,7 @@
struct MediaTrackSupportedConstraints;
-class MediaDevices : public RefCounted<MediaDevices>, public ContextDestructionObserver, public EventTargetWithInlineData, public CanMakeWeakPtr<MediaDevices> {
+class MediaDevices : public RefCounted<MediaDevices>, public ActiveDOMObject, public EventTargetWithInlineData, public CanMakeWeakPtr<MediaDevices> {
public:
static Ref<MediaDevices> create(Document&);
@@ -84,14 +86,23 @@
void scheduledEventTimerFired();
+ friend class JSMediaDevicesOwner;
+
+ // ActiveDOMObject
+ const char* activeDOMObjectName() const final;
+ bool canSuspendForDocumentSuspension() const final;
+ void stop() final;
+ bool hasPendingActivity() const final;
+
// EventTargetWithInlineData.
- EventTargetInterface eventTargetInterface() const override { return MediaDevicesEventTargetInterfaceType; }
- ScriptExecutionContext* scriptExecutionContext() const final { return m_scriptExecutionContext; }
- void refEventTarget() override { ref(); }
- void derefEventTarget() override { deref(); }
+ EventTargetInterface eventTargetInterface() const final { return MediaDevicesEventTargetInterfaceType; }
+ ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }
+ void refEventTarget() final { ref(); }
+ void derefEventTarget() final { deref(); }
Timer m_scheduledEventTimer;
- std::optional<RealtimeMediaSourceCenter::DevicesChangedObserverToken> m_deviceChangedToken;
+ RealtimeMediaSourceCenter::DevicesChangedObserverToken m_deviceChangedToken;
+ const EventNames& m_eventNames; // Need to cache this so we can use it from GC threads.
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/mediastream/MediaDevices.idl (233161 => 233162)
--- trunk/Source/WebCore/Modules/mediastream/MediaDevices.idl 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebCore/Modules/mediastream/MediaDevices.idl 2018-06-25 19:19:06 UTC (rev 233162)
@@ -30,6 +30,7 @@
// FIXME 169871: should be subclass of EventTarget
[
+ ActiveDOMObject,
Conditional=MEDIA_STREAM,
NoInterfaceObject,
] interface MediaDevices {
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (233161 => 233162)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-06-25 19:19:06 UTC (rev 233162)
@@ -1064,6 +1064,7 @@
4138D3351244054800323D33 /* EventContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 4138D3331244054800323D33 /* EventContext.h */; };
4138F8581D253F0E001CB61E /* JSDOMIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 4138F8561D253EEE001CB61E /* JSDOMIterator.h */; settings = {ATTRIBUTES = (Private, ); }; };
413C2C341BC29A8F0075204C /* JSDOMConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 413C2C331BC29A7B0075204C /* JSDOMConstructor.h */; };
+ 413CCD4A20DE034F0065A21A /* MockMediaDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 413CCD4820DE013C0065A21A /* MockMediaDevice.h */; settings = {ATTRIBUTES = (Private, ); }; };
413E00791DB0E4F2002341D2 /* MemoryRelease.h in Headers */ = {isa = PBXBuildFile; fileRef = 413E00781DB0E4DE002341D2 /* MemoryRelease.h */; settings = {ATTRIBUTES = (Private, ); }; };
414B82051D6DF0E50077EBE3 /* StructuredClone.h in Headers */ = {isa = PBXBuildFile; fileRef = 414B82031D6DF0D90077EBE3 /* StructuredClone.h */; };
414DEDE71F9FE91E0047C40D /* EmptyFrameLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 414DEDE51F9FE9150047C40D /* EmptyFrameLoaderClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -7202,6 +7203,7 @@
4138F8551D253EEE001CB61E /* JSDOMIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMIterator.cpp; sourceTree = "<group>"; };
4138F8561D253EEE001CB61E /* JSDOMIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMIterator.h; sourceTree = "<group>"; };
413C2C331BC29A7B0075204C /* JSDOMConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConstructor.h; sourceTree = "<group>"; };
+ 413CCD4820DE013C0065A21A /* MockMediaDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockMediaDevice.h; sourceTree = "<group>"; };
413E00771DB0E4DE002341D2 /* MemoryRelease.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryRelease.cpp; sourceTree = "<group>"; };
413E00781DB0E4DE002341D2 /* MemoryRelease.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryRelease.h; sourceTree = "<group>"; };
413E007B1DB0E707002341D2 /* MemoryReleaseCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MemoryReleaseCocoa.mm; sourceTree = "<group>"; };
@@ -18774,6 +18776,7 @@
077B64151B95F703003E9AD5 /* MediaPlaybackTargetMock.h */,
077B64101B94F12E003E9AD5 /* MediaPlaybackTargetPickerMock.cpp */,
077B64111B94F12E003E9AD5 /* MediaPlaybackTargetPickerMock.h */,
+ 413CCD4820DE013C0065A21A /* MockMediaDevice.h */,
07D6A4F11BED5F8800174146 /* MockRealtimeAudioSource.cpp */,
07D6A4F21BED5F8800174146 /* MockRealtimeAudioSource.h */,
07D6A4ED1BECF2D200174146 /* MockRealtimeMediaSource.cpp */,
@@ -29423,6 +29426,7 @@
CDF4B7201E03BF6F00E235A2 /* MockCDMFactory.idl in Headers */,
51058AE01D67C229009A538C /* MockGamepad.h in Headers */,
51058AE21D67C229009A538C /* MockGamepadProvider.h in Headers */,
+ 413CCD4A20DE034F0065A21A /* MockMediaDevice.h in Headers */,
CDF2B0131820540600F2B424 /* MockMediaPlayerMediaSource.h in Headers */,
CDF2B0151820540600F2B424 /* MockMediaSourcePrivate.h in Headers */,
07D6A4F41BED5F8800174146 /* MockRealtimeAudioSource.h in Headers */,
Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h (233161 => 233162)
--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h 2018-06-25 19:19:06 UTC (rev 233162)
@@ -88,7 +88,6 @@
using DevicesChangedObserverToken = unsigned;
DevicesChangedObserverToken addDevicesChangedObserver(std::function<void()>&&);
void removeDevicesChangedObserver(DevicesChangedObserverToken);
- void captureDevicesChanged();
void setVideoCapturePageState(bool, bool);
@@ -95,6 +94,8 @@
protected:
RealtimeMediaSourceCenter();
+ void captureDevicesChanged();
+
static RealtimeMediaSourceCenter& platformCenter();
RealtimeMediaSourceSupportedConstraints m_supportedConstraints;
Added: trunk/Source/WebCore/platform/mock/MockMediaDevice.h (0 => 233162)
--- trunk/Source/WebCore/platform/mock/MockMediaDevice.h (rev 0)
+++ trunk/Source/WebCore/platform/mock/MockMediaDevice.h 2018-06-25 19:19:06 UTC (rev 233162)
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 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
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "CaptureDevice.h"
+#include "RealtimeMediaSource.h"
+
+namespace WebCore {
+
+struct MockMicrophoneProperties {
+ template<class Encoder>
+ void encode(Encoder& encoder) const
+ {
+ encoder << static_cast<int32_t>(defaultSampleRate);
+ }
+
+ template <class Decoder>
+ static std::optional<MockMicrophoneProperties> decode(Decoder& decoder)
+ {
+ std::optional<int32_t> defaultSampleRate;
+ decoder >> defaultSampleRate;
+ if (!defaultSampleRate)
+ return std::nullopt;
+ return MockMicrophoneProperties { *defaultSampleRate };
+ }
+
+ int defaultSampleRate { 44100 };
+};
+
+// FIXME: Add support for other properties and serialization of colors.
+struct MockCameraProperties {
+ template<class Encoder>
+ void encode(Encoder& encoder) const
+ {
+ encoder << defaultFrameRate;
+ encoder << facingModeCapability;
+ }
+
+ template <class Decoder>
+ static std::optional<MockCameraProperties> decode(Decoder& decoder)
+ {
+ std::optional<double> defaultFrameRate;
+ decoder >> defaultFrameRate;
+ if (!defaultFrameRate)
+ return std::nullopt;
+
+ std::optional<RealtimeMediaSourceSettings::VideoFacingMode> facingModeCapability;
+ decoder >> facingModeCapability;
+ if (!facingModeCapability)
+ return std::nullopt;
+
+ return MockCameraProperties { *defaultFrameRate, *facingModeCapability, Color::black };
+ }
+
+ double defaultFrameRate { 30 };
+ RealtimeMediaSourceSettings::VideoFacingMode facingModeCapability { RealtimeMediaSourceSettings::VideoFacingMode::User };
+ Color fillColor { Color::black };
+};
+
+struct MockDisplayProperties {
+ template<class Encoder>
+ void encode(Encoder& encoder) const
+ {
+ encoder << defaultFrameRate;
+ }
+
+ template <class Decoder>
+ static std::optional<MockDisplayProperties> decode(Decoder& decoder)
+ {
+ std::optional<double> defaultFrameRate;
+ decoder >> defaultFrameRate;
+ if (!defaultFrameRate)
+ return std::nullopt;
+
+ return MockDisplayProperties { *defaultFrameRate, Color::lightGray };
+ }
+
+ double defaultFrameRate { 30 };
+ Color fillColor { Color::lightGray };
+};
+
+struct MockMediaDevice {
+ bool isMicrophone() const { return WTF::holds_alternative<MockMicrophoneProperties>(properties); }
+ bool isCamera() const { return WTF::holds_alternative<MockCameraProperties>(properties); }
+ bool isDisplay() const { return WTF::holds_alternative<MockDisplayProperties>(properties); }
+
+ CaptureDevice::DeviceType type() const
+ {
+ if (isMicrophone())
+ return CaptureDevice::DeviceType::Microphone;
+ if (isCamera())
+ return CaptureDevice::DeviceType::Camera;
+ ASSERT(isDisplay());
+ return CaptureDevice::DeviceType::Screen;
+ }
+
+ template<class Encoder>
+ void encode(Encoder& encoder) const
+ {
+ encoder << persistentId;
+ encoder << label;
+ switchOn(properties, [&](const MockMicrophoneProperties& properties) {
+ encoder << (uint8_t)1;
+ encoder << properties;
+ }, [&](const MockCameraProperties& properties) {
+ encoder << (uint8_t)2;
+ encoder << properties;
+ }, [&](const MockDisplayProperties& properties) {
+ encoder << (uint8_t)3;
+ encoder << properties;
+ });
+ }
+
+ template <typename Properties, typename Decoder>
+ static std::optional<MockMediaDevice> decodeMockMediaDevice(Decoder& decoder, String&& persistentId, String&& label)
+ {
+ std::optional<Properties> properties;
+ decoder >> properties;
+ if (!properties)
+ return std::nullopt;
+ return MockMediaDevice { WTFMove(persistentId), WTFMove(label), WTFMove(*properties) };
+ }
+
+ template <class Decoder>
+ static std::optional<MockMediaDevice> decode(Decoder& decoder)
+ {
+ std::optional<String> persistentId;
+ decoder >> persistentId;
+ if (!persistentId)
+ return std::nullopt;
+
+ std::optional<String> label;
+ decoder >> label;
+ if (!label)
+ return std::nullopt;
+
+ std::optional<uint8_t> index;
+ decoder >> index;
+ if (!index)
+ return std::nullopt;
+
+ switch (*index) {
+ case 1:
+ return decodeMockMediaDevice<MockMicrophoneProperties>(decoder, WTFMove(*persistentId), WTFMove(*label));
+ case 2:
+ return decodeMockMediaDevice<MockCameraProperties>(decoder, WTFMove(*persistentId), WTFMove(*label));
+ case 3:
+ return decodeMockMediaDevice<MockDisplayProperties>(decoder, WTFMove(*persistentId), WTFMove(*label));
+ }
+ return std::nullopt;
+ }
+
+ String persistentId;
+ String label;
+ Variant<MockMicrophoneProperties, MockCameraProperties, MockDisplayProperties> properties;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
Modified: trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp (233161 => 233162)
--- trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp 2018-06-25 19:19:06 UTC (rev 233162)
@@ -118,7 +118,7 @@
#endif
if (!sampleRate())
- setSampleRate(device() == MockRealtimeMediaSource::MockDevice::Microphone1 ? 44100 : 48000);
+ setSampleRate(WTF::get<MockMicrophoneProperties>(device().properties).defaultSampleRate);
m_startTime = MonotonicTime::now();
m_timer.startRepeating(renderInterval());
Modified: trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp (233161 => 233162)
--- trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp 2018-06-25 19:19:06 UTC (rev 233162)
@@ -44,116 +44,163 @@
namespace WebCore {
-struct MockDeviceInfo {
- ASCIILiteral id { ASCIILiteral::null() };
- CaptureDevice::DeviceType type;
- ASCIILiteral name { ASCIILiteral::null() };
- MockRealtimeMediaSource::MockDevice device;
-};
+static inline Vector<MockMediaDevice> defaultDevices()
+{
+ return Vector<MockMediaDevice> {
+ MockMediaDevice { "239c24b0-2b15-11e3-8224-0800200c9a66"_s, "Mock audio device 1"_s, MockMicrophoneProperties { 44100 } },
+ MockMediaDevice { "239c24b1-2b15-11e3-8224-0800200c9a66"_s, "Mock audio device 2"_s, MockMicrophoneProperties { 48000 } },
-static const HashMap<String, MockDeviceInfo>& deviceMap()
+ MockMediaDevice { "239c24b2-2b15-11e3-8224-0800200c9a66"_s, "Mock video device 1"_s, MockCameraProperties { 30, RealtimeMediaSourceSettings::VideoFacingMode::User, Color::black } },
+ MockMediaDevice { "239c24b3-2b15-11e3-8224-0800200c9a66"_s, "Mock video device 2"_s, MockCameraProperties { 15, RealtimeMediaSourceSettings::VideoFacingMode::Environment, Color::darkGray } },
+
+ MockMediaDevice { "SCREEN-1"_s, "Mock screen device 1"_s, MockDisplayProperties { 30, Color::lightGray } },
+ MockMediaDevice { "SCREEN-2"_s, "Mock screen device 2"_s, MockDisplayProperties { 10, Color::yellow } }
+ };
+}
+
+static Vector<MockMediaDevice>& devices()
{
- static const auto infoMap = makeNeverDestroyed([] {
- static const MockDeviceInfo devices[] = {
- { "239c24b0-2b15-11e3-8224-0800200c9a66"_s, CaptureDevice::DeviceType::Microphone, "Mock audio device 1"_s, MockRealtimeMediaSource::MockDevice::Microphone1 },
- { "239c24b1-2b15-11e3-8224-0800200c9a66"_s, CaptureDevice::DeviceType::Microphone, "Mock audio device 2"_s, MockRealtimeMediaSource::MockDevice::Microphone2 },
+ static auto devices = makeNeverDestroyed([] {
+ return defaultDevices();
+ }());
+ return devices;
+}
- { "239c24b2-2b15-11e3-8224-0800200c9a66"_s, CaptureDevice::DeviceType::Camera, "Mock video device 1"_s, MockRealtimeMediaSource::MockDevice::Camera1 },
- { "239c24b3-2b15-11e3-8224-0800200c9a66"_s, CaptureDevice::DeviceType::Camera, "Mock video device 2"_s, MockRealtimeMediaSource::MockDevice::Camera2 },
+static HashMap<String, MockMediaDevice>& deviceMap()
+{
+ static auto map = makeNeverDestroyed([] {
+ HashMap<String, MockMediaDevice> map;
+ for (auto& device : devices())
+ map.add(device.persistentId, device);
- { "SCREEN-1"_s, CaptureDevice::DeviceType::Screen, "Mock screen device 1"_s, MockRealtimeMediaSource::MockDevice::Screen1 },
- { "SCREEN-2"_s, CaptureDevice::DeviceType::Screen, "Mock screen device 2"_s, MockRealtimeMediaSource::MockDevice::Screen2 },
- };
-
- HashMap<String, MockDeviceInfo> map;
- for (auto& info : devices)
- map.add(info.id, info);
return map;
}());
+ return map;
+}
- return infoMap;
+static inline Vector<CaptureDevice>& deviceListForDevice(const MockMediaDevice& device)
+{
+ if (device.isMicrophone())
+ return MockRealtimeAudioSource::audioDevices();
+ if (device.isCamera())
+ return MockRealtimeAudioSource::videoDevices();
+
+ ASSERT(device.isDisplay());
+ return MockRealtimeAudioSource::displayDevices();
}
-std::optional<CaptureDevice> MockRealtimeMediaSource::captureDeviceWithPersistentID(CaptureDevice::DeviceType type, const String& id)
+void MockRealtimeMediaSource::createCaptureDevice(const MockMediaDevice& device)
{
- ASSERT(!id.isEmpty());
+ deviceListForDevice(device).append(captureDeviceWithPersistentID(device.type(), device.persistentId).value());
+}
- auto map = deviceMap();
- auto it = map.find(id);
- if (it != map.end() && it->value.type == type) {
- auto device = CaptureDevice(it->value.id, it->value.type, it->value.name);
- device.setEnabled(true);
- return WTFMove(device);
+void MockRealtimeMediaSource::resetDevices()
+{
+ setDevices(defaultDevices());
+}
+
+void MockRealtimeMediaSource::setDevices(Vector<MockMediaDevice>&& newMockDevices)
+{
+ audioDevices().clear();
+ videoDevices().clear();
+ displayDevices().clear();
+
+ auto& mockDevices = devices();
+ mockDevices = WTFMove(newMockDevices);
+
+ auto& map = deviceMap();
+ map.clear();
+
+ for (const auto& device : mockDevices) {
+ map.add(device.persistentId, device);
+ createCaptureDevice(device);
}
+}
- return std::nullopt;
+void MockRealtimeMediaSource::addDevice(const MockMediaDevice& device)
+{
+ devices().append(device);
+ deviceMap().set(device.persistentId, device);
+ createCaptureDevice(device);
}
-Vector<CaptureDevice>& MockRealtimeMediaSource::audioDevices()
+void MockRealtimeMediaSource::removeDevice(const String& persistentId)
{
- static auto info = makeNeverDestroyed([] {
- Vector<CaptureDevice> vector;
+ auto& map = deviceMap();
+ auto iterator = map.find(persistentId);
+ if (iterator == map.end())
+ return;
- auto captureDevice = captureDeviceWithPersistentID(CaptureDevice::DeviceType::Microphone, "239c24b0-2b15-11e3-8224-0800200c9a66"_s);
- ASSERT(captureDevice);
- vector.append(WTFMove(captureDevice.value()));
+ devices().removeFirstMatching([&persistentId](const auto& device) {
+ return device.persistentId == persistentId;
+ });
- captureDevice = captureDeviceWithPersistentID(CaptureDevice::DeviceType::Microphone, "239c24b1-2b15-11e3-8224-0800200c9a66"_s);
- ASSERT(captureDevice);
- vector.append(WTFMove(captureDevice.value()));
+ deviceListForDevice(iterator->value).removeFirstMatching([&persistentId](const auto& device) {
+ return device.persistentId() == persistentId;
+ });
- return vector;
- }());
- return info;
+ map.remove(iterator);
}
-Vector<CaptureDevice>& MockRealtimeMediaSource::videoDevices()
+std::optional<CaptureDevice> MockRealtimeMediaSource::captureDeviceWithPersistentID(CaptureDevice::DeviceType type, const String& id)
{
- static auto info = makeNeverDestroyed([] {
- Vector<CaptureDevice> vector;
+ ASSERT(!id.isEmpty());
- auto captureDevice = captureDeviceWithPersistentID(CaptureDevice::DeviceType::Camera, "239c24b2-2b15-11e3-8224-0800200c9a66"_s);
- ASSERT(captureDevice);
- vector.append(WTFMove(captureDevice.value()));
+ auto& map = deviceMap();
+ auto iterator = map.find(id);
+ if (iterator == map.end() || iterator->value.type() != type)
+ return std::nullopt;
- captureDevice = captureDeviceWithPersistentID(CaptureDevice::DeviceType::Camera, "239c24b3-2b15-11e3-8224-0800200c9a66"_s);
- ASSERT(captureDevice);
- vector.append(WTFMove(captureDevice.value()));
+ CaptureDevice device { iterator->value.persistentId, type, iterator->value.label };
+ device.setEnabled(true);
+ return WTFMove(device);
+}
- return vector;
+Vector<CaptureDevice>& MockRealtimeMediaSource::audioDevices()
+{
+ static auto audioDevices = makeNeverDestroyed([] {
+ Vector<CaptureDevice> audioDevices;
+ for (const auto& device : devices()) {
+ if (device.type() == CaptureDevice::DeviceType::Microphone)
+ audioDevices.append(captureDeviceWithPersistentID(CaptureDevice::DeviceType::Microphone, device.persistentId).value());
+ }
+ return audioDevices;
}());
- return info;
+ return audioDevices;
}
+Vector<CaptureDevice>& MockRealtimeMediaSource::videoDevices()
+{
+ static auto videoDevices = makeNeverDestroyed([] {
+ Vector<CaptureDevice> videoDevices;
+ for (const auto& device : devices()) {
+ if (device.type() == CaptureDevice::DeviceType::Camera)
+ videoDevices.append(captureDeviceWithPersistentID(CaptureDevice::DeviceType::Camera, device.persistentId).value());
+ }
+ return videoDevices;
+ }());
+ return videoDevices;
+}
+
Vector<CaptureDevice>& MockRealtimeMediaSource::displayDevices()
{
- static auto devices = makeNeverDestroyed([] {
- Vector<CaptureDevice> vector;
-
- auto captureDevice = captureDeviceWithPersistentID(CaptureDevice::DeviceType::Screen, "SCREEN-1"_s);
- ASSERT(captureDevice);
- vector.append(WTFMove(captureDevice.value()));
-
- captureDevice = captureDeviceWithPersistentID(CaptureDevice::DeviceType::Screen, "SCREEN-2"_s);
- ASSERT(captureDevice);
- vector.append(WTFMove(captureDevice.value()));
-
- return vector;
+ static auto displayDevices = makeNeverDestroyed([] {
+ Vector<CaptureDevice> displayDevices;
+ for (const auto& device : devices()) {
+ if (device.type() == CaptureDevice::DeviceType::Screen)
+ displayDevices.append(captureDeviceWithPersistentID(CaptureDevice::DeviceType::Screen, device.persistentId).value());
+ }
+ return displayDevices;
}());
- return devices;
+ return displayDevices;
}
MockRealtimeMediaSource::MockRealtimeMediaSource(const String& id, RealtimeMediaSource::Type type, const String& name)
: RealtimeMediaSource(id, type, name)
+ , m_device(deviceMap().get(id))
{
ASSERT(type != RealtimeMediaSource::Type::None);
-
- auto map = deviceMap();
- auto it = map.find(id);
- ASSERT(it != map.end());
-
- m_device = it->value.device;
setPersistentID(String(id));
}
Modified: trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.h (233161 => 233162)
--- trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.h 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.h 2018-06-25 19:19:06 UTC (rev 233162)
@@ -32,16 +32,21 @@
#if ENABLE(MEDIA_STREAM)
+#include "CaptureDevice.h"
+#include "MockMediaDevice.h"
#include "RealtimeMediaSource.h"
namespace WebCore {
-class CaptureDevice;
-
class MockRealtimeMediaSource : public RealtimeMediaSource {
public:
virtual ~MockRealtimeMediaSource() = default;
+ static void setDevices(Vector<MockMediaDevice>&&);
+ static void addDevice(const MockMediaDevice&);
+ static void removeDevice(const String& persistentId);
+ WEBCORE_EXPORT static void resetDevices();
+
static Vector<CaptureDevice>& audioDevices();
static Vector<CaptureDevice>& videoDevices();
static Vector<CaptureDevice>& displayDevices();
@@ -48,11 +53,11 @@
static std::optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType, const String&);
- enum class MockDevice { Invalid, Microphone1, Microphone2, Camera1, Camera2, Screen1, Screen2 };
-
protected:
MockRealtimeMediaSource(const String& id, Type, const String& name);
+ static void createCaptureDevice(const MockMediaDevice&);
+
virtual void updateSettings(RealtimeMediaSourceSettings&) = 0;
virtual void initializeCapabilities(RealtimeMediaSourceCapabilities&) = 0;
virtual void initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints&) = 0;
@@ -62,8 +67,8 @@
RealtimeMediaSourceSupportedConstraints& supportedConstraints();
- MockDevice device() const { return m_device; }
- MockDevice m_device { MockDevice::Invalid };
+ const MockMediaDevice& device() const { return m_device; }
+ MockMediaDevice m_device;
private:
void initializeCapabilities();
Modified: trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp (233161 => 233162)
--- trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp 2018-06-25 19:19:06 UTC (rev 233162)
@@ -37,16 +37,39 @@
namespace WebCore {
+MockRealtimeMediaSourceCenter& MockRealtimeMediaSourceCenter::singleton()
+{
+ static NeverDestroyed<MockRealtimeMediaSourceCenter> center;
+ return center;
+}
+
void MockRealtimeMediaSourceCenter::setMockRealtimeMediaSourceCenterEnabled(bool enabled)
{
- static NeverDestroyed<MockRealtimeMediaSourceCenter> center;
static bool active = false;
if (active != enabled) {
active = enabled;
- RealtimeMediaSourceCenter::setSharedStreamCenterOverride(enabled ? ¢er.get() : nullptr);
+ RealtimeMediaSourceCenter::setSharedStreamCenterOverride(enabled ? &singleton() : nullptr);
}
}
+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
#endif // ENABLE(MEDIA_STREAM)
Modified: trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h (233161 => 233162)
--- trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h 2018-06-25 19:19:06 UTC (rev 233162)
@@ -39,6 +39,10 @@
public:
WEBCORE_EXPORT static void setMockRealtimeMediaSourceCenterEnabled(bool);
+ WEBCORE_EXPORT static void setDevices(Vector<MockMediaDevice>&&);
+ WEBCORE_EXPORT static void addDevice(const MockMediaDevice&);
+ WEBCORE_EXPORT static void removeDevice(const String& persistentId);
+
static RealtimeMediaSource::VideoCaptureFactory& videoCaptureSourceFactory() { return MockRealtimeVideoSource::factory(); }
static RealtimeMediaSource::AudioCaptureFactory& audioCaptureSourceFactory() { return MockRealtimeAudioSource::factory(); }
@@ -46,6 +50,8 @@
MockRealtimeMediaSourceCenter() = default;
friend NeverDestroyed<MockRealtimeMediaSourceCenter>;
+ static MockRealtimeMediaSourceCenter& singleton();
+
RealtimeMediaSource::AudioCaptureFactory& audioFactory() final { return MockRealtimeAudioSource::factory(); }
RealtimeMediaSource::VideoCaptureFactory& videoFactory() final { return MockRealtimeVideoSource::factory(); }
Modified: trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp (233161 => 233162)
--- trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp 2018-06-25 19:19:06 UTC (rev 233162)
@@ -108,31 +108,18 @@
: MockRealtimeMediaSource(deviceID, RealtimeMediaSource::Type::Video, name)
, m_timer(RunLoop::current(), this, &MockRealtimeVideoSource::generateFrame)
{
- switch (device()) {
- case MockDevice::Camera1:
- setFrameRate(30);
- setFacingMode(RealtimeMediaSourceSettings::User);
- break;
- case MockDevice::Camera2:
- setFrameRate(15);
- setFacingMode(RealtimeMediaSourceSettings::Environment);
- break;
- case MockDevice::Screen1:
- setFrameRate(30);
- break;
- case MockDevice::Screen2:
- setFrameRate(10);
- break;
- case MockDevice::Microphone1:
- case MockDevice::Microphone2:
- case MockDevice::Invalid:
- ASSERT_NOT_REACHED();
- break;
- }
-
m_dashWidths.reserveInitialCapacity(2);
m_dashWidths.uncheckedAppend(6);
m_dashWidths.uncheckedAppend(6);
+
+ if (mockScreen()) {
+ setFrameRate(WTF::get<MockDisplayProperties>(device().properties).defaultFrameRate);
+ return;
+ }
+
+ auto& properties = WTF::get<MockCameraProperties>(device().properties);
+ setFrameRate(properties.defaultFrameRate);
+ setFacingMode(properties.facingModeCapability);
}
MockRealtimeVideoSource::~MockRealtimeVideoSource()
@@ -191,10 +178,7 @@
void MockRealtimeVideoSource::initializeCapabilities(RealtimeMediaSourceCapabilities& capabilities)
{
if (mockCamera()) {
- if (device() == MockDevice::Camera1)
- capabilities.addFacingMode(RealtimeMediaSourceSettings::User);
- else
- capabilities.addFacingMode(RealtimeMediaSourceSettings::Environment);
+ capabilities.addFacingMode(WTF::get<MockCameraProperties>(device().properties).facingModeCapability);
capabilities.setWidth(CapabilityValueOrRange(320, 1920));
capabilities.setHeight(CapabilityValueOrRange(240, 1080));
@@ -392,7 +376,7 @@
context.drawText(statsFont, TextRun((StringView(string))), statsLocation);
} else {
statsLocation.move(0, m_statsFontSize);
- context.drawText(statsFont, TextRun((StringView(device() == MockDevice::Screen1 ? "Screen 1" : "Screen 2"))), statsLocation);
+ context.drawText(statsFont, TextRun { id() }, statsLocation);
}
FloatPoint bipBopLocation(size.width() * .6, size.height() * .6);
@@ -431,27 +415,7 @@
auto& size = this->size();
FloatRect frameRect(FloatPoint(), size);
- Color fillColor;
- switch (device()) {
- case MockDevice::Camera1:
- fillColor = Color::black;
- break;
- case MockDevice::Camera2:
- fillColor = Color::darkGray;
- break;
- case MockDevice::Screen1:
- fillColor = Color::lightGray;
- break;
- case MockDevice::Screen2:
- fillColor = Color::yellow;
- break;
- case MockDevice::Microphone1:
- case MockDevice::Microphone2:
- case MockDevice::Invalid:
- ASSERT_NOT_REACHED();
- break;
- }
-
+ auto fillColor = mockCamera() ? WTF::get<MockCameraProperties>(device().properties).fillColor : WTF::get<MockDisplayProperties>(device().properties).fillColor;
context.fillRect(FloatRect(FloatPoint(), size), fillColor);
if (!muted()) {
Modified: trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.h (233161 => 233162)
--- trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.h 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.h 2018-06-25 19:19:06 UTC (rev 233162)
@@ -83,8 +83,8 @@
void delaySamples(Seconds) override;
- bool mockCamera() const { return device() == MockDevice::Camera1 || device() == MockDevice::Camera2; }
- bool mockScreen() const { return device() == MockDevice::Screen1 || device() == MockDevice::Screen2; }
+ bool mockCamera() const { return WTF::holds_alternative<MockCameraProperties>(device().properties); }
+ bool mockScreen() const { return WTF::holds_alternative<MockDisplayProperties>(device().properties); }
float m_baseFontSize { 0 };
float m_bipBopFontSize { 0 };
Modified: trunk/Source/WebKit/CMakeLists.txt (233161 => 233162)
--- trunk/Source/WebKit/CMakeLists.txt 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebKit/CMakeLists.txt 2018-06-25 19:19:06 UTC (rev 233162)
@@ -402,6 +402,7 @@
UIProcess/API/C/WKInspector.cpp
UIProcess/API/C/WKKeyValueStorageManager.cpp
UIProcess/API/C/WKMediaSessionMetadata.cpp
+ UIProcess/API/C/WKMockMediaDevice.cpp
UIProcess/API/C/WKNavigationActionRef.cpp
UIProcess/API/C/WKNavigationDataRef.cpp
UIProcess/API/C/WKNavigationRef.cpp
Modified: trunk/Source/WebKit/ChangeLog (233161 => 233162)
--- trunk/Source/WebKit/ChangeLog 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebKit/ChangeLog 2018-06-25 19:19:06 UTC (rev 233162)
@@ -1,3 +1,36 @@
+2018-06-25 Youenn Fablet <you...@apple.com>
+
+ Add API to control mock media devices
+ https://bugs.webkit.org/show_bug.cgi?id=186958
+
+ Reviewed by Eric Carlson.
+
+ Add API to clear, set, remove and reset mock media devices.
+ The mock media center of UIProcess and all WebProcesses are updated.
+
+ * CMakeLists.txt:
+ * UIProcess/API/C/WKMockMediaDevice.cpp: Added.
+ (typeFromString):
+ (WKAddMockMediaDevice):
+ (WKClearMockMediaDevices):
+ (WKRemoveMockMediaDevice):
+ (WKResetMockMediaDevices):
+ * UIProcess/API/C/WKMockMediaDevice.h: Added.
+ * UIProcess/WebProcessPool.cpp:
+ (WebKit::WebProcessPool::addMockMediaDevice):
+ (WebKit::WebProcessPool::clearMockMediaDevices):
+ (WebKit::WebProcessPool::removeMockMediaDevice):
+ (WebKit::WebProcessPool::resetMockMediaDevices):
+ * UIProcess/WebProcessPool.h:
+ * WebKit.xcodeproj/project.pbxproj:
+ * WebProcess/WebProcess.cpp:
+ (WebKit::WebProcess::addMockMediaDevice):
+ (WebKit::WebProcess::clearMockMediaDevices):
+ (WebKit::WebProcess::removeMockMediaDevice):
+ (WebKit::WebProcess::resetMockMediaDevices):
+ * WebProcess/WebProcess.h:
+ * WebProcess/WebProcess.messages.in:
+
2018-06-25 Wenson Hsieh <wenson_hs...@apple.com>
[iPad apps on macOS] Click events are broken in WKWebView
Added: trunk/Source/WebKit/UIProcess/API/C/WKMockMediaDevice.cpp (0 => 233162)
--- trunk/Source/WebKit/UIProcess/API/C/WKMockMediaDevice.cpp (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/C/WKMockMediaDevice.cpp 2018-06-25 19:19:06 UTC (rev 233162)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+#include "WKMockMediaDevice.h"
+
+#include "WKAPICast.h"
+#include "WKString.h"
+#include "WebProcessPool.h"
+#include <WebCore/MockMediaDevice.h>
+
+using namespace WebKit;
+
+void WKAddMockMediaDevice(WKContextRef context, WKStringRef persistentId, WKStringRef label, WKStringRef type)
+{
+#if ENABLE(MEDIA_STREAM)
+ String typeString = WebKit::toImpl(type)->string();
+ Variant<WebCore::MockMicrophoneProperties, WebCore::MockCameraProperties, WebCore::MockDisplayProperties> properties;
+ if (typeString == "camera")
+ properties = WebCore::MockCameraProperties { };
+ else if (typeString == "screen")
+ properties = WebCore::MockDisplayProperties { };
+ else if (typeString != "microphone")
+ return;
+
+ toImpl(context)->addMockMediaDevice({ WebKit::toImpl(persistentId)->string(), WebKit::toImpl(label)->string(), WTFMove(properties) });
+#endif
+}
+
+void WKClearMockMediaDevices(WKContextRef context)
+{
+ toImpl(context)->clearMockMediaDevices();
+}
+
+void WKRemoveMockMediaDevice(WKContextRef context, WKStringRef persistentId)
+{
+ toImpl(context)->removeMockMediaDevice(WebKit::toImpl(persistentId)->string());
+}
+
+void WKResetMockMediaDevices(WKContextRef context)
+{
+ toImpl(context)->resetMockMediaDevices();
+}
Copied: trunk/Source/WebKit/UIProcess/API/C/WKMockMediaDevice.h (from rev 233161, trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp) (0 => 233162)
--- trunk/Source/WebKit/UIProcess/API/C/WKMockMediaDevice.h (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/C/WKMockMediaDevice.h 2018-06-25 19:19:06 UTC (rev 233162)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#include <WebKit/WKBase.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+WK_EXPORT void WKAddMockMediaDevice(WKContextRef, WKStringRef persistentId, WKStringRef label, WKStringRef type);
+WK_EXPORT void WKClearMockMediaDevices(WKContextRef);
+WK_EXPORT void WKRemoveMockMediaDevice(WKContextRef, WKStringRef persistentId);
+WK_EXPORT void WKResetMockMediaDevices(WKContextRef);
+
+#ifdef __cplusplus
+}
+#endif
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (233161 => 233162)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2018-06-25 19:19:06 UTC (rev 233162)
@@ -82,6 +82,7 @@
#include <_javascript_Core/JSCInlines.h>
#include <WebCore/ApplicationCacheStorage.h>
#include <WebCore/LogInitialization.h>
+#include <WebCore/MockRealtimeMediaSourceCenter.h>
#include <WebCore/NetworkStorageSession.h>
#include <WebCore/PlatformScreen.h>
#include <WebCore/Process.h>
@@ -2212,4 +2213,36 @@
m_suspendedPages.remove(iterator);
}
+void WebProcessPool::addMockMediaDevice(const MockMediaDevice& device)
+{
+#if ENABLE(MEDIA_STREAM)
+ MockRealtimeMediaSourceCenter::addDevice(device);
+ sendToAllProcesses(Messages::WebProcess::AddMockMediaDevice { device });
+#endif
+}
+
+void WebProcessPool::clearMockMediaDevices()
+{
+#if ENABLE(MEDIA_STREAM)
+ MockRealtimeMediaSourceCenter::setDevices({ });
+ sendToAllProcesses(Messages::WebProcess::ClearMockMediaDevices { });
+#endif
+}
+
+void WebProcessPool::removeMockMediaDevice(const String& persistentId)
+{
+#if ENABLE(MEDIA_STREAM)
+ MockRealtimeMediaSourceCenter::removeDevice(persistentId);
+ sendToAllProcesses(Messages::WebProcess::RemoveMockMediaDevice { persistentId });
+#endif
+}
+
+void WebProcessPool::resetMockMediaDevices()
+{
+#if ENABLE(MEDIA_STREAM)
+ MockRealtimeMediaSource::resetDevices();
+ sendToAllProcesses(Messages::WebProcess::ResetMockMediaDevices { });
+#endif
+}
+
} // namespace WebKit
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (233161 => 233162)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.h 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h 2018-06-25 19:19:06 UTC (rev 233162)
@@ -82,6 +82,10 @@
class PageConfiguration;
}
+namespace WebCore {
+struct MockMediaDevice;
+}
+
namespace WebKit {
class DownloadProxy;
@@ -454,6 +458,11 @@
void screenPropertiesStateChanged();
+ void addMockMediaDevice(const WebCore::MockMediaDevice&);
+ void clearMockMediaDevices();
+ void removeMockMediaDevice(const String& persistentId);
+ void resetMockMediaDevices();
+
private:
void platformInitialize();
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (233161 => 233162)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2018-06-25 19:19:06 UTC (rev 233162)
@@ -913,6 +913,8 @@
410482CE1DDD324F00F006D0 /* RTCNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 410482CC1DDD2FB500F006D0 /* RTCNetwork.h */; };
4112B5551FA0EA7A00E67875 /* NetworkRTCResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4112B5471F9FD3AB00E67875 /* NetworkRTCResolver.cpp */; };
4112B5551FA0EA7A00E67986 /* NetworkRTCResolverCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4112B5471F9FD3AB00E67986 /* NetworkRTCResolverCocoa.cpp */; };
+ 411A8DDB20DDD1AC0060D34F /* WKMockMediaDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 411A8DD920DDB6050060D34F /* WKMockMediaDevice.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 411A8DDC20DDD23F0060D34F /* WKMockMediaDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 411A8DDA20DDB6050060D34F /* WKMockMediaDevice.cpp */; };
411B22641E371BA6004F7363 /* LibWebRTCNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 411B22621E371244004F7363 /* LibWebRTCNetwork.h */; };
413075A91DE85F2C0039EC69 /* NetworkRTCSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 413075981DE84FB00039EC69 /* NetworkRTCSocket.cpp */; };
413075AA1DE85F300039EC69 /* NetworkRTCMonitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4130759A1DE84FB00039EC69 /* NetworkRTCMonitor.cpp */; };
@@ -3299,6 +3301,8 @@
4112B5471F9FD3AB00E67986 /* NetworkRTCResolverCocoa.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkRTCResolverCocoa.cpp; path = NetworkProcess/webrtc/NetworkRTCResolverCocoa.cpp; sourceTree = "<group>"; };
4112B5481F9FD3AC00E67875 /* NetworkRTCResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkRTCResolver.h; path = NetworkProcess/webrtc/NetworkRTCResolver.h; sourceTree = "<group>"; };
4112B5481F9FD3AC00E67986 /* NetworkRTCResolverCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkRTCResolverCocoa.h; path = NetworkProcess/webrtc/NetworkRTCResolverCocoa.h; sourceTree = "<group>"; };
+ 411A8DD920DDB6050060D34F /* WKMockMediaDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKMockMediaDevice.h; sourceTree = "<group>"; };
+ 411A8DDA20DDB6050060D34F /* WKMockMediaDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKMockMediaDevice.cpp; sourceTree = "<group>"; };
411B22621E371244004F7363 /* LibWebRTCNetwork.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LibWebRTCNetwork.h; path = Network/webrtc/LibWebRTCNetwork.h; sourceTree = "<group>"; };
413075981DE84FB00039EC69 /* NetworkRTCSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkRTCSocket.cpp; path = NetworkProcess/webrtc/NetworkRTCSocket.cpp; sourceTree = "<group>"; };
413075991DE84FB00039EC69 /* NetworkRTCSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkRTCSocket.h; path = NetworkProcess/webrtc/NetworkRTCSocket.h; sourceTree = "<group>"; };
@@ -7572,6 +7576,8 @@
C98C48A81B6FD5B500145103 /* WKMediaSessionFocusManager.h */,
C9CD43991B4B024200239E33 /* WKMediaSessionMetadata.cpp */,
C9CD439A1B4B024200239E33 /* WKMediaSessionMetadata.h */,
+ 411A8DDA20DDB6050060D34F /* WKMockMediaDevice.cpp */,
+ 411A8DD920DDB6050060D34F /* WKMockMediaDevice.h */,
C09AE5E8125257C20025825D /* WKNativeEvent.h */,
2D3A65D81A7C3A1F00CAC637 /* WKNavigationActionRef.cpp */,
2D3A65D91A7C3A1F00CAC637 /* WKNavigationActionRef.h */,
@@ -9643,6 +9649,7 @@
C98C48AA1B6FD5B500145103 /* WKMediaSessionFocusManager.h in Headers */,
C9CD439D1B4B024F00239E33 /* WKMediaSessionMetadata.h in Headers */,
1AB40EE61BF677E300BA81BE /* WKMenuItemIdentifiersPrivate.h in Headers */,
+ 411A8DDB20DDD1AC0060D34F /* WKMockMediaDevice.h in Headers */,
BC4075FE124FF0270068F20A /* WKMutableArray.h in Headers */,
BC407600124FF0270068F20A /* WKMutableDictionary.h in Headers */,
C09AE5E9125257C20025825D /* WKNativeEvent.h in Headers */,
@@ -10358,13 +10365,9 @@
buildActionMask = 2147483647;
files = (
);
- inputFileListPaths = (
- );
inputPaths = (
);
name = "Unlock keychain";
- outputFileListPaths = (
- );
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
@@ -10376,13 +10379,9 @@
buildActionMask = 2147483647;
files = (
);
- inputFileListPaths = (
- );
inputPaths = (
);
name = "Unlock keychain";
- outputFileListPaths = (
- );
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
@@ -10394,13 +10393,9 @@
buildActionMask = 2147483647;
files = (
);
- inputFileListPaths = (
- );
inputPaths = (
);
name = "Remove stale entitlement file";
- outputFileListPaths = (
- );
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
@@ -10412,13 +10407,9 @@
buildActionMask = 2147483647;
files = (
);
- inputFileListPaths = (
- );
inputPaths = (
);
name = "Remove stale entitlement file";
- outputFileListPaths = (
- );
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
@@ -10430,14 +10421,10 @@
buildActionMask = 2147483647;
files = (
);
- inputFileListPaths = (
- );
inputPaths = (
"$(TEMP_FILE_DIR)/$(FULL_PRODUCT_NAME).xcent",
);
name = "Process WebContent entitlements";
- outputFileListPaths = (
- );
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
@@ -10449,14 +10436,10 @@
buildActionMask = 2147483647;
files = (
);
- inputFileListPaths = (
- );
inputPaths = (
"$(TEMP_FILE_DIR)/$(FULL_PRODUCT_NAME).xcent",
);
name = "Process WebContent entitlements";
- outputFileListPaths = (
- );
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
@@ -11465,6 +11448,7 @@
C98C48A91B6FD5B500145103 /* WKMediaSessionFocusManager.cpp in Sources */,
C9CD439E1B4B025300239E33 /* WKMediaSessionMetadata.cpp in Sources */,
1AB40EE51BF677E300BA81BE /* WKMenuItemIdentifiers.mm in Sources */,
+ 411A8DDC20DDD23F0060D34F /* WKMockMediaDevice.cpp in Sources */,
BC4075FD124FF0270068F20A /* WKMutableArray.cpp in Sources */,
BC4075FF124FF0270068F20A /* WKMutableDictionary.cpp in Sources */,
1A5B1C501898606F004FCF9B /* WKNavigation.mm in Sources */,
Modified: trunk/Source/WebKit/WebProcess/WebProcess.cpp (233161 => 233162)
--- trunk/Source/WebKit/WebProcess/WebProcess.cpp 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebKit/WebProcess/WebProcess.cpp 2018-06-25 19:19:06 UTC (rev 233162)
@@ -101,6 +101,7 @@
#include <WebCore/MemoryCache.h>
#include <WebCore/MemoryRelease.h>
#include <WebCore/MessagePort.h>
+#include <WebCore/MockRealtimeMediaSourceCenter.h>
#include <WebCore/NetworkStorageSession.h>
#include <WebCore/Page.h>
#include <WebCore/PageCache.h>
@@ -1690,4 +1691,26 @@
}
#endif
+#if ENABLE(MEDIA_STREAM)
+void WebProcess::addMockMediaDevice(const WebCore::MockMediaDevice& device)
+{
+ MockRealtimeMediaSourceCenter::addDevice(device);
+}
+
+void WebProcess::clearMockMediaDevices()
+{
+ MockRealtimeMediaSourceCenter::setDevices({ });
+}
+
+void WebProcess::removeMockMediaDevice(const String& persistentId)
+{
+ MockRealtimeMediaSourceCenter::removeDevice(persistentId);
+}
+
+void WebProcess::resetMockMediaDevices()
+{
+ MockRealtimeMediaSource::resetDevices();
+}
+#endif
+
} // namespace WebKit
Modified: trunk/Source/WebKit/WebProcess/WebProcess.h (233161 => 233162)
--- trunk/Source/WebKit/WebProcess/WebProcess.h 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebKit/WebProcess/WebProcess.h 2018-06-25 19:19:06 UTC (rev 233162)
@@ -69,6 +69,7 @@
class UserGestureToken;
struct MessagePortIdentifier;
struct MessageWithMessagePorts;
+struct MockMediaDevice;
struct PluginInfo;
struct SecurityOriginData;
struct SoupNetworkProxySettings;
@@ -359,6 +360,13 @@
void stopRunLoop() override;
#endif
+#if ENABLE(MEDIA_STREAM)
+ void addMockMediaDevice(const WebCore::MockMediaDevice&);
+ void clearMockMediaDevices();
+ void removeMockMediaDevice(const String& persistentId);
+ void resetMockMediaDevices();
+#endif
+
void platformInitializeProcess(const ChildProcessInitializationParameters&);
// IPC::Connection::Client
Modified: trunk/Source/WebKit/WebProcess/WebProcess.messages.in (233161 => 233162)
--- trunk/Source/WebKit/WebProcess/WebProcess.messages.in 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Source/WebKit/WebProcess/WebProcess.messages.in 2018-06-25 19:19:06 UTC (rev 233162)
@@ -139,4 +139,11 @@
#if PLATFORM(COCOA)
SetMediaMIMETypes(Vector<String> types)
#endif
+
+#if ENABLE(MEDIA_STREAM)
+ AddMockMediaDevice(struct WebCore::MockMediaDevice device);
+ ClearMockMediaDevices();
+ RemoveMockMediaDevice(String persistentId);
+ ResetMockMediaDevices();
+#endif
}
Modified: trunk/Tools/ChangeLog (233161 => 233162)
--- trunk/Tools/ChangeLog 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Tools/ChangeLog 2018-06-25 19:19:06 UTC (rev 233162)
@@ -1,3 +1,31 @@
+2018-06-25 Youenn Fablet <you...@apple.com>
+
+ Add API to control mock media devices
+ https://bugs.webkit.org/show_bug.cgi?id=186958
+
+ Reviewed by Eric Carlson.
+
+ Add test runner API to clear/add/remove/reset mock media devices.
+
+ * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+ * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+ (WTR::TestRunner::addMockMediaDevice):
+ (WTR::TestRunner::addMockCameraDevice):
+ (WTR::TestRunner::addMockMicrophoneDevice):
+ (WTR::TestRunner::addMockScreenDevice):
+ (WTR::TestRunner::clearMockMediaDevices):
+ (WTR::TestRunner::removeMockMediaDevice):
+ (WTR::TestRunner::resetMockMediaDevices):
+ * WebKitTestRunner/InjectedBundle/TestRunner.h:
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::addMockMediaDevice):
+ (WTR::TestController::clearMockMediaDevices):
+ (WTR::TestController::removeMockMediaDevice):
+ (WTR::TestController::resetMockMediaDevices):
+ * WebKitTestRunner/TestController.h:
+ * WebKitTestRunner/TestInvocation.cpp:
+ (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+
2018-06-25 Aakash Jain <aakash_j...@apple.com>
[ews-build] Add support for try Buildbot try schedulers
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (233161 => 233162)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2018-06-25 19:19:06 UTC (rev 233162)
@@ -336,4 +336,11 @@
void getApplicationManifestThen(object callback);
void installFakeHelvetica(DOMString configuration);
+
+ void addMockCameraDevice(DOMString persistentId, DOMString label);
+ void addMockMicrophoneDevice(DOMString persistentId, DOMString label);
+ void addMockScreenDevice(DOMString persistentId, DOMString label);
+ void clearMockMediaDevices();
+ void removeMockMediaDevice(DOMString persistentId);
+ void resetMockMediaDevices();
};
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (233161 => 233162)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp 2018-06-25 19:19:06 UTC (rev 233162)
@@ -1971,6 +1971,71 @@
callTestRunnerCallback(AllStorageAccessEntriesCallbackID, 1, &result);
}
+void TestRunner::addMockMediaDevice(JSStringRef persistentId, JSStringRef label, const char* type)
+{
+ Vector<WKRetainPtr<WKStringRef>> keys;
+ Vector<WKRetainPtr<WKTypeRef>> values;
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("PersistentID") });
+ values.append(toWK(persistentId));
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("Label") });
+ values.append(toWK(label));
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("Type") });
+ values.append({ AdoptWK, WKStringCreateWithUTF8CString(type) });
+
+ Vector<WKStringRef> rawKeys;
+ Vector<WKTypeRef> rawValues;
+ rawKeys.resize(keys.size());
+ rawValues.resize(values.size());
+
+ for (size_t i = 0; i < keys.size(); ++i) {
+ rawKeys[i] = keys[i].get();
+ rawValues[i] = values[i].get();
+ }
+
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("AddMockMediaDevice"));
+ WKRetainPtr<WKDictionaryRef> messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size()));
+
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::addMockCameraDevice(JSStringRef persistentId, JSStringRef label)
+{
+ addMockMediaDevice(persistentId, label, "camera");
+}
+
+void TestRunner::addMockMicrophoneDevice(JSStringRef persistentId, JSStringRef label)
+{
+ addMockMediaDevice(persistentId, label, "microphone");
+}
+
+void TestRunner::addMockScreenDevice(JSStringRef persistentId, JSStringRef label)
+{
+ addMockMediaDevice(persistentId, label, "screen");
+}
+
+void TestRunner::clearMockMediaDevices()
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("ClearMockMediaDevices"));
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr);
+}
+
+void TestRunner::removeMockMediaDevice(JSStringRef persistentId)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("RemoveMockMediaDevice"));
+ WKRetainPtr<WKTypeRef> messageBody(toWK(persistentId));
+
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::resetMockMediaDevices()
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("ResetMockMediaDevices"));
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr);
+}
+
#if PLATFORM(MAC)
void TestRunner::connectMockGamepad(unsigned index)
{
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (233161 => 233162)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2018-06-25 19:19:06 UTC (rev 233162)
@@ -446,6 +446,13 @@
void dumpAllHTTPRedirectedResponseHeaders() { m_dumpAllHTTPRedirectedResponseHeaders = true; }
bool shouldDumpAllHTTPRedirectedResponseHeaders() const { return m_dumpAllHTTPRedirectedResponseHeaders; }
+ void addMockCameraDevice(JSStringRef persistentId, JSStringRef label);
+ void addMockMicrophoneDevice(JSStringRef persistentId, JSStringRef label);
+ void addMockScreenDevice(JSStringRef persistentId, JSStringRef label);
+ void clearMockMediaDevices();
+ void removeMockMediaDevice(JSStringRef persistentId);
+ void resetMockMediaDevices();
+
private:
TestRunner();
@@ -455,6 +462,8 @@
void setDumpPixels(bool);
void setWaitUntilDone(bool);
+ void addMockMediaDevice(JSStringRef persistentId, JSStringRef label, const char* type);
+
WKRetainPtr<WKURLRef> m_testURL; // Set by InjectedBundlePage once provisional load starts.
bool m_shouldDumpAllFrameScrollPositions;
Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (233161 => 233162)
--- trunk/Tools/WebKitTestRunner/TestController.cpp 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp 2018-06-25 19:19:06 UTC (rev 233162)
@@ -43,6 +43,7 @@
#include <WebKit/WKFrameHandleRef.h>
#include <WebKit/WKFrameInfoRef.h>
#include <WebKit/WKIconDatabase.h>
+#include <WebKit/WKMockMediaDevice.h>
#include <WebKit/WKNavigationResponseRef.h>
#include <WebKit/WKNotification.h>
#include <WebKit/WKNotificationManager.h>
@@ -2866,6 +2867,26 @@
WKWebsiteDataStoreStatisticsResetToConsistentState(dataStore);
}
+void TestController::addMockMediaDevice(WKStringRef persistentID, WKStringRef label, WKStringRef type)
+{
+ WKAddMockMediaDevice(platformContext(), persistentID, label, type);
+}
+
+void TestController::clearMockMediaDevices()
+{
+ WKClearMockMediaDevices(platformContext());
+}
+
+void TestController::removeMockMediaDevice(WKStringRef persistentID)
+{
+ WKRemoveMockMediaDevice(platformContext(), persistentID);
+}
+
+void TestController::resetMockMediaDevices()
+{
+ WKResetMockMediaDevices(platformContext());
+}
+
#if !PLATFORM(COCOA)
void TestController::platformAddTestOptions(TestOptions&) const
{
Modified: trunk/Tools/WebKitTestRunner/TestController.h (233161 => 233162)
--- trunk/Tools/WebKitTestRunner/TestController.h 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Tools/WebKitTestRunner/TestController.h 2018-06-25 19:19:06 UTC (rev 233162)
@@ -213,6 +213,11 @@
bool didReceiveServerRedirectForProvisionalNavigation() const { return m_didReceiveServerRedirectForProvisionalNavigation; }
void clearDidReceiveServerRedirectForProvisionalNavigation() { m_didReceiveServerRedirectForProvisionalNavigation = false; }
+ void addMockMediaDevice(WKStringRef persistentID, WKStringRef label, WKStringRef type);
+ void clearMockMediaDevices();
+ void removeMockMediaDevice(WKStringRef persistentID);
+ void resetMockMediaDevices();
+
private:
WKRetainPtr<WKPageConfigurationRef> generatePageConfiguration(WKContextConfigurationRef);
WKRetainPtr<WKContextConfigurationRef> generateContextConfiguration() const;
Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (233161 => 233162)
--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2018-06-25 18:53:34 UTC (rev 233161)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2018-06-25 19:19:06 UTC (rev 233162)
@@ -916,6 +916,39 @@
return nullptr;
}
+ if (WKStringIsEqualToUTF8CString(messageName, "AddMockMediaDevice")) {
+ ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+
+ WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+ WKRetainPtr<WKStringRef> persistentIDKey(AdoptWK, WKStringCreateWithUTF8CString("PersistentID"));
+ WKRetainPtr<WKStringRef> labelKey(AdoptWK, WKStringCreateWithUTF8CString("Label"));
+ WKRetainPtr<WKStringRef> typeKey(AdoptWK, WKStringCreateWithUTF8CString("Type"));
+
+ auto persistentID = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, persistentIDKey.get()));
+ auto label = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, labelKey.get()));
+ auto type = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, typeKey.get()));
+
+ TestController::singleton().addMockMediaDevice(persistentID, label, type);
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "ClearMockMediaDevices")) {
+ TestController::singleton().clearMockMediaDevices();
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "RemoveMockMediaDevice")) {
+ WKStringRef persistentId = static_cast<WKStringRef>(messageBody);
+
+ TestController::singleton().removeMockMediaDevice(persistentId);
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "ResetMockMediaDevices")) {
+ TestController::singleton().resetMockMediaDevices();
+ return nullptr;
+ }
+
#if PLATFORM(MAC)
if (WKStringIsEqualToUTF8CString(messageName, "ConnectMockGamepad")) {
ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());