Changeset 209082 in webkit
- Timestamp:
- Nov 29, 2016 11:20:08 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r209081 r209082 1 2016-11-29 Eric Carlson <eric.carlson@apple.com> 2 3 [MediaStream] Don't request user permission for a device if it has already been granted in the current browsing context 4 https://bugs.webkit.org/show_bug.cgi?id=164760 5 6 Reviewed by Youenn Fablet. 7 8 * fast/mediastream/MediaDevices-getUserMedia-expected.txt: 9 * fast/mediastream/MediaDevices-getUserMedia.html: 10 1 11 2016-11-29 Ryan Haddad <ryanhaddad@apple.com> 2 12 -
trunk/LayoutTests/fast/mediastream/MediaDevices-enumerateDevices.html
r209024 r209082 59 59 if (window.testRunner) { 60 60 testRunner.setUserMediaPermission(true); 61 testRunner.setUserMediaPer missionForOrigin(false, document.location.href, "");61 testRunner.setUserMediaPersistentPermissionForOrigin(false, document.location.href, ""); 62 62 } 63 63 … … 78 78 { 79 79 if (window.testRunner) 80 testRunner.setUserMediaPer missionForOrigin(true, document.location.href, "");80 testRunner.setUserMediaPersistentPermissionForOrigin(true, document.location.href, ""); 81 81 82 82 debug(`<br>*** Calling mediaDevices.enumerateDevices with persistent access, and without a media stream track<br>`); -
trunk/LayoutTests/fast/mediastream/MediaDevices-getUserMedia-expected.txt
r206011 r209082 32 32 PASS navigator.mediaDevices.getUserMedia({audio:false, video:videoConstraints}).then(invalidGotStream).catch(errorWithConstraints2) did not throw exception. 33 33 PASS Error callback called. 34 PASS navigator.mediaDevices.getUserMedia({audio:true}).then(invalidGotStream, error1); did not throw exception. 35 PASS Error callback called. 36 PASS errorArg.name is "NotAllowedError" 37 PASS navigator.mediaDevices.getUserMedia({audio:true}).then(invalidGotStream).catch(error2); did not throw exception. 38 PASS Error callback called. 34 PASS errorArg.name is "Error" 35 PASS navigator.mediaDevices.getUserMedia({audio:true}).then(validStream, error1); did not throw exception. 36 PASS Stream generated because page has already authenticated. 39 37 PASS successfullyParsed is true 40 38 -
trunk/LayoutTests/fast/mediastream/MediaDevices-getUserMedia.html
r208559 r209082 28 28 } 29 29 30 function error2(e) {31 testPassed(" Error callback called.");30 function validStream(e) { 31 testPassed("Stream generated because page has already authenticated."); 32 32 finishJSTest(); 33 33 } 34 34 35 35 function error1(e) { 36 errorArg = e; 37 testPassed("Error callback called."); 38 shouldBeEqualToString("errorArg.name", "NotAllowedError"); 39 40 shouldNotThrow("navigator.mediaDevices.getUserMedia({audio:true}).then(invalidGotStream).catch(error2);"); 36 testFailed("Error callback called."); 37 finishJSTest(); 41 38 } 42 39 43 function errorWithConstraints2( ) {40 function errorWithConstraints2(e) { 44 41 testPassed("Error callback called."); 42 errorArg = e; 43 shouldBeEqualToString("errorArg.name", "Error"); 44 45 // We tell LayoutTestRunner to deny user media requests but expect the gUM call to succeed 46 // as it should not see the request because the current browsing context has already 47 // successfully created a stream for the mock audio device. 45 48 setUserMediaPermission(false); 46 shouldNotThrow("navigator.mediaDevices.getUserMedia({audio:true}).then( invalidGotStream, error1);");49 shouldNotThrow("navigator.mediaDevices.getUserMedia({audio:true}).then(validStream, error1);"); 47 50 } 48 51 -
trunk/LayoutTests/http/tests/media/media-stream/enumerate-devices-source-id-persistent.html
r209024 r209082 12 12 if (window.testRunner) { 13 13 testRunner.setUserMediaPermission(true); 14 testRunner.setUserMediaPer missionForOrigin(true, "http://localhost:8000", location.href);14 testRunner.setUserMediaPersistentPermissionForOrigin(true, "http://localhost:8000", location.href); 15 15 } 16 16 -
trunk/Source/WebKit2/ChangeLog
r209070 r209082 1 2016-11-29 Eric Carlson <eric.carlson@apple.com> 2 3 [MediaStream] Don't request user permission for a device if it has already been granted in the current browsing context 4 https://bugs.webkit.org/show_bug.cgi?id=164760 5 <rdar://problem/29261266> 6 7 Reviewed by Youenn Fablet. 8 9 * UIProcess/UserMediaPermissionRequestManagerProxy.cpp: 10 (WebKit::FrameAuthorizationState::FrameAuthorizationState): 11 (WebKit::FrameAuthorizationState::hasPermissionToUseCaptureDevice): 12 (WebKit::FrameAuthorizationState::setHasPermissionToUseCaptureDevice): 13 (WebKit::FrameAuthorizationState::reset): 14 (WebKit::FrameAuthorizationState::securityOriginsAreEqual): 15 (WebKit::UserMediaPermissionRequestManagerProxy::stateForRequest): 16 (WebKit::UserMediaPermissionRequestManagerProxy::invalidateRequests): 17 (WebKit::UserMediaPermissionRequestManagerProxy::createRequest): 18 (WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasDenied): 19 (WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted): 20 (WebKit::UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame): 21 * UIProcess/UserMediaPermissionRequestManagerProxy.h: 22 (WebKit::FrameAuthorizationState::~FrameAuthorizationState): 23 (WebKit::FrameAuthorizationState::frameID): 24 * UIProcess/UserMediaPermissionRequestProxy.cpp: 25 (WebKit::UserMediaPermissionRequestProxy::UserMediaPermissionRequestProxy): 26 * UIProcess/UserMediaPermissionRequestProxy.h: 27 (WebKit::UserMediaPermissionRequestProxy::create): 28 (WebKit::UserMediaPermissionRequestProxy::frameID): 29 (WebKit::UserMediaPermissionRequestProxy::userMediaDocumentSecurityOrigin): 30 (WebKit::UserMediaPermissionRequestProxy::topLevelDocumentSecurityOrigin): 31 * UIProcess/WebPageProxy.cpp: 32 (WebKit::WebPageProxy::didCommitLoadForFrame): 33 * WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp: 34 (WebKit::UserMediaPermissionRequestManager::removeMediaRequestFromMaps): 35 1 36 2016-11-29 Wenson Hsieh <wenson_hsieh@apple.com> 2 37 -
trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp
r208903 r209082 2633 2633 } 2634 2634 2635 void WKPageClearUserMediaState(WKPageRef page) 2636 { 2637 #if ENABLE(MEDIA_STREAM) 2638 toImpl(page)->clearUserMediaState(); 2639 #else 2640 UNUSED_PARAM(page); 2641 #endif 2642 } 2643 2635 2644 void WKPageDidDenyPointerLock(WKPageRef page) 2636 2645 { -
trunk/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h
r208903 r209082 129 129 typedef uint32_t WKMediaMutedState; 130 130 WK_EXPORT void WKPageSetMuted(WKPageRef page, WKMediaMutedState muted); 131 131 132 WK_EXPORT void WKPageClearUserMediaState(WKPageRef page); 133 132 134 WK_EXPORT void WKPageDidAllowPointerLock(WKPageRef page); 133 135 WK_EXPORT void WKPageDidDenyPointerLock(WKPageRef page); -
trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp
r209024 r209082 35 35 namespace WebKit { 36 36 37 FrameAuthorizationState::FrameAuthorizationState(UserMediaPermissionRequestProxy& request) 38 : m_userMediaDocumentSecurityOrigin(request.userMediaDocumentSecurityOrigin()) 39 , m_topLevelDocumentSecurityOrigin(request.topLevelDocumentSecurityOrigin()) 40 { 41 } 42 43 bool FrameAuthorizationState::hasPermissionToUseCaptureDevice(const String& deviceUID) 44 { 45 return m_authorizedDeviceUIDs.find(deviceUID) != notFound; 46 } 47 48 void FrameAuthorizationState::setHasPermissionToUseCaptureDevice(const String& deviceUID, bool hasPermission) 49 { 50 if (deviceUID.isEmpty()) 51 return; 52 53 size_t index = m_authorizedDeviceUIDs.find(deviceUID); 54 if (hasPermission == (index != notFound)) 55 return; 56 57 if (hasPermission) 58 m_authorizedDeviceUIDs.append(deviceUID); 59 else 60 m_authorizedDeviceUIDs.remove(index); 61 } 62 63 void FrameAuthorizationState::ensureSecurityOriginsAreEqual(UserMediaPermissionRequestProxy& request) 64 { 65 do { 66 if (!m_userMediaDocumentSecurityOrigin || !m_userMediaDocumentSecurityOrigin->equal(request.userMediaDocumentSecurityOrigin())) 67 break; 68 69 if (!m_topLevelDocumentSecurityOrigin || !m_topLevelDocumentSecurityOrigin->equal(request.topLevelDocumentSecurityOrigin())) 70 break; 71 72 return; 73 } while (0); 74 75 m_userMediaDocumentSecurityOrigin = request.userMediaDocumentSecurityOrigin(); 76 m_topLevelDocumentSecurityOrigin = request.topLevelDocumentSecurityOrigin(); 77 m_authorizedDeviceUIDs.clear(); 78 } 79 80 FrameAuthorizationState& UserMediaPermissionRequestManagerProxy::stateForRequest(UserMediaPermissionRequestProxy& request) 81 { 82 auto& state = m_frameStates.add(request.frameID(), nullptr).iterator->value; 83 if (state) { 84 state->ensureSecurityOriginsAreEqual(request); 85 return *state; 86 } 87 88 state = std::make_unique<FrameAuthorizationState>(request); 89 return *state; 90 } 91 37 92 UserMediaPermissionRequestManagerProxy::UserMediaPermissionRequestManagerProxy(WebPageProxy& page) 38 93 : m_page(page) … … 50 105 m_pendingDeviceRequests.clear(); 51 106 52 m_pageSandboxExtensionsGranted.clear(); 53 } 54 55 Ref<UserMediaPermissionRequestProxy> UserMediaPermissionRequestManagerProxy::createRequest(uint64_t userMediaID, const Vector<String>& audioDeviceUIDs, const Vector<String>& videoDeviceUIDs) 56 { 57 Ref<UserMediaPermissionRequestProxy> request = UserMediaPermissionRequestProxy::create(*this, userMediaID, audioDeviceUIDs, videoDeviceUIDs); 58 m_pendingUserMediaRequests.add(userMediaID, request.ptr()); 59 return request; 60 } 61 62 Ref<UserMediaPermissionRequestProxy> UserMediaPermissionRequestManagerProxy::createRequest(uint64_t userMediaID) 63 { 64 Ref<UserMediaPermissionRequestProxy> request = UserMediaPermissionRequestProxy::create(*this, userMediaID, Vector<String>(), Vector<String>()); 107 m_frameStates.clear(); 108 } 109 110 void UserMediaPermissionRequestManagerProxy::clearCachedState() 111 { 112 invalidateRequests(); 113 } 114 115 Ref<UserMediaPermissionRequestProxy> UserMediaPermissionRequestManagerProxy::createRequest(uint64_t userMediaID, uint64_t frameID, const String& userMediaDocumentOriginIdentifier, const String& topLevelDocumentOriginIdentifier, const Vector<String>& audioDeviceUIDs, const Vector<String>& videoDeviceUIDs) 116 { 117 auto request = UserMediaPermissionRequestProxy::create(*this, userMediaID, frameID, userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier, audioDeviceUIDs, videoDeviceUIDs); 65 118 m_pendingUserMediaRequests.add(userMediaID, request.ptr()); 66 119 return request; … … 104 157 return; 105 158 106 if (!m_pendingUserMediaRequests.take(userMediaID)) 107 return; 108 109 denyRequest(userMediaID, reason, ""); 159 auto request = m_pendingUserMediaRequests.take(userMediaID); 160 if (!request) 161 return; 162 163 auto fameState = stateForRequest(*request); 164 for (const auto& deviceUID : request->videoDeviceUIDs()) 165 fameState.setHasPermissionToUseCaptureDevice(deviceUID, false); 166 for (const auto& deviceUID : request->audioDeviceUIDs()) 167 fameState.setHasPermissionToUseCaptureDevice(deviceUID, false); 168 169 denyRequest(userMediaID, reason, emptyString()); 110 170 } 111 171 … … 129 189 return; 130 190 131 if (!m_pendingUserMediaRequests.take(userMediaID)) 132 return; 133 134 #if ENABLE(MEDIA_STREAM) 191 #if ENABLE(MEDIA_STREAM) 192 auto request = m_pendingUserMediaRequests.take(userMediaID); 193 if (!request) 194 return; 195 196 auto& fameState = stateForRequest(*request); 197 fameState.setHasPermissionToUseCaptureDevice(audioDeviceUID, true); 198 fameState.setHasPermissionToUseCaptureDevice(videoDeviceUID, true); 199 135 200 size_t extensionCount = 0; 136 201 unsigned requiredExtensions = SandboxExtensionsGranted::None; … … 144 209 } 145 210 146 unsigned currentExtensions = m_pageSandboxExtensionsGranted .get(m_page.pageID());211 unsigned currentExtensions = m_pageSandboxExtensionsGranted; 147 212 if (!(requiredExtensions & currentExtensions)) { 148 213 ASSERT(extensionCount); 149 m_pageSandboxExtensionsGranted .set(m_page.pageID(), requiredExtensions | currentExtensions);214 m_pageSandboxExtensionsGranted = requiredExtensions | currentExtensions; 150 215 SandboxExtension::HandleArray handles; 151 216 handles.allocate(extensionCount); … … 159 224 m_page.process().send(Messages::WebPage::UserMediaAccessWasGranted(userMediaID, audioDeviceUID, videoDeviceUID), m_page.pageID()); 160 225 #else 226 UNUSED_PARAM(userMediaID); 161 227 UNUSED_PARAM(audioDeviceUID); 162 228 UNUSED_PARAM(videoDeviceUID); … … 179 245 180 246 if (videoDeviceUIDs.isEmpty() && audioDeviceUIDs.isEmpty()) { 181 denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints, "");247 denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints, emptyString()); 182 248 return; 183 249 } … … 185 251 auto userMediaOrigin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(userMediaDocumentOriginIdentifier)->securityOrigin()); 186 252 auto topLevelOrigin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(topLevelDocumentOriginIdentifier)->securityOrigin()); 187 auto request = createRequest(userMediaID, audioDeviceUIDs, videoDeviceUIDs); 188 189 if (!m_page.uiClient().decidePolicyForUserMediaPermissionRequest(m_page, *m_page.process().webFrame(frameID), *userMediaOrigin.get(), *topLevelOrigin.get(), request.get())) { 190 m_pendingUserMediaRequests.take(userMediaID); 191 request->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::UserMediaDisabled); 253 auto request = createRequest(userMediaID, frameID, userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier, audioDeviceUIDs, videoDeviceUIDs); 254 255 String authorizedAudioDevice; 256 String authorizedVideoDevice; 257 auto& fameState = stateForRequest(request); 258 for (auto deviceUID : audioDeviceUIDs) { 259 if (fameState.hasPermissionToUseCaptureDevice(deviceUID)) { 260 authorizedAudioDevice = deviceUID; 261 break; 262 } 192 263 } 264 for (auto deviceUID : videoDeviceUIDs) { 265 if (fameState.hasPermissionToUseCaptureDevice(deviceUID)) { 266 authorizedVideoDevice = deviceUID; 267 break; 268 } 269 } 270 271 if (audioDeviceUIDs.isEmpty() == authorizedAudioDevice.isEmpty() && videoDeviceUIDs.isEmpty() == authorizedVideoDevice.isEmpty()) { 272 userMediaAccessWasGranted(userMediaID, authorizedAudioDevice, authorizedVideoDevice); 273 return; 274 } 275 276 if (!m_page.uiClient().decidePolicyForUserMediaPermissionRequest(m_page, *m_page.process().webFrame(frameID), *userMediaOrigin.get(), *topLevelOrigin.get(), request.get())) 277 userMediaAccessWasDenied(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::UserMediaDisabled); 278 193 279 }; 194 280 -
trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h
r209024 r209082 23 23 #include "UserMediaPermissionCheckProxy.h" 24 24 #include "UserMediaPermissionRequestProxy.h" 25 #include <WebCore/SecurityOrigin.h> 25 26 #include <WebCore/UserMediaRequest.h> 26 27 #include <wtf/HashMap.h> … … 35 36 class WebPageProxy; 36 37 38 class FrameAuthorizationState { 39 public: 40 explicit FrameAuthorizationState(UserMediaPermissionRequestProxy&); 41 42 bool hasPermissionToUseCaptureDevice(const String& deviceUID); 43 void setHasPermissionToUseCaptureDevice(const String&, bool); 44 45 void ensureSecurityOriginsAreEqual(UserMediaPermissionRequestProxy&); 46 47 private: 48 RefPtr<WebCore::SecurityOrigin> m_userMediaDocumentSecurityOrigin; 49 RefPtr<WebCore::SecurityOrigin> m_topLevelDocumentSecurityOrigin; 50 Vector<String> m_authorizedDeviceUIDs; 51 }; 52 37 53 class UserMediaPermissionRequestManagerProxy { 38 54 public: … … 45 61 void userMediaAccessWasGranted(uint64_t, const String& audioDeviceUID, const String& videoDeviceUID); 46 62 void userMediaAccessWasDenied(uint64_t, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason); 63 FrameAuthorizationState& stateForRequest(UserMediaPermissionRequestProxy&); 47 64 48 65 void enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier); … … 50 67 void didCompleteUserMediaPermissionCheck(uint64_t, const String&, bool allow); 51 68 69 void clearCachedState(); 70 52 71 private: 53 Ref<UserMediaPermissionRequestProxy> createRequest(uint64_t, const Vector<String>& audioDeviceUIDs, const Vector<String>& videoDeviceUIDs); 54 Ref<UserMediaPermissionRequestProxy> createRequest(uint64_t userMediaID); 72 Ref<UserMediaPermissionRequestProxy> createRequest(uint64_t userMediaID, uint64_t frameID, const String&userMediaDocumentOriginIdentifier, const String& topLevelDocumentOriginIdentifier, const Vector<String>& audioDeviceUIDs, const Vector<String>& videoDeviceUIDs); 55 73 void denyRequest(uint64_t userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason, const String& invalidConstraint); 56 74 Ref<UserMediaPermissionCheckProxy> createUserMediaPermissionCheck(uint64_t userMediaID); … … 65 83 Audio = 1 << 1 66 84 }; 67 HashMap<uint64_t, unsigned> m_pageSandboxExtensionsGranted; 85 unsigned m_pageSandboxExtensionsGranted; 86 87 HashMap<uint64_t, std::unique_ptr<FrameAuthorizationState>> m_frameStates; 68 88 69 89 WebPageProxy& m_page; -
trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.cpp
r209024 r209082 23 23 #include "UserMediaPermissionRequestManagerProxy.h" 24 24 #include <WebCore/RealtimeMediaSourceCenter.h> 25 #include <WebCore/SecurityOrigin.h> 26 #include <WebCore/SecurityOriginData.h> 25 27 #include <wtf/text/StringHash.h> 28 29 using namespace WebCore; 26 30 27 31 namespace WebKit { 28 32 29 UserMediaPermissionRequestProxy::UserMediaPermissionRequestProxy(UserMediaPermissionRequestManagerProxy& manager, uint64_t userMediaID, const Vector<String>& audioDeviceUIDs, const Vector<String>& videoDeviceUIDs)33 UserMediaPermissionRequestProxy::UserMediaPermissionRequestProxy(UserMediaPermissionRequestManagerProxy& manager, uint64_t userMediaID, uint64_t frameID, const String& userMediaDocumentOriginIdentifier, const String& topLevelDocumentOriginIdentifier, const Vector<String>& audioDeviceUIDs, const Vector<String>& videoDeviceUIDs) 30 34 : m_manager(&manager) 31 35 , m_userMediaID(userMediaID) 36 , m_frameID(frameID) 37 , m_userMediaDocumentSecurityOrigin((SecurityOriginData::fromDatabaseIdentifier(userMediaDocumentOriginIdentifier)->securityOrigin())) 38 , m_topLevelDocumentSecurityOrigin(SecurityOriginData::fromDatabaseIdentifier(topLevelDocumentOriginIdentifier)->securityOrigin()) 32 39 , m_videoDeviceUIDs(videoDeviceUIDs) 33 40 , m_audioDeviceUIDs(audioDeviceUIDs) -
trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.h
r209024 r209082 26 26 #include <wtf/text/WTFString.h> 27 27 28 namespace WebCore { 29 class SecurityOrigin; 30 } 31 28 32 namespace WebKit { 29 33 … … 32 36 class UserMediaPermissionRequestProxy : public API::ObjectImpl<API::Object::Type::UserMediaPermissionRequest> { 33 37 public: 34 static Ref<UserMediaPermissionRequestProxy> create(UserMediaPermissionRequestManagerProxy& manager, uint64_t userMediaID, const Vector<String>& videoDeviceUIDs, const Vector<String>& audioDeviceUIDs)38 static Ref<UserMediaPermissionRequestProxy> create(UserMediaPermissionRequestManagerProxy& manager, uint64_t userMediaID, uint64_t frameID, const String& userMediaDocumentOriginIdentifier, const String& topLevelDocumentOriginIdentifier, const Vector<String>& videoDeviceUIDs, const Vector<String>& audioDeviceUIDs) 35 39 { 36 return adoptRef(*new UserMediaPermissionRequestProxy(manager, userMediaID, videoDeviceUIDs, audioDeviceUIDs));40 return adoptRef(*new UserMediaPermissionRequestProxy(manager, userMediaID, frameID, userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier, videoDeviceUIDs, audioDeviceUIDs)); 37 41 } 38 42 … … 50 54 const Vector<String>& audioDeviceUIDs() const { return m_audioDeviceUIDs; } 51 55 56 uint64_t frameID() const { return m_frameID; } 57 WebCore::SecurityOrigin* userMediaDocumentSecurityOrigin() { return &m_userMediaDocumentSecurityOrigin.get(); } 58 WebCore::SecurityOrigin* topLevelDocumentSecurityOrigin() { return &m_topLevelDocumentSecurityOrigin.get(); } 59 52 60 private: 53 UserMediaPermissionRequestProxy(UserMediaPermissionRequestManagerProxy&, uint64_t userMediaID, const Vector<String>& videoDeviceUIDs, const Vector<String>& audioDeviceUIDs);61 UserMediaPermissionRequestProxy(UserMediaPermissionRequestManagerProxy&, uint64_t userMediaID, uint64_t frameID, const String& userMediaDocumentOriginIdentifier, const String& topLevelDocumentOriginIdentifier, const Vector<String>& videoDeviceUIDs, const Vector<String>& audioDeviceUIDs); 54 62 55 63 UserMediaPermissionRequestManagerProxy* m_manager; 56 64 uint64_t m_userMediaID; 65 uint64_t m_frameID; 66 Ref<WebCore::SecurityOrigin> m_userMediaDocumentSecurityOrigin; 67 Ref<WebCore::SecurityOrigin> m_topLevelDocumentSecurityOrigin; 57 68 Vector<String> m_videoDeviceUIDs; 58 69 Vector<String> m_audioDeviceUIDs; -
trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp
r209067 r209082 5733 5733 } 5734 5734 5735 void WebPageProxy::clearUserMediaState() 5736 { 5737 #if ENABLE(MEDIA_STREAM) 5738 m_userMediaPermissionRequestManager.clearCachedState(); 5739 #endif 5740 } 5735 5741 5736 5742 void WebPageProxy::requestNotificationPermission(uint64_t requestID, const String& originString) -
trunk/Source/WebKit2/UIProcess/WebPageProxy.h
r208985 r209082 1171 1171 void isLoadingChanged() { activityStateDidChange(WebCore::ActivityState::IsLoading); } 1172 1172 1173 void clearUserMediaState(); 1174 1173 1175 private: 1174 1176 WebPageProxy(PageClient&, WebProcessProxy&, uint64_t pageID, Ref<API::PageConfiguration>&&); -
trunk/Tools/ChangeLog
r209073 r209082 1 2016-11-29 Eric Carlson <eric.carlson@apple.com> 2 3 [MediaStream] Don't request user permission for a device if it has already been granted in the current browsing context 4 https://bugs.webkit.org/show_bug.cgi?id=164760 5 <rdar://problem/29261266> 6 7 Reviewed by Youenn Fablet. 8 9 Allow scripts to determine the number of times the user has been prompted for capture device access. 10 11 * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: 12 * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp: 13 (WTR::InjectedBundle::setUserMediaPersistentPermissionForOrigin): 14 (WTR::InjectedBundle::userMediaPermissionRequestCountForOrigin): 15 (WTR::InjectedBundle::resetUserMediaPermissionRequestCountForOrigin): 16 (WTR::InjectedBundle::setUserMediaPermissionForOrigin): Deleted. 17 * WebKitTestRunner/InjectedBundle/InjectedBundle.h: 18 * WebKitTestRunner/InjectedBundle/TestRunner.cpp: 19 (WTR::TestRunner::setUserMediaPersistentPermissionForOrigin): 20 (WTR::TestRunner::userMediaPermissionRequestCountForOrigin): 21 (WTR::TestRunner::resetUserMediaPermissionRequestCountForOrigin): 22 (WTR::TestRunner::setUserMediaPermissionForOrigin): Deleted. 23 * WebKitTestRunner/InjectedBundle/TestRunner.h: 24 * WebKitTestRunner/TestController.cpp: 25 (WTR::TestController::resetStateToConsistentValues): 26 (WTR::OriginSettings::incrementRequestCount): 27 (WTR::OriginSettings::resetRequestCount): 28 (WTR::OriginSettings::requestCount): 29 (WTR::TestController::saltForOrigin): 30 (WTR::TestController::setUserMediaPersistentPermissionForOrigin): 31 (WTR::TestController::handleCheckOfUserMediaPermissionForOrigin): 32 (WTR::TestController::settingsForOrigin): 33 (WTR::TestController::userMediaPermissionRequestCountForOrigin): 34 (WTR::TestController::resetUserMediaPermissionRequestCountForOrigin): 35 (WTR::TestController::decidePolicyForUserMediaPermissionRequestIfPossible): 36 (WTR::TestController::setUserMediaPermissionForOrigin): Deleted. 37 * WebKitTestRunner/TestController.h: 38 * WebKitTestRunner/TestInvocation.cpp: 39 (WTR::TestInvocation::didReceiveMessageFromInjectedBundle): 40 (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle): 41 1 42 2016-11-29 Simon Fraser <simon.fraser@apple.com> 2 43 -
trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl
r209024 r209082 186 186 // MediaStream 187 187 void setUserMediaPermission(boolean value); 188 void setUserMediaPermissionForOrigin(boolean permission, DOMString origin, DOMString parentOrigin); 188 void setUserMediaPersistentPermissionForOrigin(boolean permission, DOMString origin, DOMString parentOrigin); 189 unsigned long userMediaPermissionRequestCountForOrigin(DOMString origin, DOMString parentOrigin); 190 void resetUserMediaPermissionRequestCountForOrigin(DOMString origin, DOMString parentOrigin); 189 191 190 192 // Audio testing. -
trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
r209024 r209082 583 583 } 584 584 585 void InjectedBundle::setUserMediaPer missionForOrigin(bool permission, WKStringRef origin, WKStringRef parentOrigin)586 { 587 auto messageName = adoptWK(WKStringCreateWithUTF8CString("SetUserMediaPer missionForOrigin"));585 void InjectedBundle::setUserMediaPersistentPermissionForOrigin(bool permission, WKStringRef origin, WKStringRef parentOrigin) 586 { 587 auto messageName = adoptWK(WKStringCreateWithUTF8CString("SetUserMediaPersistentPermissionForOrigin")); 588 588 WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate()); 589 589 … … 591 591 WKRetainPtr<WKBooleanRef> permissionWK(AdoptWK, WKBooleanCreate(permission)); 592 592 WKDictionarySetItem(messageBody.get(), permissionKeyWK.get(), permissionWK.get()); 593 594 WKRetainPtr<WKStringRef> originKeyWK(AdoptWK, WKStringCreateWithUTF8CString("origin")); 595 WKDictionarySetItem(messageBody.get(), originKeyWK.get(), origin); 596 597 WKRetainPtr<WKStringRef> parentOriginKeyWK(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin")); 598 WKDictionarySetItem(messageBody.get(), parentOriginKeyWK.get(), parentOrigin); 599 600 WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get()); 601 } 602 603 unsigned InjectedBundle::userMediaPermissionRequestCountForOrigin(WKStringRef origin, WKStringRef parentOrigin) const 604 { 605 WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("UserMediaPermissionRequestCountForOrigin")); 606 WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate()); 607 608 WKRetainPtr<WKStringRef> originKeyWK(AdoptWK, WKStringCreateWithUTF8CString("origin")); 609 WKDictionarySetItem(messageBody.get(), originKeyWK.get(), origin); 610 611 WKRetainPtr<WKStringRef> parentOriginKeyWK(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin")); 612 WKDictionarySetItem(messageBody.get(), parentOriginKeyWK.get(), parentOrigin); 613 614 WKTypeRef resultToPass = 0; 615 WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), messageBody.get(), &resultToPass); 616 WKRetainPtr<WKUInt64Ref> count(AdoptWK, static_cast<WKUInt64Ref>(resultToPass)); 617 618 return static_cast<unsigned>(WKUInt64GetValue(count.get())); 619 } 620 621 void InjectedBundle::resetUserMediaPermissionRequestCountForOrigin(WKStringRef origin, WKStringRef parentOrigin) 622 { 623 WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("ResetUserMediaPermissionRequestCountForOrigin")); 624 WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate()); 593 625 594 626 WKRetainPtr<WKStringRef> originKeyWK(AdoptWK, WKStringCreateWithUTF8CString("origin")); -
trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.h
r209024 r209082 102 102 // MediaStream. 103 103 void setUserMediaPermission(bool); 104 void setUserMediaPermissionForOrigin(bool permission, WKStringRef origin, WKStringRef parentOrigin); 104 void setUserMediaPersistentPermissionForOrigin(bool permission, WKStringRef origin, WKStringRef parentOrigin); 105 unsigned userMediaPermissionRequestCountForOrigin(WKStringRef origin, WKStringRef parentOrigin) const; 106 void resetUserMediaPermissionRequestCountForOrigin(WKStringRef origin, WKStringRef parentOrigin); 105 107 106 108 // Policy delegate. -
trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
r209024 r209082 890 890 } 891 891 892 void TestRunner::setUserMediaPer missionForOrigin(bool permission, JSStringRef origin, JSStringRef parentOrigin)892 void TestRunner::setUserMediaPersistentPermissionForOrigin(bool permission, JSStringRef origin, JSStringRef parentOrigin) 893 893 { 894 894 WKRetainPtr<WKStringRef> originWK = toWK(origin); 895 895 WKRetainPtr<WKStringRef> parentOriginWK = toWK(parentOrigin); 896 InjectedBundle::singleton().setUserMediaPermissionForOrigin(permission, originWK.get(), parentOriginWK.get()); 896 InjectedBundle::singleton().setUserMediaPersistentPermissionForOrigin(permission, originWK.get(), parentOriginWK.get()); 897 } 898 899 unsigned TestRunner::userMediaPermissionRequestCountForOrigin(JSStringRef origin, JSStringRef parentOrigin) const 900 { 901 WKRetainPtr<WKStringRef> originWK = toWK(origin); 902 WKRetainPtr<WKStringRef> parentOriginWK = toWK(parentOrigin); 903 return InjectedBundle::singleton().userMediaPermissionRequestCountForOrigin(originWK.get(), parentOriginWK.get()); 904 } 905 906 void TestRunner::resetUserMediaPermissionRequestCountForOrigin(JSStringRef origin, JSStringRef parentOrigin) 907 { 908 WKRetainPtr<WKStringRef> originWK = toWK(origin); 909 WKRetainPtr<WKStringRef> parentOriginWK = toWK(parentOrigin); 910 InjectedBundle::singleton().resetUserMediaPermissionRequestCountForOrigin(originWK.get(), parentOriginWK.get()); 897 911 } 898 912 -
trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
r209024 r209082 287 287 // MediaStream 288 288 void setUserMediaPermission(bool); 289 void setUserMediaPermissionForOrigin(bool permission, JSStringRef origin, JSStringRef parentOrigin); 289 void setUserMediaPersistentPermissionForOrigin(bool permission, JSStringRef origin, JSStringRef parentOrigin); 290 unsigned userMediaPermissionRequestCountForOrigin(JSStringRef origin, JSStringRef parentOrigin) const; 291 void resetUserMediaPermissionRequestCountForOrigin(JSStringRef origin, JSStringRef parentOrigin); 290 292 291 293 void setPageVisibility(JSStringRef state); … … 401 403 WKRetainPtr<WKArrayRef> m_allowedHosts; 402 404 405 size_t m_userMediaPermissionRequestCount { 0 }; 406 403 407 PlatformTimerRef m_waitToDumpWatchdogTimer; 404 408 }; -
trunk/Tools/WebKitTestRunner/TestController.cpp
r209073 r209082 757 757 WKPageSetMuted(m_mainWebView->page(), true); 758 758 759 WKPageClearUserMediaState(m_mainWebView->page()); 760 759 761 // Reset notification permissions 760 762 m_webNotificationProvider.reset(); … … 767 769 // Reset UserMedia permissions. 768 770 m_userMediaPermissionRequests.clear(); 769 m_ca hcedUserMediaPermissions.clear();771 m_cachedUserMediaPermissions.clear(); 770 772 m_isUserMediaPermissionSet = false; 771 773 m_isUserMediaPermissionAllowed = false; … … 1887 1889 HashMap<uint64_t, String>& ephemeralSalts() { return m_ephemeralSalts; } 1888 1890 1891 void incrementRequestCount() { ++m_requestCount; } 1892 void resetRequestCount() { m_requestCount = 0; } 1893 unsigned requestCount() const { return m_requestCount; } 1894 1889 1895 private: 1890 1896 HashMap<uint64_t, String> m_ephemeralSalts; 1891 1897 String m_persistentSalt; 1898 unsigned m_requestCount { 0 }; 1892 1899 bool m_persistentPermission { false }; 1893 1900 }; … … 1895 1902 String TestController::saltForOrigin(WKFrameRef frame, String originHash) 1896 1903 { 1897 RefPtr<OriginSettings> settings = m_cahcedUserMediaPermissions.get(originHash); 1898 if (!settings) { 1899 settings = adoptRef(*new OriginSettings()); 1900 m_cahcedUserMediaPermissions.add(originHash, settings); 1901 } 1902 1903 auto& ephemeralSalts = settings->ephemeralSalts(); 1904 auto& settings = settingsForOrigin(originHash); 1905 auto& ephemeralSalts = settings.ephemeralSalts(); 1904 1906 auto frameInfo = adoptWK(WKFrameCreateFrameInfo(frame)); 1905 1907 auto frameHandle = WKFrameInfoGetFrameHandleRef(frameInfo.get()); … … 1907 1909 String frameSalt = ephemeralSalts.get(frameIdentifier); 1908 1910 1909 if (settings ->persistentPermission()) {1911 if (settings.persistentPermission()) { 1910 1912 if (frameSalt.length()) 1911 1913 return frameSalt; 1912 1914 1913 if (!settings ->persistentSalt().length())1914 settings ->setPersistentSalt(createCanonicalUUIDString());1915 1916 return settings ->persistentSalt();1915 if (!settings.persistentSalt().length()) 1916 settings.setPersistentSalt(createCanonicalUUIDString()); 1917 1918 return settings.persistentSalt(); 1917 1919 } 1918 1920 … … 1925 1927 } 1926 1928 1927 void TestController::setUserMediaPer missionForOrigin(bool permission, WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString)1929 void TestController::setUserMediaPersistentPermissionForOrigin(bool permission, WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString) 1928 1930 { 1929 1931 auto originHash = userMediaOriginHash(userMediaDocumentOriginString, topLevelDocumentOriginString); 1930 RefPtr<OriginSettings> settings = m_cahcedUserMediaPermissions.get(originHash); 1931 if (!settings) { 1932 settings = adoptRef(*new OriginSettings()); 1933 m_cahcedUserMediaPermissions.add(originHash, settings); 1934 } 1935 1936 settings->setPersistentPermission(permission); 1932 auto& settings = settingsForOrigin(originHash); 1933 settings.setPersistentPermission(permission); 1937 1934 } 1938 1935 … … 1942 1939 auto salt = saltForOrigin(frame, originHash); 1943 1940 1944 WKUserMediaPermissionCheckSetUserMediaAccessInfo(checkRequest, WKStringCreateWithUTF8CString(salt.utf8().data()), m_cahcedUserMediaPermissions.get(originHash)->persistentPermission());1941 WKUserMediaPermissionCheckSetUserMediaAccessInfo(checkRequest, WKStringCreateWithUTF8CString(salt.utf8().data()), settingsForOrigin(originHash).persistentPermission()); 1945 1942 } 1946 1943 … … 1952 1949 } 1953 1950 1951 OriginSettings& TestController::settingsForOrigin(const String& originHash) 1952 { 1953 RefPtr<OriginSettings> settings = m_cachedUserMediaPermissions.get(originHash); 1954 if (!settings) { 1955 settings = adoptRef(*new OriginSettings()); 1956 m_cachedUserMediaPermissions.add(originHash, settings); 1957 } 1958 1959 return *settings; 1960 } 1961 1962 unsigned TestController::userMediaPermissionRequestCountForOrigin(WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString) 1963 { 1964 auto originHash = userMediaOriginHash(userMediaDocumentOriginString, topLevelDocumentOriginString); 1965 return settingsForOrigin(originHash).requestCount(); 1966 } 1967 1968 void TestController::resetUserMediaPermissionRequestCountForOrigin(WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString) 1969 { 1970 auto originHash = userMediaOriginHash(userMediaDocumentOriginString, topLevelDocumentOriginString); 1971 settingsForOrigin(originHash).resetRequestCount(); 1972 } 1973 1954 1974 void TestController::decidePolicyForUserMediaPermissionRequestIfPossible() 1955 1975 { … … 1961 1981 auto request = pair.second.get(); 1962 1982 1963 bool persistentPermission = false; 1964 RefPtr<OriginSettings> settings = m_cahcedUserMediaPermissions.get(originHash); 1965 if (settings) 1966 persistentPermission = settings->persistentPermission(); 1967 1968 if (!m_isUserMediaPermissionAllowed && !persistentPermission) { 1983 auto& settings = settingsForOrigin(originHash); 1984 settings.incrementRequestCount(); 1985 1986 if (!m_isUserMediaPermissionAllowed && !settings.persistentPermission()) { 1969 1987 WKUserMediaPermissionRequestDeny(request, kWKPermissionDenied); 1970 1988 continue; -
trunk/Tools/WebKitTestRunner/TestController.h
r209024 r209082 102 102 WKStringRef getUserMediaSaltForOrigin(WKFrameRef, WKStringRef originKey); 103 103 void setUserMediaPermission(bool); 104 void setUserMediaPer missionForOrigin(bool, WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString);104 void setUserMediaPersistentPermissionForOrigin(bool, WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString); 105 105 void handleUserMediaPermissionRequest(WKFrameRef, WKSecurityOriginRef, WKSecurityOriginRef, WKUserMediaPermissionRequestRef); 106 106 void handleCheckOfUserMediaPermissionForOrigin(WKFrameRef, WKSecurityOriginRef, WKSecurityOriginRef, const WKUserMediaPermissionCheckRef&); 107 OriginSettings& settingsForOrigin(const String&); 108 unsigned userMediaPermissionRequestCountForOrigin(WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString); 109 void resetUserMediaPermissionRequestCountForOrigin(WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString); 107 110 108 111 // Policy delegate. … … 317 320 bool m_isGeolocationPermissionAllowed { false }; 318 321 319 HashMap<String, RefPtr<OriginSettings>> m_ca hcedUserMediaPermissions;322 HashMap<String, RefPtr<OriginSettings>> m_cachedUserMediaPermissions; 320 323 321 324 typedef Vector<std::pair<String, WKRetainPtr<WKUserMediaPermissionRequestRef>>> PermissionRequestList; -
trunk/Tools/WebKitTestRunner/TestInvocation.cpp
r209024 r209082 497 497 } 498 498 499 if (WKStringIsEqualToUTF8CString(messageName, "SetUserMediaPer missionForOrigin")) {499 if (WKStringIsEqualToUTF8CString(messageName, "SetUserMediaPersistentPermissionForOrigin")) { 500 500 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); 501 501 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody); … … 511 511 WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get())); 512 512 513 TestController::singleton().setUserMediaPermissionForOrigin(permission, originWK, parentOriginWK); 513 TestController::singleton().setUserMediaPersistentPermissionForOrigin(permission, originWK, parentOriginWK); 514 return; 515 } 516 517 if (WKStringIsEqualToUTF8CString(messageName, "ResetUserMediaPermissionRequestCountForOrigin")) { 518 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); 519 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody); 520 521 WKRetainPtr<WKStringRef> originKey(AdoptWK, WKStringCreateWithUTF8CString("origin")); 522 WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get())); 523 524 WKRetainPtr<WKStringRef> parentOriginKey(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin")); 525 WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get())); 526 527 TestController::singleton().resetUserMediaPermissionRequestCountForOrigin(originWK, parentOriginWK); 514 528 return; 515 529 } … … 847 861 #endif // PLATFORM(MAC) 848 862 863 if (WKStringIsEqualToUTF8CString(messageName, "UserMediaPermissionRequestCountForOrigin")) { 864 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); 865 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody); 866 867 WKRetainPtr<WKStringRef> originKey(AdoptWK, WKStringCreateWithUTF8CString("origin")); 868 WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get())); 869 870 WKRetainPtr<WKStringRef> parentOriginKey(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin")); 871 WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get())); 872 873 unsigned count = TestController::singleton().userMediaPermissionRequestCountForOrigin(originWK, parentOriginWK); 874 WKRetainPtr<WKUInt64Ref> result(AdoptWK, WKUInt64Create(count)); 875 return result; 876 } 877 878 849 879 ASSERT_NOT_REACHED(); 850 880 return nullptr;
Note: See TracChangeset
for help on using the changeset viewer.