summaryrefslogtreecommitdiff
path: root/Source/WebKit2/WebProcess/MediaStream
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebKit2/WebProcess/MediaStream
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebKit2/WebProcess/MediaStream')
-rw-r--r--Source/WebKit2/WebProcess/MediaStream/MediaDeviceSandboxExtensions.cpp80
-rw-r--r--Source/WebKit2/WebProcess/MediaStream/MediaDeviceSandboxExtensions.h59
-rw-r--r--Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp226
-rw-r--r--Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h83
4 files changed, 448 insertions, 0 deletions
diff --git a/Source/WebKit2/WebProcess/MediaStream/MediaDeviceSandboxExtensions.cpp b/Source/WebKit2/WebProcess/MediaStream/MediaDeviceSandboxExtensions.cpp
new file mode 100644
index 000000000..2a4fb525c
--- /dev/null
+++ b/Source/WebKit2/WebProcess/MediaStream/MediaDeviceSandboxExtensions.cpp
@@ -0,0 +1,80 @@
+/*
+ * 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
+ * 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. AND ITS 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 APPLE INC. OR ITS 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 "MediaDeviceSandboxExtensions.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "WebCoreArgumentCoders.h"
+
+namespace WebKit {
+
+MediaDeviceSandboxExtensions::MediaDeviceSandboxExtensions(Vector<String> ids, SandboxExtension::HandleArray&& handles)
+ : m_ids(ids)
+ , m_handles(WTFMove(handles))
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(m_ids.size() == m_handles.size());
+}
+
+void MediaDeviceSandboxExtensions::encode(IPC::Encoder& encoder) const
+{
+ encoder << m_ids;
+ m_handles.encode(encoder);
+}
+
+bool MediaDeviceSandboxExtensions::decode(IPC::Decoder& decoder, MediaDeviceSandboxExtensions& result)
+{
+ if (!decoder.decode(result.m_ids))
+ return false;
+
+ if (!SandboxExtension::HandleArray::decode(decoder, result.m_handles))
+ return false;
+
+ return true;
+}
+
+std::pair<String, RefPtr<SandboxExtension>> MediaDeviceSandboxExtensions::operator[](size_t i)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(m_ids.size() == m_handles.size());
+ ASSERT_WITH_SECURITY_IMPLICATION(i < m_ids.size());
+ return { m_ids[i], SandboxExtension::create(m_handles[i]) };
+}
+
+const std::pair<String, RefPtr<SandboxExtension>> MediaDeviceSandboxExtensions::operator[](size_t i) const
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(m_ids.size() == m_handles.size());
+ ASSERT_WITH_SECURITY_IMPLICATION(i < m_ids.size());
+ return { m_ids[i], SandboxExtension::create(m_handles[i]) };
+}
+
+size_t MediaDeviceSandboxExtensions::size() const
+{
+ return m_ids.size();
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebKit2/WebProcess/MediaStream/MediaDeviceSandboxExtensions.h b/Source/WebKit2/WebProcess/MediaStream/MediaDeviceSandboxExtensions.h
new file mode 100644
index 000000000..a270f4e1e
--- /dev/null
+++ b/Source/WebKit2/WebProcess/MediaStream/MediaDeviceSandboxExtensions.h
@@ -0,0 +1,59 @@
+/*
+ * 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
+ * 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. AND ITS 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 APPLE INC. OR ITS 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 "SandboxExtension.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/RefPtr.h>
+
+namespace WebKit {
+
+class MediaDeviceSandboxExtensions {
+ WTF_MAKE_NONCOPYABLE(MediaDeviceSandboxExtensions);
+public:
+ MediaDeviceSandboxExtensions()
+ {
+ }
+
+ MediaDeviceSandboxExtensions(Vector<String> ids, SandboxExtension::HandleArray&& handles);
+
+ std::pair<String, RefPtr<SandboxExtension>> operator[](size_t i);
+ const std::pair<String, RefPtr<SandboxExtension>> operator[](size_t i) const;
+ size_t size() const;
+
+ void encode(IPC::Encoder&) const;
+ static bool decode(IPC::Decoder&, MediaDeviceSandboxExtensions&);
+
+private:
+ Vector<String> m_ids;
+ SandboxExtension::HandleArray m_handles;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp b/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp
new file mode 100644
index 000000000..7f11dc7a3
--- /dev/null
+++ b/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2014 Igalia S.L.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "UserMediaPermissionRequestManager.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "WebFrame.h"
+#include "WebPage.h"
+#include "WebPageProxyMessages.h"
+#include <WebCore/CaptureDevice.h>
+#include <WebCore/Document.h>
+#include <WebCore/Frame.h>
+#include <WebCore/FrameLoader.h>
+#include <WebCore/MediaConstraintsImpl.h>
+#include <WebCore/SecurityOrigin.h>
+#include <WebCore/SecurityOriginData.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+using namespace WebCore;
+
+static uint64_t generateRequestID()
+{
+ static uint64_t uniqueRequestID = 1;
+ return uniqueRequestID++;
+}
+
+UserMediaPermissionRequestManager::UserMediaPermissionRequestManager(WebPage& page)
+ : m_page(page)
+{
+}
+
+UserMediaPermissionRequestManager::~UserMediaPermissionRequestManager()
+{
+ for (auto& sandboxExtension : m_userMediaDeviceSandboxExtensions)
+ sandboxExtension.value->revoke();
+}
+
+void UserMediaPermissionRequestManager::startUserMediaRequest(UserMediaRequest& request)
+{
+ Document* document = request.document();
+ Frame* frame = document ? document->frame() : nullptr;
+
+ if (!frame || !document->page()) {
+ request.deny(UserMediaRequest::OtherFailure, emptyString());
+ return;
+ }
+
+ if (document->page()->canStartMedia()) {
+ sendUserMediaRequest(request);
+ return;
+ }
+
+ auto& pendingRequests = m_blockedRequests.add(document, Vector<RefPtr<UserMediaRequest>>()).iterator->value;
+ if (pendingRequests.isEmpty())
+ document->addMediaCanStartListener(this);
+ pendingRequests.append(&request);
+}
+
+void UserMediaPermissionRequestManager::sendUserMediaRequest(UserMediaRequest& request)
+{
+ Document* document = request.document();
+ Frame* frame = document ? document->frame() : nullptr;
+
+ if (!frame) {
+ request.deny(UserMediaRequest::OtherFailure, emptyString());
+ return;
+ }
+
+ uint64_t requestID = generateRequestID();
+ m_idToUserMediaRequestMap.add(requestID, &request);
+ m_userMediaRequestToIDMap.add(&request, requestID);
+
+ WebFrame* webFrame = WebFrame::fromCoreFrame(*frame);
+ ASSERT(webFrame);
+
+ SecurityOrigin* topLevelDocumentOrigin = request.topLevelDocumentOrigin();
+ String topLevelDocumentOriginString = topLevelDocumentOrigin ? SecurityOriginData::fromSecurityOrigin(*topLevelDocumentOrigin).databaseIdentifier() : emptyString();
+ m_page.send(Messages::WebPageProxy::RequestUserMediaPermissionForFrame(requestID, webFrame->frameID(), SecurityOriginData::fromSecurityOrigin(*request.userMediaDocumentOrigin()).databaseIdentifier(), topLevelDocumentOriginString, request.audioConstraints().data(), request.videoConstraints().data()));
+}
+
+void UserMediaPermissionRequestManager::cancelUserMediaRequest(UserMediaRequest& request)
+{
+ uint64_t requestID = m_userMediaRequestToIDMap.take(&request);
+ if (!requestID)
+ return;
+ m_idToUserMediaRequestMap.remove(requestID);
+ removeMediaRequestFromMaps(request);
+}
+
+void UserMediaPermissionRequestManager::mediaCanStart(Document& document)
+{
+ auto pendingRequests = m_blockedRequests.take(&document);
+ while (!pendingRequests.isEmpty()) {
+ if (!document.page()->canStartMedia()) {
+ m_blockedRequests.add(&document, pendingRequests);
+ document.addMediaCanStartListener(this);
+ break;
+ }
+
+ sendUserMediaRequest(*pendingRequests.takeLast());
+ }
+}
+
+void UserMediaPermissionRequestManager::removeMediaRequestFromMaps(UserMediaRequest& request)
+{
+ Document* document = request.document();
+ if (!document)
+ return;
+
+ auto pendingRequests = m_blockedRequests.take(document);
+ for (auto& pendingRequest : pendingRequests) {
+ if (&request != pendingRequest.get())
+ continue;
+
+ if (pendingRequests.isEmpty())
+ request.document()->removeMediaCanStartListener(this);
+ else
+ m_blockedRequests.add(request.document(), pendingRequests);
+ break;
+ }
+
+ m_userMediaRequestToIDMap.remove(&request);
+}
+
+void UserMediaPermissionRequestManager::userMediaAccessWasGranted(uint64_t requestID, const String& audioDeviceUID, const String& videoDeviceUID)
+{
+ auto request = m_idToUserMediaRequestMap.take(requestID);
+ if (!request)
+ return;
+ removeMediaRequestFromMaps(*request);
+
+ request->allow(audioDeviceUID, videoDeviceUID);
+}
+
+void UserMediaPermissionRequestManager::userMediaAccessWasDenied(uint64_t requestID, WebCore::UserMediaRequest::MediaAccessDenialReason reason, const String& invalidConstraint)
+{
+ auto request = m_idToUserMediaRequestMap.take(requestID);
+ if (!request)
+ return;
+ removeMediaRequestFromMaps(*request);
+
+ request->deny(reason, invalidConstraint);
+}
+
+void UserMediaPermissionRequestManager::enumerateMediaDevices(MediaDevicesEnumerationRequest& request)
+{
+ auto* document = downcast<Document>(request.scriptExecutionContext());
+ auto* frame = document ? document->frame() : nullptr;
+
+ if (!frame) {
+ request.setDeviceInfo(Vector<CaptureDevice>(), emptyString(), false);
+ return;
+ }
+
+ uint64_t requestID = generateRequestID();
+ m_idToMediaDevicesEnumerationRequestMap.add(requestID, &request);
+ m_mediaDevicesEnumerationRequestToIDMap.add(&request, requestID);
+
+ WebFrame* webFrame = WebFrame::fromCoreFrame(*frame);
+ ASSERT(webFrame);
+
+ SecurityOrigin* topLevelDocumentOrigin = request.topLevelDocumentOrigin();
+ String topLevelDocumentOriginString = topLevelDocumentOrigin ? SecurityOriginData::fromSecurityOrigin(*topLevelDocumentOrigin).databaseIdentifier() : emptyString();
+ m_page.send(Messages::WebPageProxy::EnumerateMediaDevicesForFrame(requestID, webFrame->frameID(), SecurityOriginData::fromSecurityOrigin(*request.userMediaDocumentOrigin()).databaseIdentifier(), topLevelDocumentOriginString));
+}
+
+void UserMediaPermissionRequestManager::cancelMediaDevicesEnumeration(WebCore::MediaDevicesEnumerationRequest& request)
+{
+ uint64_t requestID = m_mediaDevicesEnumerationRequestToIDMap.take(&request);
+ if (!requestID)
+ return;
+ m_idToMediaDevicesEnumerationRequestMap.remove(requestID);
+}
+
+void UserMediaPermissionRequestManager::didCompleteMediaDeviceEnumeration(uint64_t requestID, const Vector<CaptureDevice>& deviceList, const String& mediaDeviceIdentifierHashSalt, bool hasPersistentAccess)
+{
+ RefPtr<MediaDevicesEnumerationRequest> request = m_idToMediaDevicesEnumerationRequestMap.take(requestID);
+ if (!request)
+ return;
+ m_mediaDevicesEnumerationRequestToIDMap.remove(request);
+
+ request->setDeviceInfo(deviceList, mediaDeviceIdentifierHashSalt, hasPersistentAccess);
+}
+
+void UserMediaPermissionRequestManager::grantUserMediaDeviceSandboxExtensions(const MediaDeviceSandboxExtensions& extensions)
+{
+ for (size_t i = 0; i < extensions.size(); i++) {
+ auto& extension = extensions[i];
+ extension.second->consume();
+ m_userMediaDeviceSandboxExtensions.add(extension.first, extension.second.copyRef());
+ }
+}
+
+void UserMediaPermissionRequestManager::revokeUserMediaDeviceSandboxExtensions(const Vector<String>& extensionIDs)
+{
+ for (const auto& extensionID : extensionIDs) {
+ auto extension = m_userMediaDeviceSandboxExtensions.take(extensionID);
+ if (extension)
+ extension->revoke();
+ }
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h b/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h
new file mode 100644
index 000000000..e8a96c253
--- /dev/null
+++ b/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 Igalia S.L.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef UserMediaPermissionRequestManager_h
+#define UserMediaPermissionRequestManager_h
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "MediaDeviceSandboxExtensions.h"
+#include "SandboxExtension.h"
+#include <WebCore/MediaCanStartListener.h>
+#include <WebCore/MediaConstraints.h>
+#include <WebCore/MediaDevicesEnumerationRequest.h>
+#include <WebCore/UserMediaClient.h>
+#include <WebCore/UserMediaRequest.h>
+#include <wtf/HashMap.h>
+#include <wtf/Ref.h>
+#include <wtf/RefPtr.h>
+
+namespace WebKit {
+
+class WebPage;
+
+class UserMediaPermissionRequestManager
+ : private WebCore::MediaCanStartListener {
+public:
+ explicit UserMediaPermissionRequestManager(WebPage&);
+ ~UserMediaPermissionRequestManager();
+
+ void startUserMediaRequest(WebCore::UserMediaRequest&);
+ void cancelUserMediaRequest(WebCore::UserMediaRequest&);
+ void userMediaAccessWasGranted(uint64_t, const String& audioDeviceUID, const String& videoDeviceUID);
+ void userMediaAccessWasDenied(uint64_t, WebCore::UserMediaRequest::MediaAccessDenialReason, const String&);
+
+ void enumerateMediaDevices(WebCore::MediaDevicesEnumerationRequest&);
+ void cancelMediaDevicesEnumeration(WebCore::MediaDevicesEnumerationRequest&);
+ void didCompleteMediaDeviceEnumeration(uint64_t, const Vector<WebCore::CaptureDevice>& deviceList, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess);
+
+ void grantUserMediaDeviceSandboxExtensions(const MediaDeviceSandboxExtensions&);
+ void revokeUserMediaDeviceSandboxExtensions(const Vector<String>&);
+
+private:
+ void sendUserMediaRequest(WebCore::UserMediaRequest&);
+
+ // WebCore::MediaCanStartListener
+ void mediaCanStart(WebCore::Document&) override;
+
+ void removeMediaRequestFromMaps(WebCore::UserMediaRequest&);
+
+ WebPage& m_page;
+
+ HashMap<uint64_t, RefPtr<WebCore::UserMediaRequest>> m_idToUserMediaRequestMap;
+ HashMap<RefPtr<WebCore::UserMediaRequest>, uint64_t> m_userMediaRequestToIDMap;
+
+ HashMap<uint64_t, RefPtr<WebCore::MediaDevicesEnumerationRequest>> m_idToMediaDevicesEnumerationRequestMap;
+ HashMap<RefPtr<WebCore::MediaDevicesEnumerationRequest>, uint64_t> m_mediaDevicesEnumerationRequestToIDMap;
+
+ HashMap<String, RefPtr<SandboxExtension>> m_userMediaDeviceSandboxExtensions;
+
+ HashMap<RefPtr<WebCore::Document>, Vector<RefPtr<WebCore::UserMediaRequest>>> m_blockedRequests;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(MEDIA_STREAM)
+
+#endif // UserMediaPermissionRequestManager_h