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 |
|
---|
38 | namespace WebCore {
|
---|
39 | class CaptureDevice;
|
---|
40 | struct ClientOrigin;
|
---|
41 | struct MediaConstraints;
|
---|
42 | struct MediaStreamRequest;
|
---|
43 | class SecurityOrigin;
|
---|
44 | };
|
---|
45 |
|
---|
46 | namespace WebKit {
|
---|
47 |
|
---|
48 | class WebPageProxy;
|
---|
49 |
|
---|
50 | enum MediaDevicePermissionRequestIdentifierType { };
|
---|
51 | using MediaDevicePermissionRequestIdentifier = ObjectIdentifier<MediaDevicePermissionRequestIdentifierType>;
|
---|
52 |
|
---|
53 | class 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;
|
---|
64 | public:
|
---|
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 |
|
---|
126 | private:
|
---|
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 |
|
---|
199 | String convertEnumerationToString(UserMediaPermissionRequestManagerProxy::RequestAction);
|
---|
200 |
|
---|
201 | } // namespace WebKit
|
---|
202 |
|
---|
203 | #if ENABLE(MEDIA_STREAM)
|
---|
204 | namespace WTF {
|
---|
205 |
|
---|
206 | template<typename Type>
|
---|
207 | struct LogArgument;
|
---|
208 |
|
---|
209 | template <>
|
---|
210 | struct 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
|
---|