0c805adec6bab5f8f56c2fdfbfaa352468059313
[WebKit-https.git] / Source / WebKit2 / WebProcess / MediaStream / UserMediaPermissionRequestManager.cpp
1 /*
2  * Copyright (C) 2014 Igalia S.L.
3  * Copyright (C) 2016 Apple Inc. All rights reserved.
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19
20 #include "config.h"
21 #include "UserMediaPermissionRequestManager.h"
22
23 #if ENABLE(MEDIA_STREAM)
24
25 #include "WebFrame.h"
26 #include "WebPage.h"
27 #include "WebPageProxyMessages.h"
28 #include <WebCore/CaptureDevice.h>
29 #include <WebCore/Document.h>
30 #include <WebCore/Frame.h>
31 #include <WebCore/FrameLoader.h>
32 #include <WebCore/SecurityOrigin.h>
33 #include <WebCore/SecurityOriginData.h>
34
35 using namespace WebCore;
36
37 namespace WebKit {
38
39 using namespace WebCore;
40
41 static uint64_t generateRequestID()
42 {
43     static uint64_t uniqueRequestID = 1;
44     return uniqueRequestID++;
45 }
46
47 UserMediaPermissionRequestManager::UserMediaPermissionRequestManager(WebPage& page)
48     : m_page(page)
49 {
50 }
51
52 UserMediaPermissionRequestManager::~UserMediaPermissionRequestManager()
53 {
54     for (auto& sandboxExtension : m_userMediaDeviceSandboxExtensions)
55         sandboxExtension->revoke();
56 }
57
58 void UserMediaPermissionRequestManager::startUserMediaRequest(UserMediaRequest& request)
59 {
60     Document* document = request.document();
61     Frame* frame = document ? document->frame() : nullptr;
62
63     if (!frame) {
64         request.deny(UserMediaRequest::OtherFailure, emptyString());
65         return;
66     }
67
68     uint64_t requestID = generateRequestID();
69     m_idToUserMediaRequestMap.add(requestID, &request);
70     m_userMediaRequestToIDMap.add(&request, requestID);
71
72     WebFrame* webFrame = WebFrame::fromCoreFrame(*frame);
73     ASSERT(webFrame);
74
75     SecurityOrigin* topLevelDocumentOrigin = request.topLevelDocumentOrigin();
76     String topLevelDocumentOriginString = topLevelDocumentOrigin ? SecurityOriginData::fromSecurityOrigin(*topLevelDocumentOrigin).databaseIdentifier() : emptyString();
77     m_page.send(Messages::WebPageProxy::RequestUserMediaPermissionForFrame(requestID, webFrame->frameID(), SecurityOriginData::fromSecurityOrigin(*request.userMediaDocumentOrigin()).databaseIdentifier(), topLevelDocumentOriginString, request.audioConstraints().data(), request.videoConstraints().data()));
78 }
79
80 void UserMediaPermissionRequestManager::cancelUserMediaRequest(UserMediaRequest& request)
81 {
82     uint64_t requestID = m_userMediaRequestToIDMap.take(&request);
83     if (!requestID)
84         return;
85     m_idToUserMediaRequestMap.remove(requestID);
86 }
87
88 void UserMediaPermissionRequestManager::userMediaAccessWasGranted(uint64_t requestID, const String& audioDeviceUID, const String& videoDeviceUID)
89 {
90     auto request = m_idToUserMediaRequestMap.take(requestID);
91     if (!request)
92         return;
93     m_userMediaRequestToIDMap.remove(request);
94
95     request->allow(audioDeviceUID, videoDeviceUID);
96 }
97
98 void UserMediaPermissionRequestManager::userMediaAccessWasDenied(uint64_t requestID, WebCore::UserMediaRequest::MediaAccessDenialReason reason, const String& invalidConstraint)
99 {
100     auto request = m_idToUserMediaRequestMap.take(requestID);
101     if (!request)
102         return;
103     m_userMediaRequestToIDMap.remove(request);
104
105     request->deny(reason, invalidConstraint);
106 }
107
108 void UserMediaPermissionRequestManager::enumerateMediaDevices(MediaDevicesEnumerationRequest& request)
109 {
110     auto* document = downcast<Document>(request.scriptExecutionContext());
111     auto* frame = document ? document->frame() : nullptr;
112
113     if (!frame) {
114         request.setDeviceInfo(Vector<CaptureDevice>(), emptyString(), false);
115         return;
116     }
117
118     uint64_t requestID = generateRequestID();
119     m_idToMediaDevicesEnumerationRequestMap.add(requestID, &request);
120     m_mediaDevicesEnumerationRequestToIDMap.add(&request, requestID);
121
122     WebFrame* webFrame = WebFrame::fromCoreFrame(*frame);
123     ASSERT(webFrame);
124
125     SecurityOrigin* topLevelDocumentOrigin = request.topLevelDocumentOrigin();
126     String topLevelDocumentOriginString = topLevelDocumentOrigin ? SecurityOriginData::fromSecurityOrigin(*topLevelDocumentOrigin).databaseIdentifier() : emptyString();
127     m_page.send(Messages::WebPageProxy::EnumerateMediaDevicesForFrame(requestID, webFrame->frameID(), SecurityOriginData::fromSecurityOrigin(*request.userMediaDocumentOrigin()).databaseIdentifier(), topLevelDocumentOriginString));
128 }
129
130 void UserMediaPermissionRequestManager::cancelMediaDevicesEnumeration(WebCore::MediaDevicesEnumerationRequest& request)
131 {
132     uint64_t requestID = m_mediaDevicesEnumerationRequestToIDMap.take(&request);
133     if (!requestID)
134         return;
135     m_idToMediaDevicesEnumerationRequestMap.remove(requestID);
136 }
137
138 void UserMediaPermissionRequestManager::didCompleteMediaDeviceEnumeration(uint64_t requestID, const Vector<CaptureDevice>& deviceList, const String& mediaDeviceIdentifierHashSalt, bool hasPersistentAccess)
139 {
140     RefPtr<MediaDevicesEnumerationRequest> request = m_idToMediaDevicesEnumerationRequestMap.take(requestID);
141     if (!request)
142         return;
143     m_mediaDevicesEnumerationRequestToIDMap.remove(request);
144     
145     request->setDeviceInfo(deviceList, mediaDeviceIdentifierHashSalt, hasPersistentAccess);
146 }
147
148 void UserMediaPermissionRequestManager::grantUserMediaDevicesSandboxExtension(const SandboxExtension::HandleArray& sandboxExtensionHandles)
149 {
150     ASSERT(m_userMediaDeviceSandboxExtensions.size() <= 2);
151
152     for (size_t i = 0; i < sandboxExtensionHandles.size(); i++) {
153         if (RefPtr<SandboxExtension> extension = SandboxExtension::create(sandboxExtensionHandles[i])) {
154             extension->consume();
155             m_userMediaDeviceSandboxExtensions.append(extension.release());
156         }
157     }
158 }
159
160 } // namespace WebKit
161
162 #endif // ENABLE(MEDIA_STREAM)