source: webkit/trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h

Last change on this file was 291284, checked in by [email protected], 3 years ago

Mark permission as denied if system forbids access to camera and/or microphone
https://bugs.webkit.org/show_bug.cgi?id=237823

Reviewed by Eric Carlson.

Source/WebKit:

If application has not set the camera/microphone usage string, we do not need to call ther permission delegate.
Ditto if TCC prompt is denied. Instead, we can return deny if possible or prompt otherwise.
Covered by API test.

  • UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
  • UIProcess/UserMediaPermissionRequestManagerProxy.h:
  • UIProcess/WebPageProxy.cpp:

Tools:

  • TestWebKitAPI/Tests/WebKit/GetUserMedia.mm:
  • TestWebKitAPI/Tests/WebKit/getUserMediaPermission.html:
File size: 9.3 KB
Line 
1/*
2 * Copyright (C) 2014 Igalia S.L.
3 * Copyright (C) 2016-2020 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#pragma once
21
22#include "UserMediaPermissionCheckProxy.h"
23#include "UserMediaPermissionRequestProxy.h"
24#include <WebCore/MediaProducer.h>
25#include <WebCore/PermissionDescriptor.h>
26#include <WebCore/PermissionState.h>
27#include <WebCore/RealtimeMediaSourceCenter.h>
28#include <WebCore/RealtimeMediaSourceFactory.h>
29#include <WebCore/SecurityOrigin.h>
30#include <wtf/CompletionHandler.h>
31#include <wtf/Deque.h>
32#include <wtf/HashMap.h>
33#include <wtf/LoggerHelper.h>
34#include <wtf/RunLoop.h>
35#include <wtf/Seconds.h>
36#include <wtf/WeakPtr.h>
37
38namespace WebCore {
39class CaptureDevice;
40struct ClientOrigin;
41struct MediaConstraints;
42struct MediaStreamRequest;
43class SecurityOrigin;
44};
45
46namespace WebKit {
47
48class WebPageProxy;
49
50enum MediaDevicePermissionRequestIdentifierType { };
51using MediaDevicePermissionRequestIdentifier = ObjectIdentifier<MediaDevicePermissionRequestIdentifierType>;
52
53class UserMediaPermissionRequestManagerProxy
54#if ENABLE(MEDIA_STREAM)
55 : public WebCore::AudioCaptureFactory::ExtensiveObserver
56#else
57 : public CanMakeWeakPtr<UserMediaPermissionRequestManagerProxy>
58#endif
59#if !RELEASE_LOG_DISABLED
60 , private LoggerHelper
61#endif
62{
63 WTF_MAKE_FAST_ALLOCATED;
64public:
65 explicit UserMediaPermissionRequestManagerProxy(WebPageProxy&);
66 ~UserMediaPermissionRequestManagerProxy();
67
68 WebPageProxy& page() const { return m_page; }
69
70#if ENABLE(MEDIA_STREAM)
71 static void forEach(const WTF::Function<void(UserMediaPermissionRequestManagerProxy&)>&);
72#endif
73 static bool permittedToCaptureAudio();
74 static bool permittedToCaptureVideo();
75
76 void invalidatePendingRequests();
77
78 void requestUserMediaPermissionForFrame(WebCore::UserMediaRequestIdentifier, WebCore::FrameIdentifier, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, WebCore::MediaStreamRequest&&);
79
80 void resetAccess(std::optional<WebCore::FrameIdentifier> mainFrameID = { });
81 void viewIsBecomingVisible();
82
83 void grantRequest(UserMediaPermissionRequestProxy&);
84 void denyRequest(UserMediaPermissionRequestProxy&, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason, const String& invalidConstraint = { });
85
86 void enumerateMediaDevicesForFrame(WebCore::FrameIdentifier, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, CompletionHandler<void(const Vector<WebCore::CaptureDevice>&, const String&)>&&);
87
88 void stopCapture();
89 void scheduleNextRejection();
90 void rejectionTimerFired();
91 void clearCachedState();
92 void captureDevicesChanged();
93
94 void captureStateChanged(WebCore::MediaProducerMediaStateFlags oldState, WebCore::MediaProducerMediaStateFlags newState);
95 void syncWithWebCorePrefs() const;
96
97 enum class RequestAction {
98 Deny,
99 Grant,
100 Prompt
101 };
102
103 bool canAudioCaptureSucceed() const;
104 bool canVideoCaptureSucceed() const;
105 void setMockCaptureDevicesEnabledOverride(std::optional<bool>);
106 bool hasPendingCapture() const { return m_hasPendingCapture; }
107
108 void checkUserMediaPermissionForSpeechRecognition(WebCore::FrameIdentifier, const WebCore::SecurityOrigin&, const WebCore::SecurityOrigin&, const WebCore::CaptureDevice&, CompletionHandler<void(bool)>&&);
109
110 struct DeniedRequest {
111 WebCore::FrameIdentifier mainFrameID;
112 Ref<WebCore::SecurityOrigin> userMediaDocumentOrigin;
113 Ref<WebCore::SecurityOrigin> topLevelDocumentOrigin;
114 bool isAudioDenied;
115 bool isVideoDenied;
116 bool isScreenCaptureDenied;
117 };
118
119 std::optional<WebCore::PermissionState> filterPermissionQuery(const WebCore::ClientOrigin&, const WebCore::PermissionDescriptor&, WebCore::PermissionState);
120
121 bool shouldChangeDeniedToPromptForCamera(const WebCore::ClientOrigin&) const;
122 bool shouldChangeDeniedToPromptForMicrophone(const WebCore::ClientOrigin&) const;
123 bool shouldChangePromptToGrantForCamera(const WebCore::ClientOrigin&) const;
124 bool shouldChangePromptToGrantForMicrophone(const WebCore::ClientOrigin&) const;
125
126private:
127#if !RELEASE_LOG_DISABLED
128 const Logger& logger() const final;
129 const void* logIdentifier() const final { return m_logIdentifier; }
130 const char* logClassName() const override { return "UserMediaPermissionRequestManagerProxy"; }
131 WTFLogChannel& logChannel() const final;
132#endif
133
134 Ref<UserMediaPermissionRequestProxy> createPermissionRequest(WebCore::UserMediaRequestIdentifier, WebCore::FrameIdentifier mainFrameID, WebCore::FrameIdentifier, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, Vector<WebCore::CaptureDevice>&& audioDevices, Vector<WebCore::CaptureDevice>&& videoDevices, WebCore::MediaStreamRequest&&);
135#if ENABLE(MEDIA_STREAM)
136 void finishGrantingRequest(UserMediaPermissionRequestProxy&);
137
138 const UserMediaPermissionRequestProxy* searchForGrantedRequest(WebCore::FrameIdentifier, const WebCore::SecurityOrigin& userMediaDocumentOrigin, const WebCore::SecurityOrigin& topLevelDocumentOrigin, bool needsAudio, bool needsVideo) const;
139 bool wasRequestDenied(const UserMediaPermissionRequestProxy&, bool needsAudio, bool needsVideo, bool needsScreenCapture);
140
141 using PermissionInfo = UserMediaPermissionCheckProxy::PermissionInfo;
142 void getUserMediaPermissionInfo(WebCore::FrameIdentifier, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, CompletionHandler<void(PermissionInfo)>&&);
143 void captureDevicesChanged(PermissionInfo);
144
145 RequestAction getRequestAction(const UserMediaPermissionRequestProxy&);
146
147 bool wasGrantedVideoOrAudioAccess(WebCore::FrameIdentifier, const WebCore::SecurityOrigin& userMediaDocumentOrigin, const WebCore::SecurityOrigin& topLevelDocumentOrigin);
148
149 void computeFilteredDeviceList(bool revealIdsAndLabels, CompletionHandler<void(Vector<WebCore::CaptureDevice>&&)>&&);
150 void platformGetMediaStreamDevices(CompletionHandler<void(Vector<WebCore::CaptureDevice>&&)>&&);
151
152 void processUserMediaPermissionRequest();
153 void processUserMediaPermissionInvalidRequest(const String& invalidConstraint);
154 void processUserMediaPermissionValidRequest(Vector<WebCore::CaptureDevice>&& audioDevices, Vector<WebCore::CaptureDevice>&& videoDevices, String&& deviceIdentifierHashSalt);
155 void startProcessingUserMediaPermissionRequest(Ref<UserMediaPermissionRequestProxy>&&);
156
157 static void requestSystemValidation(const WebPageProxy&, UserMediaPermissionRequestProxy&, CompletionHandler<void(bool)>&&);
158
159 void platformValidateUserMediaRequestConstraints(WebCore::RealtimeMediaSourceCenter::ValidConstraintsHandler&& validHandler, WebCore::RealtimeMediaSourceCenter::InvalidConstraintsHandler&& invalidHandler, String&& deviceIDHashSalt);
160#endif
161
162 bool mockCaptureDevicesEnabled() const;
163
164 void watchdogTimerFired();
165
166 void processNextUserMediaRequestIfNeeded();
167 void decidePolicyForUserMediaPermissionRequest();
168 void updateStoredRequests(UserMediaPermissionRequestProxy&);
169
170 RefPtr<UserMediaPermissionRequestProxy> m_currentUserMediaRequest;
171 Deque<Ref<UserMediaPermissionRequestProxy>> m_pendingUserMediaRequests;
172 HashSet<MediaDevicePermissionRequestIdentifier> m_pendingDeviceRequests;
173
174 WebPageProxy& m_page;
175
176 RunLoop::Timer<UserMediaPermissionRequestManagerProxy> m_rejectionTimer;
177 Deque<Ref<UserMediaPermissionRequestProxy>> m_pendingRejections;
178
179 Vector<Ref<UserMediaPermissionRequestProxy>> m_pregrantedRequests;
180 Vector<Ref<UserMediaPermissionRequestProxy>> m_grantedRequests;
181
182 Vector<DeniedRequest> m_deniedRequests;
183
184 WebCore::MediaProducerMediaStateFlags m_captureState;
185 RunLoop::Timer<UserMediaPermissionRequestManagerProxy> m_watchdogTimer;
186 Seconds m_currentWatchdogInterval;
187#if !RELEASE_LOG_DISABLED
188 Ref<const Logger> m_logger;
189 const void* m_logIdentifier;
190#endif
191 bool m_hasFilteredDeviceList { false };
192#if PLATFORM(COCOA)
193 bool m_hasCreatedSandboxExtensionForTCCD { false };
194#endif
195 uint64_t m_hasPendingCapture { 0 };
196 std::optional<bool> m_mockDevicesEnabledOverride;
197};
198
199String convertEnumerationToString(UserMediaPermissionRequestManagerProxy::RequestAction);
200
201} // namespace WebKit
202
203#if ENABLE(MEDIA_STREAM)
204namespace WTF {
205
206template<typename Type>
207struct LogArgument;
208
209template <>
210struct LogArgument<WebKit::UserMediaPermissionRequestManagerProxy::RequestAction> {
211 static String toString(const WebKit::UserMediaPermissionRequestManagerProxy::RequestAction type)
212 {
213 return convertEnumerationToString(type);
214 }
215};
216
217}; // namespace WTF
218#endif
Note: See TracBrowser for help on using the repository browser.