Unreviewed, rolling out r218530.
authorjlewis3@apple.com <jlewis3@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Jun 2017 17:53:17 +0000 (17:53 +0000)
committerjlewis3@apple.com <jlewis3@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Jun 2017 17:53:17 +0000 (17:53 +0000)
This revision caused multiple media stream test crashes on
Debug builds.

Reverted changeset:

"Merge MediaDevicesRequest and MediaDevicesEnumerationRequest
to tighten up code and object lifetime"
https://bugs.webkit.org/show_bug.cgi?id=173527
http://trac.webkit.org/changeset/218530

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@218601 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/MediaDeviceInfo.cpp
Source/WebCore/Modules/mediastream/MediaDeviceInfo.h
Source/WebCore/Modules/mediastream/MediaDeviceInfo.idl
Source/WebCore/Modules/mediastream/MediaDevices.cpp
Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.cpp
Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.h
Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp [new file with mode: 0644]
Source/WebCore/Modules/mediastream/MediaDevicesRequest.h [new file with mode: 0644]
Source/WebCore/Modules/mediastream/UserMediaController.cpp
Source/WebCore/Modules/mediastream/UserMediaController.h
Source/WebCore/Modules/mediastream/UserMediaRequest.cpp
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/testing/Internals.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.h
Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp
Source/WebKit2/WebProcess/WebCoreSupport/WebUserMediaClient.cpp

index e2eaa90..8b9acda 100644 (file)
@@ -964,6 +964,7 @@ set(WebCore_SOURCES
     Modules/mediastream/MediaDeviceInfo.cpp
     Modules/mediastream/MediaDevices.cpp
     Modules/mediastream/MediaDevicesEnumerationRequest.cpp
+    Modules/mediastream/MediaDevicesRequest.cpp
     Modules/mediastream/MediaEndpointPeerConnection.cpp
     Modules/mediastream/MediaEndpointSessionDescription.cpp
     Modules/mediastream/MediaStream.cpp
index 2fd8acc..78ccd1d 100644 (file)
@@ -1,3 +1,17 @@
+2017-06-20  Matt Lewis  <jlewis3@apple.com>
+
+        Unreviewed, rolling out r218530.
+
+        This revision caused multiple media stream test crashes on
+        Debug builds.
+
+        Reverted changeset:
+
+        "Merge MediaDevicesRequest and MediaDevicesEnumerationRequest
+        to tighten up code and object lifetime"
+        https://bugs.webkit.org/show_bug.cgi?id=173527
+        http://trac.webkit.org/changeset/218530
+
 2017-06-19  Antoine Quint  <graouts@apple.com>
 
         Media document experience with long-loading files is poor
index ebcab75..fe760d9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace WebCore {
 
-inline MediaDeviceInfo::MediaDeviceInfo(const String& label, const String& deviceId, const String& groupId, Kind kind)
-    : m_label(label)
+inline MediaDeviceInfo::MediaDeviceInfo(ScriptExecutionContext* context, const String& label, const String& deviceId, const String& groupId, Kind kind)
+    : ContextDestructionObserver(context)
+    , m_label(label)
     , m_deviceId(deviceId)
     , m_groupId(groupId)
     , m_kind(kind)
 {
 }
 
-Ref<MediaDeviceInfo> MediaDeviceInfo::create(const String& label, const String& deviceId, const String& groupId, Kind kind)
+Ref<MediaDeviceInfo> MediaDeviceInfo::create(ScriptExecutionContext* context, const String& label, const String& deviceId, const String& groupId, Kind kind)
 {
-    return adoptRef(*new MediaDeviceInfo(label, deviceId, groupId, kind));
+    return adoptRef(*new MediaDeviceInfo(context, label, deviceId, groupId, kind));
 }
 
 } // namespace WebCore
index 08f9b56..fc68904 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(MEDIA_STREAM)
 
+#include "ContextDestructionObserver.h"
 #include "ScriptWrappable.h"
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
-class MediaDeviceInfo : public RefCounted<MediaDeviceInfo>, public ScriptWrappable {
+class MediaDeviceInfo : public RefCounted<MediaDeviceInfo>, public ScriptWrappable, private ContextDestructionObserver {
 public:
     enum class Kind { Audioinput, Audiooutput, Videoinput };
 
-    static Ref<MediaDeviceInfo> create(const String& label, const String& deviceId, const String& groupId, Kind);
+    static Ref<MediaDeviceInfo> create(ScriptExecutionContext*, const String&, const String&, const String&, Kind);
 
     const String& label() const { return m_label; }
     const String& deviceId() const { return m_deviceId; }
@@ -44,7 +45,7 @@ public:
     Kind kind() const { return m_kind; }
 
 private:
-    MediaDeviceInfo(const String& label, const String& deviceId, const String& groupId, Kind);
+    MediaDeviceInfo(ScriptExecutionContext*, const String&, const String&, const String&, Kind);
 
     const String m_label;
     const String m_deviceId;
@@ -52,6 +53,8 @@ private:
     const Kind m_kind;
 };
 
+typedef Vector<RefPtr<MediaDeviceInfo>> MediaDeviceInfoVector;
+
 }
 
 #endif
index d667278..d2b2c9f 100644 (file)
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2015-2017 Apple Inc. All rights reserved.
+* Copyright (C) 2015 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
@@ -25,7 +25,6 @@
 
 [
     Conditional=MEDIA_STREAM,
-    ImplementationLacksVTable,
     JSGenerateToJSObject,
 ] interface MediaDeviceInfo {
     readonly attribute DOMString deviceId;
index 09cd8b4..41e595d 100644 (file)
@@ -37,7 +37,7 @@
 #include "Document.h"
 #include "Event.h"
 #include "EventNames.h"
-#include "MediaDevicesEnumerationRequest.h"
+#include "MediaDevicesRequest.h"
 #include "MediaTrackSupportedConstraints.h"
 #include "UserMediaRequest.h"
 #include <wtf/RandomNumber.h>
@@ -109,7 +109,7 @@ void MediaDevices::enumerateDevices(EnumerateDevicesPromise&& promise) const
     auto* document = this->document();
     if (!document)
         return;
-    MediaDevicesEnumerationRequest::start(*document, WTFMove(promise));
+    MediaDevicesRequest::create(*document, WTFMove(promise))->start();
 }
 
 MediaTrackSupportedConstraints MediaDevices::getSupportedConstraints()
index 7700e31..db2811b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(MEDIA_STREAM)
 
+#include "CaptureDevice.h"
 #include "Document.h"
-#include "JSMediaDeviceInfo.h"
-#include "RealtimeMediaSourceCenter.h"
+#include "MainFrame.h"
+#include "SecurityOrigin.h"
 #include "UserMediaController.h"
 
-#if PLATFORM(COCOA)
-#define REMOVE_ATYPICAL_DEVICES 1
-#else
-#define REMOVE_ATYPICAL_DEVICES 0
-#endif
-
-#if PLATFORM(COCOA)
-const int typicalMicrophoneCount = 1;
-#endif
-
-#if PLATFORM(IOS)
-const int typicalCameraCount = 2;
-#endif
-
-#if PLATFORM(MAC)
-const int typicalCameraCount = 1;
-#endif
-
 namespace WebCore {
 
-inline MediaDevicesEnumerationRequest::MediaDevicesEnumerationRequest(Document& document, Promise&& promise)
-    : ContextDestructionObserver(&document)
-    , m_promise(WTFMove(promise))
+Ref<MediaDevicesEnumerationRequest> MediaDevicesEnumerationRequest::create(Document& document, CompletionHandler&& completionHandler)
 {
+    return adoptRef(*new MediaDevicesEnumerationRequest(document, WTFMove(completionHandler)));
 }
 
-void MediaDevicesEnumerationRequest::start(Document& document, Promise&& promise)
+MediaDevicesEnumerationRequest::MediaDevicesEnumerationRequest(ScriptExecutionContext& context, CompletionHandler&& completionHandler)
+    : ContextDestructionObserver(&context)
+    , m_completionHandler(WTFMove(completionHandler))
 {
-    auto* page = document.page();
-    if (!page) {
-        // FIXME: Should we resolve or reject the promise here instead of leaving the website waiting?
-        return;
-    }
-
-    UserMediaController::from(*page).enumerateMediaDevices(adoptRef(*new MediaDevicesEnumerationRequest(document, WTFMove(promise))));
 }
 
 MediaDevicesEnumerationRequest::~MediaDevicesEnumerationRequest()
 {
-    // We will get here with m_isActive true if the client drops the request without ever calling setDeviceInfo.
-    // FIXME: Should we resolve or reject the promise in that case instead of leaving the website waiting?
 }
 
-Document* MediaDevicesEnumerationRequest::document()
+SecurityOrigin* MediaDevicesEnumerationRequest::userMediaDocumentOrigin() const
 {
-    return m_promise ? downcast<Document>(scriptExecutionContext()) : nullptr;
-}
+    if (!scriptExecutionContext())
+        return nullptr;
 
-Frame* MediaDevicesEnumerationRequest::frame()
-{
-    auto* document = this->document();
-    return document ? document->frame() : nullptr;
+    return scriptExecutionContext()->securityOrigin();
 }
 
-SecurityOrigin* MediaDevicesEnumerationRequest::userMediaDocumentOrigin()
+SecurityOrigin* MediaDevicesEnumerationRequest::topLevelDocumentOrigin() const
 {
-    auto* document = this->document();
-    return document ? &document->securityOrigin() : nullptr;
-}
+    if (!scriptExecutionContext())
+        return nullptr;
 
-SecurityOrigin* MediaDevicesEnumerationRequest::topLevelDocumentOrigin()
-{
-    auto* document = this->document();
-    return document ? &document->topOrigin() : nullptr;
+    return &scriptExecutionContext()->topOrigin();
 }
 
 void MediaDevicesEnumerationRequest::contextDestroyed()
 {
-    // FIXME: Should we be calling UserMediaController::cancelMediaDevicesEnumerationRequest here?
-    // If not, then why does that function exist? If we decide that we want to call that cancel
-    // function here, then there may be a problem, because it's hard to get from the document to
-    // the page to the user media controller while the document is being destroyed.
+    // Calling cancel() may destroy ourselves.
+    Ref<MediaDevicesEnumerationRequest> protectedThis(*this);
 
-    m_promise = std::nullopt;
+    cancel();
     ContextDestructionObserver::contextDestroyed();
 }
 
-#if REMOVE_ATYPICAL_DEVICES
-
-// To reduce the value of media devices for fingerprinting, filter devices that go beyond the typical number.
-static inline void removeAtypicalDevices(Vector<RefPtr<MediaDeviceInfo>>& devices)
-{
-    int cameraCount = 0;
-    int microphoneCount = 0;
-    devices.removeAllMatching([&cameraCount, &microphoneCount] (const RefPtr<MediaDeviceInfo>& device) {
-        if (device->kind() == MediaDeviceInfo::Kind::Videoinput && ++cameraCount > typicalCameraCount)
-            return true;
-        if (device->kind() == MediaDeviceInfo::Kind::Audioinput && ++microphoneCount > typicalMicrophoneCount)
-            return true;
-        return false;
-    });
-}
-
-#endif
-
-void MediaDevicesEnumerationRequest::setDeviceInfo(const Vector<CaptureDevice>& captureDevices, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess)
+void MediaDevicesEnumerationRequest::start()
 {
-    if (!m_promise)
-        return;
-    auto promise = WTFMove(m_promise.value());
-    ASSERT(!m_promise);
+    ASSERT(scriptExecutionContext());
 
     auto& document = downcast<Document>(*scriptExecutionContext());
+    auto* controller = UserMediaController::from(document.page());
+    if (!controller)
+        return;
 
-    // Policy about including some of the more sensitive information about capture devices.
-    bool includeLabels = originHasPersistentAccess || document.hasHadActiveMediaStreamTrack();
-#if REMOVE_ATYPICAL_DEVICES
-    bool includeAtypicalDevices = includeLabels;
-#endif
-
-    Vector<RefPtr<MediaDeviceInfo>> devices;
-
-    document.setDeviceIDHashSalt(deviceIdentifierHashSalt);
-
-    for (auto& captureDevice : captureDevices) {
-        auto id = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(captureDevice.persistentId(), deviceIdentifierHashSalt);
-        if (id.isEmpty())
-            continue;
-
-        auto label = includeLabels ? captureDevice.label() : emptyString();
-        auto groupId = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(captureDevice.groupId(), deviceIdentifierHashSalt);
-        auto deviceType = captureDevice.type() == CaptureDevice::DeviceType::Audio ? MediaDeviceInfo::Kind::Audioinput : MediaDeviceInfo::Kind::Videoinput;
-
-        devices.append(MediaDeviceInfo::create(label, id, groupId, deviceType));
-    }
+    Ref<MediaDevicesEnumerationRequest> protectedThis(*this);
+    controller->enumerateMediaDevices(*this);
+}
 
-#if REMOVE_ATYPICAL_DEVICES
-    if (!includeAtypicalDevices)
-        removeAtypicalDevices(devices);
-#endif
+void MediaDevicesEnumerationRequest::cancel()
+{
+    m_completionHandler = nullptr;
+}
 
-    promise.resolve(devices);
+void MediaDevicesEnumerationRequest::setDeviceInfo(const Vector<CaptureDevice>& deviceList, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess)
+{
+    if (m_completionHandler)
+        m_completionHandler(deviceList, deviceIdentifierHashSalt, originHasPersistentAccess);
+    m_completionHandler = nullptr;
 }
 
 } // namespace WebCore
index 2eb9f4e..0bd0dd5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(MEDIA_STREAM)
 
-#include "JSDOMPromiseDeferred.h"
+#include "ActiveDOMObject.h"
+#include <wtf/Function.h>
+#include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
 class CaptureDevice;
-class Frame;
-class MediaDeviceInfo;
+class Document;
 class SecurityOrigin;
 
-class MediaDevicesEnumerationRequest final : public RefCounted<MediaDevicesEnumerationRequest>, private ContextDestructionObserver {
+class MediaDevicesEnumerationRequest final : public ContextDestructionObserver, public RefCounted<MediaDevicesEnumerationRequest> {
 public:
-    using Promise = DOMPromiseDeferred<IDLSequence<IDLInterface<MediaDeviceInfo>>>;
-    static void start(Document&, Promise&&);
+    using CompletionHandler = WTF::Function<void(const Vector<CaptureDevice>&, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess)>;
+
+    static Ref<MediaDevicesEnumerationRequest> create(Document&, CompletionHandler&&);
 
     virtual ~MediaDevicesEnumerationRequest();
 
+    void start();
+    void cancel();
+
+    bool wasCanceled() const { return !m_completionHandler; }
+
     WEBCORE_EXPORT void setDeviceInfo(const Vector<CaptureDevice>&, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess);
 
-    WEBCORE_EXPORT Frame* frame();
-    WEBCORE_EXPORT SecurityOrigin* userMediaDocumentOrigin();
-    WEBCORE_EXPORT SecurityOrigin* topLevelDocumentOrigin();
+    WEBCORE_EXPORT SecurityOrigin* userMediaDocumentOrigin() const;
+    WEBCORE_EXPORT SecurityOrigin* topLevelDocumentOrigin() const;
 
 private:
-    MediaDevicesEnumerationRequest(Document&, Promise&&);
-    Document* document();
+    MediaDevicesEnumerationRequest(ScriptExecutionContext&, CompletionHandler&&);
+
+    // ContextDestructionObserver
     void contextDestroyed() final;
 
-    std::optional<Promise> m_promise;
+    CompletionHandler m_completionHandler;
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp b/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp
new file mode 100644 (file)
index 0000000..18e2597
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2015-2016 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 "MediaDevicesRequest.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "CaptureDevice.h"
+#include "Document.h"
+#include "Frame.h"
+#include "JSMediaDeviceInfo.h"
+#include "MediaDevicesEnumerationRequest.h"
+#include "RealtimeMediaSourceCenter.h"
+#include "SecurityOrigin.h"
+#include "UserMediaController.h"
+#include <wtf/MainThread.h>
+#include <wtf/SHA1.h>
+
+namespace WebCore {
+
+inline MediaDevicesRequest::MediaDevicesRequest(Document& document, MediaDevices::EnumerateDevicesPromise&& promise)
+    : ContextDestructionObserver(&document)
+    , m_promise(WTFMove(promise))
+{
+}
+
+Ref<MediaDevicesRequest> MediaDevicesRequest::create(Document& document, MediaDevices::EnumerateDevicesPromise&& promise)
+{
+    return adoptRef(*new MediaDevicesRequest(document, WTFMove(promise)));
+}
+
+MediaDevicesRequest::~MediaDevicesRequest()
+{
+    // This should only get destroyed after the enumeration request has completed or has been canceled.
+    ASSERT(!m_enumerationRequest || m_enumerationRequest->wasCanceled());
+}
+
+SecurityOrigin* MediaDevicesRequest::securityOrigin() const
+{
+    if (scriptExecutionContext())
+        return scriptExecutionContext()->securityOrigin();
+
+    return nullptr;
+}
+
+void MediaDevicesRequest::contextDestroyed()
+{
+    // The call to m_enumerationRequest->cancel() might delete this.
+    auto protectedThis = makeRef(*this);
+
+    if (m_enumerationRequest) {
+        m_enumerationRequest->cancel();
+        m_enumerationRequest = nullptr;
+    }
+    ContextDestructionObserver::contextDestroyed();
+}
+
+void MediaDevicesRequest::filterDeviceList(Vector<RefPtr<MediaDeviceInfo>>& devices)
+{
+#if !PLATFORM(COCOA)
+    UNUSED_PARAM(devices);
+#else
+
+#if PLATFORM(IOS)
+    static const int defaultCameraCount = 2;
+#endif
+#if PLATFORM(MAC)
+    static const int defaultCameraCount = 1;
+#endif
+    static const int defaultMicrophoneCount = 1;
+
+    int cameraCount = 0;
+    int microphoneCount = 0;
+    devices.removeAllMatching([&](const RefPtr<MediaDeviceInfo>& device) -> bool {
+        if (device->kind() == MediaDeviceInfo::Kind::Videoinput && ++cameraCount > defaultCameraCount)
+            return true;
+        if (device->kind() == MediaDeviceInfo::Kind::Audioinput && ++microphoneCount > defaultMicrophoneCount)
+            return true;
+
+        return false;
+    });
+
+#endif
+}
+
+void MediaDevicesRequest::start()
+{
+    // This lambda keeps |this| alive until the request completes or is canceled.
+    auto completion = [this, protectedThis = makeRef(*this)] (const Vector<CaptureDevice>& captureDevices, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess) mutable {
+
+        m_enumerationRequest = nullptr;
+
+        if (!scriptExecutionContext())
+            return;
+
+        Document& document = downcast<Document>(*scriptExecutionContext());
+        document.setDeviceIDHashSalt(deviceIdentifierHashSalt);
+
+        Vector<RefPtr<MediaDeviceInfo>> devices;
+        for (auto& deviceInfo : captureDevices) {
+            auto label = emptyString();
+            if (originHasPersistentAccess || document.hasHadActiveMediaStreamTrack())
+                label = deviceInfo.label();
+
+            auto id = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(deviceInfo.persistentId(), deviceIdentifierHashSalt);
+            if (id.isEmpty())
+                continue;
+
+            auto groupId = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(deviceInfo.groupId(), deviceIdentifierHashSalt);
+            auto deviceType = deviceInfo.type() == CaptureDevice::DeviceType::Audio ? MediaDeviceInfo::Kind::Audioinput : MediaDeviceInfo::Kind::Videoinput;
+            devices.append(MediaDeviceInfo::create(scriptExecutionContext(), label, id, groupId, deviceType));
+        }
+
+        if (!originHasPersistentAccess && !document.hasHadActiveMediaStreamTrack())
+            filterDeviceList(devices);
+
+        callOnMainThread([protectedThis = makeRef(*this), devices = WTFMove(devices)]() mutable {
+            protectedThis->m_promise.resolve(devices);
+        });
+    };
+
+    m_enumerationRequest = MediaDevicesEnumerationRequest::create(*downcast<Document>(scriptExecutionContext()), WTFMove(completion));
+    m_enumerationRequest->start();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h b/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h
new file mode 100644 (file)
index 0000000..4af017d
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015-2016 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
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "MediaDevices.h"
+
+namespace WebCore {
+
+class Document;
+class MediaDevicesEnumerationRequest;
+class SecurityOrigin;
+
+class MediaDevicesRequest : public RefCounted<MediaDevicesRequest>, private ContextDestructionObserver {
+public:
+    static Ref<MediaDevicesRequest> create(Document&, MediaDevices::EnumerateDevicesPromise&&);
+
+    virtual ~MediaDevicesRequest();
+
+    void start();
+
+    SecurityOrigin* securityOrigin() const;
+
+private:
+    MediaDevicesRequest(Document&, MediaDevices::EnumerateDevicesPromise&&);
+
+    void contextDestroyed() final;
+
+    void filterDeviceList(Vector<RefPtr<MediaDeviceInfo>>&);
+
+    MediaDevices::EnumerateDevicesPromise m_promise;
+    RefPtr<MediaDevicesRequest> m_protector;
+    RefPtr<MediaDevicesEnumerationRequest> m_enumerationRequest;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
index aff758b..8e1aba7 100644 (file)
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,19 +36,19 @@ const char* UserMediaController::supplementName()
     return "UserMediaController";
 }
 
-inline UserMediaController::UserMediaController(UserMediaClient& client)
+UserMediaController::UserMediaController(UserMediaClient* client)
     : m_client(client)
 {
 }
 
 UserMediaController::~UserMediaController()
 {
-    m_client.pageDestroyed();
+    m_client->pageDestroyed();
 }
 
 void provideUserMediaTo(Page* page, UserMediaClient* client)
 {
-    UserMediaController::provideTo(page, UserMediaController::supplementName(), std::make_unique<UserMediaController>(*client));
+    UserMediaController::provideTo(page, UserMediaController::supplementName(), std::make_unique<UserMediaController>(client));
 }
 
 } // namespace WebCore
index 9e5fd59..fd7c965 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,9 +36,11 @@ class UserMediaRequest;
 
 class UserMediaController : public Supplement<Page> {
 public:
-    explicit UserMediaController(UserMediaClient&);
+    explicit UserMediaController(UserMediaClient*);
     ~UserMediaController();
 
+    UserMediaClient* client() const { return m_client; }
+
     void requestUserMediaAccess(UserMediaRequest&);
     void cancelUserMediaAccessRequest(UserMediaRequest&);
 
@@ -46,30 +48,30 @@ public:
     void cancelMediaDevicesEnumerationRequest(MediaDevicesEnumerationRequest&);
 
     WEBCORE_EXPORT static const char* supplementName();
-    static UserMediaController& from(Page& page) { return *static_cast<UserMediaController*>(Supplement<Page>::from(&page, supplementName())); }
+    static UserMediaController* from(Page* page) { return static_cast<UserMediaController*>(Supplement<Page>::from(page, supplementName())); }
 
 private:
-    UserMediaClient& m_client;
+    UserMediaClient* m_client;
 };
 
 inline void UserMediaController::requestUserMediaAccess(UserMediaRequest& request)
 {
-    m_client.requestUserMediaAccess(request);
+    m_client->requestUserMediaAccess(request);
 }
 
 inline void UserMediaController::cancelUserMediaAccessRequest(UserMediaRequest& request)
 {
-    m_client.cancelUserMediaAccessRequest(request);
+    m_client->cancelUserMediaAccessRequest(request);
 }
 
 inline void UserMediaController::enumerateMediaDevices(MediaDevicesEnumerationRequest& request)
 {
-    m_client.enumerateMediaDevices(request);
+    m_client->enumerateMediaDevices(request);
 }
 
 inline void UserMediaController::cancelMediaDevicesEnumerationRequest(MediaDevicesEnumerationRequest& request)
 {
-    m_client.cancelMediaDevicesEnumerationRequest(request);
+    m_client->cancelMediaDevicesEnumerationRequest(request);
 }
 
 } // namespace WebCore
index 73dedda..ac972b4 100644 (file)
@@ -52,8 +52,8 @@ namespace WebCore {
 
 ExceptionOr<void> UserMediaRequest::start(Document& document, MediaConstraints&& audioConstraints, MediaConstraints&& videoConstraints, DOMPromiseDeferred<IDLInterface<MediaStream>>&& promise)
 {
-    auto* page = document.page();
-    if (!page)
+    auto* userMedia = UserMediaController::from(document.page());
+    if (!userMedia)
         return Exception { NOT_SUPPORTED_ERR }; // FIXME: Why is it better to return an exception here instead of rejecting the promise as we do just below?
 
     if (!audioConstraints.isValid && !videoConstraints.isValid) {
@@ -61,7 +61,7 @@ ExceptionOr<void> UserMediaRequest::start(Document& document, MediaConstraints&&
         return { };
     }
 
-    adoptRef(*new UserMediaRequest(document, UserMediaController::from(*page), WTFMove(audioConstraints), WTFMove(videoConstraints), WTFMove(promise)))->start();
+    adoptRef(*new UserMediaRequest(document, *userMedia, WTFMove(audioConstraints), WTFMove(videoConstraints), WTFMove(promise)))->start();
     return { };
 }
 
index fc90566..9db5631 100644 (file)
                073794FA19F5864E00E5A045 /* RTCDataChannelHandlerMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 073794F419F5864E00E5A045 /* RTCDataChannelHandlerMock.h */; };
                073794FD19F5864E00E5A045 /* RTCNotifiersMock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 073794F719F5864E00E5A045 /* RTCNotifiersMock.cpp */; };
                073794FE19F5864E00E5A045 /* RTCNotifiersMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 073794F819F5864E00E5A045 /* RTCNotifiersMock.h */; };
+               07394EC81BAB2CCD00BE99CD /* MediaDevicesRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07394EC71BAB2CCD00BE99CD /* MediaDevicesRequest.cpp */; };
+               07394ECA1BAB2CD700BE99CD /* MediaDevicesRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 07394EC91BAB2CD700BE99CD /* MediaDevicesRequest.h */; settings = {ATTRIBUTES = (Private, ); }; };
                073B87661E4385AC0071C0EC /* AudioSampleBufferList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 073B87621E43859D0071C0EC /* AudioSampleBufferList.cpp */; };
                073B87671E4385AC0071C0EC /* AudioSampleBufferList.h in Headers */ = {isa = PBXBuildFile; fileRef = 073B87631E43859D0071C0EC /* AudioSampleBufferList.h */; };
                073B87681E4385AC0071C0EC /* AudioSampleDataSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 073B87641E43859D0071C0EC /* AudioSampleDataSource.mm */; };
                073794F419F5864E00E5A045 /* RTCDataChannelHandlerMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCDataChannelHandlerMock.h; sourceTree = "<group>"; };
                073794F719F5864E00E5A045 /* RTCNotifiersMock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RTCNotifiersMock.cpp; sourceTree = "<group>"; };
                073794F819F5864E00E5A045 /* RTCNotifiersMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCNotifiersMock.h; sourceTree = "<group>"; };
+               07394EC71BAB2CCD00BE99CD /* MediaDevicesRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaDevicesRequest.cpp; sourceTree = "<group>"; };
+               07394EC91BAB2CD700BE99CD /* MediaDevicesRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaDevicesRequest.h; sourceTree = "<group>"; };
                073B87561E40DCE50071C0EC /* AudioStreamDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioStreamDescription.h; sourceTree = "<group>"; };
                073B87571E40DCFD0071C0EC /* CAAudioStreamDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAAudioStreamDescription.cpp; sourceTree = "<group>"; };
                073B87581E40DCFD0071C0EC /* CAAudioStreamDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAAudioStreamDescription.h; sourceTree = "<group>"; };
                                5EA725CF1ACABCD900EAD17B /* MediaDevices.idl */,
                                07ABEF6B1D8A1C5800F21972 /* MediaDevicesEnumerationRequest.cpp */,
                                07ABEF6D1D8A1C7600F21972 /* MediaDevicesEnumerationRequest.h */,
+                               07394EC71BAB2CCD00BE99CD /* MediaDevicesRequest.cpp */,
+                               07394EC91BAB2CD700BE99CD /* MediaDevicesRequest.h */,
                                5E16A2E21BFA64FB0029A21E /* MediaEndpointPeerConnection.cpp */,
                                5E16A2E31BFA64FB0029A21E /* MediaEndpointPeerConnection.h */,
                                5E4EAB021D07164C0006A184 /* MediaEndpointSessionDescription.cpp */,
                                15145B901B3A1CE000662BF7 /* MediaDeviceInfo.h in Headers */,
                                5EA725D31ACABD4700EAD17B /* MediaDevices.h in Headers */,
                                07ABEF6E1D8A1C7600F21972 /* MediaDevicesEnumerationRequest.h in Headers */,
+                               07394ECA1BAB2CD700BE99CD /* MediaDevicesRequest.h in Headers */,
                                97205AB81239291000B17380 /* MediaDocument.h in Headers */,
                                FD6F252D13F5EF0E0065165F /* MediaElementAudioSourceNode.h in Headers */,
                                07FE99DD18807A7D00256648 /* MediaElementSession.h in Headers */,
                                159AE82B1B3A402F0037478B /* MediaDeviceInfo.cpp in Sources */,
                                5EA725D21ACABD4700EAD17B /* MediaDevices.cpp in Sources */,
                                07ABEF6C1D8A1C5800F21972 /* MediaDevicesEnumerationRequest.cpp in Sources */,
+                               07394EC81BAB2CCD00BE99CD /* MediaDevicesRequest.cpp in Sources */,
                                97205AB71239291000B17380 /* MediaDocument.cpp in Sources */,
                                FD6F252C13F5EF0E0065165F /* MediaElementAudioSourceNode.cpp in Sources */,
                                07FE99DC18807A7D00256648 /* MediaElementSession.cpp in Sources */,
index f415e5d..bd6ede6 100644 (file)
 #include "TreeScope.h"
 #include "TypeConversions.h"
 #include "UserGestureIndicator.h"
+#include "UserMediaController.h"
 #include "ViewportArguments.h"
 #include "WebCoreJSClientData.h"
+#if ENABLE(WEBGL)
+#include "WebGLRenderingContext.h"
+#endif
 #include "WorkerThread.h"
 #include "WritingDirection.h"
 #include "XMLHttpRequest.h"
 #include "TimeRanges.h"
 #endif
 
-#if ENABLE(WEBGL)
-#include "WebGLRenderingContext.h"
-#endif
-
 #if ENABLE(SPEECH_SYNTHESIS)
 #include "DOMWindowSpeechSynthesis.h"
 #include "PlatformSpeechSynthesizerMock.h"
index 40908fb..7389f58 100644 (file)
@@ -1,3 +1,17 @@
+2017-06-20  Matt Lewis  <jlewis3@apple.com>
+
+        Unreviewed, rolling out r218530.
+
+        This revision caused multiple media stream test crashes on
+        Debug builds.
+
+        Reverted changeset:
+
+        "Merge MediaDevicesRequest and MediaDevicesEnumerationRequest
+        to tighten up code and object lifetime"
+        https://bugs.webkit.org/show_bug.cgi?id=173527
+        http://trac.webkit.org/changeset/218530
+
 2017-06-20  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         [iOS DnD] [WK2] Remove custom logic for disambiguating long press action sheet gestures and drag lift
index a891f52..d257845 100644 (file)
@@ -41,4 +41,4 @@ WK_EXPORT void WKUserMediaPermissionCheckSetUserMediaAccessInfo(WKUserMediaPermi
 }
 #endif
 
-#endif /* WKUserMediaPermissionCheck_h */
+#endif /* WKMediaDevicesRequest_h */
index 7f47362..e9ff24f 100644 (file)
@@ -168,7 +168,9 @@ void UserMediaPermissionRequestManager::userMediaAccessWasDenied(uint64_t reques
 
 void UserMediaPermissionRequestManager::enumerateMediaDevices(MediaDevicesEnumerationRequest& request)
 {
-    auto* frame = request.frame();
+    auto* document = downcast<Document>(request.scriptExecutionContext());
+    auto* frame = document ? document->frame() : nullptr;
+
     if (!frame) {
         request.setDeviceInfo(Vector<CaptureDevice>(), emptyString(), false);
         return;
index 4efabe9..2a019a0 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "UserMediaPermissionRequestManager.h"
 #include "WebPage.h"
+#include <WebCore/UserMediaController.h>
 #include <WebCore/UserMediaRequest.h>
 
 using namespace WebCore;