Changeset 241270 in webkit
- Timestamp:
- Feb 11, 2019 10:49:10 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r241268 r241270 1 2019-02-11 Youenn Fablet <youenn@apple.com> 2 3 Filter out Overconstrainederror.constraint when getUserMedia is not granted 4 https://bugs.webkit.org/show_bug.cgi?id=194240 5 6 Reviewed by Eric Carlson. 7 8 * fast/mediastream/overconstrainederror-constraint-expected.txt: Added. 9 * fast/mediastream/overconstrainederror-constraint.html: Added. 10 1 11 2019-02-11 Truitt Savell <tsavell@apple.com> 2 12 -
trunk/Source/WebKit/ChangeLog
r241262 r241270 1 2019-02-11 Youenn Fablet <youenn@apple.com> 2 3 Filter out Overconstrainederror.constraint when getUserMedia is not granted 4 https://bugs.webkit.org/show_bug.cgi?id=194240 5 6 Reviewed by Eric Carlson. 7 8 Make sure in UIProcess to filter out constraint if either the page was not granted gum access or it has no persistent access. 9 10 Refactor UserMediaPermissionRequestManagerProxy to make the implementation easier to understand. 11 12 Covered by added test. 13 14 * UIProcess/UserMediaPermissionCheckProxy.cpp: 15 (WebKit::UserMediaPermissionCheckProxy::setUserMediaAccessInfo): 16 * UIProcess/UserMediaPermissionRequestManagerProxy.cpp: 17 (WebKit::UserMediaPermissionRequestManagerProxy::captureDevicesChanged): 18 (WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted): 19 (WebKit::UserMediaPermissionRequestManagerProxy::grantAccess): 20 (WebKit::UserMediaPermissionRequestManagerProxy::getRequestAction): 21 (WebKit::UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame): 22 (WebKit::UserMediaPermissionRequestManagerProxy::processUserMediaPermissionRequest): 23 (WebKit::UserMediaPermissionRequestManagerProxy::processUserMediaPermissionInvalidRequest): 24 (WebKit::UserMediaPermissionRequestManagerProxy::processUserMediaPermissionValidRequest): 25 (WebKit::UserMediaPermissionRequestManagerProxy::getUserMediaPermissionInfo): 26 (WebKit::UserMediaPermissionRequestManagerProxy::wasGrantedVideoOrAudioAccess): 27 (WebKit::UserMediaPermissionRequestManagerProxy::computeFilteredDeviceList): 28 (WebKit::UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame): 29 (WebKit::UserMediaPermissionRequestManagerProxy::createPermissionRequest): Deleted. 30 * UIProcess/UserMediaPermissionRequestManagerProxy.h: 31 * UIProcess/UserMediaPermissionRequestProxy.h: 32 (WebKit::UserMediaPermissionRequestProxy::isPending const): 33 (WebKit::UserMediaPermissionRequestProxy::setEligibleVideoDeviceUIDs): 34 (WebKit::UserMediaPermissionRequestProxy::setEligibleAudioDeviceUIDs): 35 (WebKit::UserMediaPermissionRequestProxy::hasAudioDevice const): 36 (WebKit::UserMediaPermissionRequestProxy::hasVideoDevice const): 37 (WebKit::UserMediaPermissionRequestProxy::hasPersistentAccess const): 38 (WebKit::UserMediaPermissionRequestProxy::setHasPersistentAccess): 39 (WebKit::UserMediaPermissionRequestProxy::userMediaID const): 40 (WebKit::UserMediaPermissionRequestProxy::topLevelDocumentSecurityOrigin const): 41 (WebKit::UserMediaPermissionRequestProxy::userMediaDocumentSecurityOrigin const): 42 (WebKit::UserMediaPermissionRequestProxy::userRequest const): 43 (WebKit::UserMediaPermissionRequestProxy::setDeviceIdentifierHashSalt): 44 (WebKit::UserMediaPermissionRequestProxy::deviceIdentifierHashSalt const): 45 (WebKit::UserMediaPermissionRequestProxy::audioDevice const): 46 (WebKit::UserMediaPermissionRequestProxy::videoDevice const): 47 * UIProcess/WebPageProxy.cpp: 48 (WebKit::WebPageProxy::requestUserMediaPermissionForFrame): 49 * UIProcess/WebPageProxy.h: 50 1 51 2019-02-11 Carlos Garcia Campos <cgarcia@igalia.com> 2 52 -
trunk/Source/WebKit/UIProcess/UserMediaPermissionCheckProxy.cpp
r241252 r241270 42 42 } 43 43 44 UserMediaPermissionCheckProxy::~UserMediaPermissionCheckProxy() 45 { 46 invalidate(); 47 } 48 44 49 void UserMediaPermissionCheckProxy::setUserMediaAccessInfo(bool allowed) 45 50 { 46 51 ASSERT(m_completionHandler); 52 complete(allowed); 53 } 54 55 void UserMediaPermissionCheckProxy::complete(Optional<bool> allowed) 56 { 47 57 if (!m_completionHandler) 48 58 return; 49 59 50 m_completionHandler(allowed); 51 m_completionHandler = nullptr; 52 } 53 54 void UserMediaPermissionCheckProxy::invalidate() 55 { 56 m_completionHandler = nullptr; 60 auto completionHandler = WTFMove(m_completionHandler); 61 completionHandler(allowed); 57 62 } 58 63 -
trunk/Source/WebKit/UIProcess/UserMediaPermissionCheckProxy.h
r241252 r241270 28 28 #include "APIObject.h" 29 29 #include <WebCore/MediaConstraints.h> 30 #include <wtf/ Function.h>30 #include <wtf/CompletionHandler.h> 31 31 #include <wtf/text/WTFString.h> 32 32 … … 40 40 public: 41 41 42 using CompletionHandler = WTF:: Function<void(boolallowed)>;42 using CompletionHandler = WTF::CompletionHandler<void(Optional<bool> allowed)>; 43 43 44 44 static Ref<UserMediaPermissionCheckProxy> create(uint64_t frameID, CompletionHandler&& handler, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin) … … 49 49 void deny() { setUserMediaAccessInfo(false); } 50 50 void setUserMediaAccessInfo(bool); 51 void invalidate() ;51 void invalidate() { complete({ }); } 52 52 53 53 uint64_t frameID() const { return m_frameID; } … … 57 57 private: 58 58 UserMediaPermissionCheckProxy(uint64_t frameID, CompletionHandler&&, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin); 59 ~UserMediaPermissionCheckProxy(); 59 60 61 void complete(Optional<bool> allowed); 62 60 63 uint64_t m_frameID; 61 64 CompletionHandler m_completionHandler; -
trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp
r241252 r241270 76 76 m_pendingUserMediaRequests.clear(); 77 77 78 for (auto& request : m_pendingDeviceRequests.values())79 request->invalidate();80 78 m_pendingDeviceRequests.clear(); 81 79 } … … 93 91 return; 94 92 95 auto requestID = generateRequestID(); 96 auto handler = [this, weakThis = makeWeakPtr(*this), requestID](bool originHasPersistentAccess) mutable { 97 if (!weakThis) 98 return; 99 100 auto pendingRequest = m_pendingDeviceRequests.take(requestID); 101 if (!pendingRequest || !m_page.isValid()) 102 return; 103 104 if (m_grantedRequests.isEmpty() && !originHasPersistentAccess) 93 auto handler = [this](Optional<bool> originHasPersistentAccess) mutable { 94 if (!originHasPersistentAccess || !m_page.isValid()) 95 return; 96 97 if (m_grantedRequests.isEmpty() && !*originHasPersistentAccess) 105 98 return; 106 99 … … 109 102 110 103 auto origin = WebCore::SecurityOrigin::create(m_page.mainFrame()->url()); 111 getUserMediaPermissionInfo( requestID, m_page.mainFrame()->frameID(), WTFMove(handler), origin.get(), WTFMove(origin));104 getUserMediaPermissionInfo(m_page.mainFrame()->frameID(), origin.get(), WTFMove(origin), WTFMove(handler)); 112 105 #endif 113 106 } … … 116 109 { 117 110 invalidatePendingRequests(); 118 }119 120 Ref<UserMediaPermissionRequestProxy> UserMediaPermissionRequestManagerProxy::createPermissionRequest(uint64_t userMediaID, uint64_t mainFrameID, uint64_t frameID, Ref<SecurityOrigin>&& userMediaDocumentOrigin, Ref<SecurityOrigin>&& topLevelDocumentOrigin, Vector<CaptureDevice>&& audioDevices, Vector<CaptureDevice>&& videoDevices, MediaStreamRequest&& request)121 {122 auto permissionRequest = UserMediaPermissionRequestProxy::create(*this, userMediaID, mainFrameID, frameID, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin), WTFMove(audioDevices), WTFMove(videoDevices), WTFMove(request));123 m_pendingUserMediaRequests.add(userMediaID, permissionRequest.ptr());124 return permissionRequest;125 111 } 126 112 … … 189 175 return; 190 176 191 m_page.websiteDataStore().deviceIdHashSaltStorage().deviceIdHashSaltForOrigin(request->userMediaDocumentSecurityOrigin(), request->topLevelDocumentSecurityOrigin(), [this, weakThis = makeWeakPtr(*this), userMediaID, audioDevice = WTFMove(audioDevice), videoDevice = WTFMove(videoDevice), localRequest = request.copyRef()] (String&& deviceIDHashSalt) mutable { 177 auto& userMediaDocumentSecurityOrigin = request->userMediaDocumentSecurityOrigin(); 178 auto& topLevelDocumentSecurityOrigin = request->topLevelDocumentSecurityOrigin(); 179 m_page.websiteDataStore().deviceIdHashSaltStorage().deviceIdHashSaltForOrigin(userMediaDocumentSecurityOrigin, topLevelDocumentSecurityOrigin, [this, weakThis = makeWeakPtr(*this), request = request.releaseNonNull()] (String&& deviceIDHashSalt) mutable { 192 180 if (!weakThis) 193 181 return; 194 if (grantAccess(userMediaID, WTFMove(audioDevice), WTFMove(videoDevice), WTFMove(deviceIDHashSalt))) { 195 m_grantedRequests.append(localRequest.releaseNonNull()); 196 if (m_hasFilteredDeviceList) 197 captureDevicesChanged(); 198 m_hasFilteredDeviceList = false; 199 } 182 if (!grantAccess(request)) 183 return; 184 185 m_grantedRequests.append(WTFMove(request)); 186 if (m_hasFilteredDeviceList) 187 captureDevicesChanged(); 188 m_hasFilteredDeviceList = false; 200 189 }); 201 190 #else … … 267 256 } 268 257 269 bool UserMediaPermissionRequestManagerProxy::grantAccess( uint64_t userMediaID, const CaptureDevice audioDevice, const CaptureDevice videoDevice, const String& deviceIdentifierHashSalt)270 { 271 if (!UserMediaProcessManager::singleton().willCreateMediaStream(*this, !!audioDevice, !!videoDevice)) {272 denyRequest( userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::OtherFailure, "Unable to extend sandbox.");258 bool UserMediaPermissionRequestManagerProxy::grantAccess(const UserMediaPermissionRequestProxy& request) 259 { 260 if (!UserMediaProcessManager::singleton().willCreateMediaStream(*this, request.hasAudioDevice(), request.hasVideoDevice())) { 261 denyRequest(request.userMediaID(), UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::OtherFailure, "Unable to extend sandbox."); 273 262 return false; 274 263 } 275 264 276 m_page.process().send(Messages::WebPage::UserMediaAccessWasGranted( userMediaID, audioDevice, videoDevice, deviceIdentifierHashSalt), m_page.pageID());265 m_page.process().send(Messages::WebPage::UserMediaAccessWasGranted(request.userMediaID(), request.audioDevice(), request.videoDevice(), request.deviceIdentifierHashSalt()), m_page.pageID()); 277 266 return true; 278 267 } … … 297 286 298 287 #if ENABLE(MEDIA_STREAM) 299 UserMediaPermissionRequestManagerProxy::RequestAction UserMediaPermissionRequestManagerProxy::getRequestAction(uint64_t frameID, SecurityOrigin& userMediaDocumentOrigin, SecurityOrigin& topLevelDocumentOrigin, const MediaStreamRequest& userRequest, Vector<CaptureDevice>& audioDevices, Vector<CaptureDevice>& videoDevices) 300 { 301 bool requestingScreenCapture = userRequest.type == MediaStreamRequest::Type::DisplayMedia; 302 ASSERT(!(requestingScreenCapture && videoDevices.isEmpty())); 303 ASSERT(!(requestingScreenCapture && !audioDevices.isEmpty())); 304 bool requestingCamera = !requestingScreenCapture && !videoDevices.isEmpty(); 305 bool requestingMicrophone = !audioDevices.isEmpty(); 306 307 if (wasRequestDenied(frameID, userMediaDocumentOrigin, topLevelDocumentOrigin, requestingMicrophone, requestingCamera, requestingScreenCapture)) 288 UserMediaPermissionRequestManagerProxy::RequestAction UserMediaPermissionRequestManagerProxy::getRequestAction(const UserMediaPermissionRequestProxy& request) 289 { 290 bool requestingScreenCapture = request.requestType() == MediaStreamRequest::Type::DisplayMedia; 291 bool requestingCamera = !requestingScreenCapture && request.hasVideoDevice(); 292 bool requestingMicrophone = request.hasAudioDevice(); 293 294 ASSERT(!(requestingScreenCapture && !request.hasVideoDevice())); 295 ASSERT(!(requestingScreenCapture && requestingMicrophone)); 296 297 if (wasRequestDenied(request.frameID(), request.userMediaDocumentSecurityOrigin(), request.topLevelDocumentSecurityOrigin(), requestingMicrophone, requestingCamera, requestingScreenCapture)) 308 298 return RequestAction::Deny; 309 299 310 if ( userRequest.type== MediaStreamRequest::Type::DisplayMedia)300 if (request.requestType() == MediaStreamRequest::Type::DisplayMedia) 311 301 return RequestAction::Prompt; 312 302 313 return searchForGrantedRequest( frameID, userMediaDocumentOrigin, topLevelDocumentOrigin, requestingMicrophone, requestingCamera) ? RequestAction::Grant : RequestAction::Prompt;314 } 315 #endif 316 317 void UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, Ref<SecurityOrigin>&& userMediaDocumentOrigin, Ref<SecurityOrigin>&& topLevelDocumentOrigin, const MediaStreamRequest& userRequest)303 return searchForGrantedRequest(request.frameID(), request.userMediaDocumentSecurityOrigin(), request.topLevelDocumentSecurityOrigin(), requestingMicrophone, requestingCamera) ? RequestAction::Grant : RequestAction::Prompt; 304 } 305 #endif 306 307 void UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, Ref<SecurityOrigin>&& userMediaDocumentOrigin, Ref<SecurityOrigin>&& topLevelDocumentOrigin, MediaStreamRequest&& userRequest) 318 308 { 319 309 #if ENABLE(MEDIA_STREAM) … … 324 314 } 325 315 326 RealtimeMediaSourceCenter::InvalidConstraintsHandler invalidHandler = [this, userMediaID](const String& invalidConstraint) {327 if (!m_page.isValid())328 return; 329 330 denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::InvalidConstraint, invalidConstraint); 331 };332 333 auto validHandler = [this, userMediaID, frameID, userMediaDocumentOrigin = userMediaDocumentOrigin.copyRef(), topLevelDocumentOrigin = topLevelDocumentOrigin.copyRef(), localUserRequest = userRequest](Vector<CaptureDevice>&& audioDevices, Vector<CaptureDevice>&& videoDevices, String&& deviceIdentifierHashSalt) mutable {334 if (! m_page.isValid() || !m_page.mainFrame())335 return; 336 337 if ( videoDevices.isEmpty() && audioDevices.isEmpty()) {338 denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints, emptyString());316 if (!m_page.isValid()) 317 return; 318 319 auto request = m_pendingUserMediaRequests.add(userMediaID, UserMediaPermissionRequestProxy::create(*this, userMediaID, m_page.mainFrame()->frameID(), frameID, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin), { }, { }, WTFMove(userRequest))).iterator->value.copyRef(); 320 321 auto& userMediaOrigin = request->userMediaDocumentSecurityOrigin(); 322 auto& topLevelOrigin = request->topLevelDocumentSecurityOrigin(); 323 getUserMediaPermissionInfo(frameID, userMediaOrigin, topLevelOrigin, [this, request = request.releaseNonNull()](Optional<bool> hasPersistentAccess) mutable { 324 if (!request->isPending()) 325 return; 326 327 if (!hasPersistentAccess) { 328 request->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::OtherFailure); 339 329 return; 340 330 } 341 331 342 auto action = getRequestAction(m_page.mainFrame()->frameID(), userMediaDocumentOrigin.get(), topLevelDocumentOrigin.get(), localUserRequest, audioDevices, videoDevices); 343 if (action == RequestAction::Deny) { 344 denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied, emptyString()); 345 return; 346 } 347 348 if (action == RequestAction::Grant) { 349 ASSERT(localUserRequest.type != MediaStreamRequest::Type::DisplayMedia); 350 351 if (m_page.isViewVisible()) { 352 // We select the first available devices, but the current client API allows client to select which device to pick. 353 // FIXME: Remove the possiblity for the client to do the device selection. 354 auto audioDevice = !audioDevices.isEmpty() ? audioDevices[0] : CaptureDevice(); 355 auto videoDevice = !videoDevices.isEmpty() ? videoDevices[0] : CaptureDevice(); 356 grantAccess(userMediaID, WTFMove(audioDevice), WTFMove(videoDevice), WTFMove(deviceIdentifierHashSalt)); 357 } else 358 m_pregrantedRequests.append(createPermissionRequest(userMediaID, m_page.mainFrame()->frameID(), frameID, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin), WTFMove(audioDevices), WTFMove(videoDevices), WTFMove(localUserRequest))); 359 360 return; 361 } 362 363 auto userMediaOrigin = API::SecurityOrigin::create(userMediaDocumentOrigin.get()); 364 auto topLevelOrigin = API::SecurityOrigin::create(topLevelDocumentOrigin.get()); 365 auto pendingRequest = createPermissionRequest(userMediaID, m_page.mainFrame()->frameID(), frameID, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin), WTFMove(audioDevices), WTFMove(videoDevices), WTFMove(localUserRequest)); 366 367 if (m_page.isControlledByAutomation()) { 368 if (WebAutomationSession* automationSession = m_page.process().processPool().automationSession()) { 369 if (automationSession->shouldAllowGetUserMediaForPage(m_page)) 370 pendingRequest->allow(); 371 else 372 userMediaAccessWasDenied(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied); 373 332 processUserMediaPermissionRequest(WTFMove(request), *hasPersistentAccess); 333 }); 334 } 335 336 void UserMediaPermissionRequestManagerProxy::processUserMediaPermissionRequest(Ref<UserMediaPermissionRequestProxy>&& request, bool hasPersistentAccess) 337 { 338 if (hasPersistentAccess) 339 request->setHasPersistentAccess(); 340 341 auto& userMediaDocumentSecurityOrigin = request->userMediaDocumentSecurityOrigin(); 342 auto& topLevelDocumentSecurityOrigin = request->topLevelDocumentSecurityOrigin(); 343 m_page.websiteDataStore().deviceIdHashSaltStorage().deviceIdHashSaltForOrigin(userMediaDocumentSecurityOrigin, topLevelDocumentSecurityOrigin, [this, request = WTFMove(request)] (String&& deviceIDHashSalt) mutable { 344 if (!request->isPending()) 345 return; 346 347 RealtimeMediaSourceCenter::InvalidConstraintsHandler invalidHandler = [this, request = request.copyRef()](const String& invalidConstraint) { 348 if (!request->isPending()) 374 349 return; 375 } 376 } 377 378 if (m_page.preferences().mockCaptureDevicesEnabled() && !m_page.preferences().mockCaptureDevicesPromptEnabled()) { 379 pendingRequest->allow(); 380 return; 381 } 382 383 // If page navigated, there is no need to call the page client for authorization. 384 auto* webFrame = m_page.process().webFrame(frameID); 385 386 if (!webFrame || !SecurityOrigin::createFromString(m_page.pageLoadState().activeURL())->isSameSchemeHostPort(topLevelOrigin->securityOrigin())) { 387 denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints, emptyString()); 388 return; 389 } 390 391 // FIXME: Remove webFrame, userMediaOrigin and topLevelOrigin from this uiClient API call. 392 m_page.uiClient().decidePolicyForUserMediaPermissionRequest(m_page, *webFrame, WTFMove(userMediaOrigin), WTFMove(topLevelOrigin), pendingRequest.get()); 393 }; 394 395 auto requestID = generateRequestID(); 396 auto havePermissionInfoHandler = [this, weakThis = makeWeakPtr(*this), requestID, validHandler = WTFMove(validHandler), invalidHandler = WTFMove(invalidHandler), localUserRequest = userRequest](bool originHasPersistentAccess) mutable { 397 if (!weakThis) 398 return; 399 400 auto pendingRequest = m_pendingDeviceRequests.take(requestID); 401 if (!pendingRequest) 402 return; 403 404 if (!m_page.isValid()) 405 return; 350 351 if (!m_page.isValid()) 352 return; 353 354 processUserMediaPermissionInvalidRequest(request.get(), invalidConstraint); 355 }; 356 357 auto validHandler = [this, request = request.copyRef()](Vector<CaptureDevice>&& audioDevices, Vector<CaptureDevice>&& videoDevices, String&& deviceIdentifierHashSalt) mutable { 358 if (!request->isPending()) 359 return; 360 361 if (!m_page.isValid() || !m_page.mainFrame()) 362 return; 363 364 processUserMediaPermissionValidRequest(WTFMove(request), WTFMove(audioDevices), WTFMove(videoDevices), WTFMove(deviceIdentifierHashSalt)); 365 }; 406 366 407 367 syncWithWebCorePrefs(); 408 368 409 m_page.websiteDataStore().deviceIdHashSaltStorage().deviceIdHashSaltForOrigin(pendingRequest.value()->userMediaDocumentSecurityOrigin(), pendingRequest.value()->topLevelDocumentSecurityOrigin(), [validHandler = WTFMove(validHandler), invalidHandler = WTFMove(invalidHandler), localUserRequest = localUserRequest] (String&& deviceIDHashSalt) mutable { 410 RealtimeMediaSourceCenter::singleton().validateRequestConstraints(WTFMove(validHandler), WTFMove(invalidHandler), WTFMove(localUserRequest), WTFMove(deviceIDHashSalt)); 411 }); 412 }; 413 414 getUserMediaPermissionInfo(requestID, frameID, WTFMove(havePermissionInfoHandler), WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin)); 369 RealtimeMediaSourceCenter::singleton().validateRequestConstraints(WTFMove(validHandler), WTFMove(invalidHandler), request->userRequest(), WTFMove(deviceIDHashSalt)); 370 }); 415 371 #else 416 372 UNUSED_PARAM(userMediaID); … … 423 379 424 380 #if ENABLE(MEDIA_STREAM) 425 void UserMediaPermissionRequestManagerProxy::getUserMediaPermissionInfo(uint64_t requestID, uint64_t frameID, UserMediaPermissionCheckProxy::CompletionHandler&& handler, Ref<SecurityOrigin>&& userMediaDocumentOrigin, Ref<SecurityOrigin>&& topLevelDocumentOrigin) 381 void UserMediaPermissionRequestManagerProxy::processUserMediaPermissionInvalidRequest(const UserMediaPermissionRequestProxy& request, const String& invalidConstraint) 382 { 383 bool filterConstraint = !request.hasPersistentAccess() && !wasGrantedVideoOrAudioAccess(request.frameID(), request.userMediaDocumentSecurityOrigin(), request.topLevelDocumentSecurityOrigin()); 384 385 denyRequest(request.userMediaID(), UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::InvalidConstraint, filterConstraint ? String { } : invalidConstraint); 386 } 387 388 void UserMediaPermissionRequestManagerProxy::processUserMediaPermissionValidRequest(Ref<UserMediaPermissionRequestProxy>&& request, Vector<CaptureDevice>&& audioDevices, Vector<CaptureDevice>&& videoDevices, String&& deviceIdentifierHashSalt) 389 { 390 if (videoDevices.isEmpty() && audioDevices.isEmpty()) { 391 denyRequest(request->userMediaID(), UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints, emptyString()); 392 return; 393 } 394 395 request->setDeviceIdentifierHashSalt(WTFMove(deviceIdentifierHashSalt)); 396 request->setEligibleVideoDeviceUIDs(WTFMove(videoDevices)); 397 request->setEligibleAudioDeviceUIDs(WTFMove(audioDevices)); 398 399 auto action = getRequestAction(request); 400 if (action == RequestAction::Deny) { 401 denyRequest(request->userMediaID(), UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied, emptyString()); 402 return; 403 } 404 405 if (action == RequestAction::Grant) { 406 ASSERT(request->requestType() != MediaStreamRequest::Type::DisplayMedia); 407 408 if (m_page.isViewVisible()) 409 grantAccess(request); 410 else 411 m_pregrantedRequests.append(WTFMove(request)); 412 413 return; 414 } 415 416 if (m_page.isControlledByAutomation()) { 417 if (WebAutomationSession* automationSession = m_page.process().processPool().automationSession()) { 418 if (automationSession->shouldAllowGetUserMediaForPage(m_page)) 419 request->allow(); 420 else 421 userMediaAccessWasDenied(request->userMediaID(), UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied); 422 423 return; 424 } 425 } 426 427 if (m_page.preferences().mockCaptureDevicesEnabled() && !m_page.preferences().mockCaptureDevicesPromptEnabled()) { 428 request->allow(); 429 return; 430 } 431 432 // If page navigated, there is no need to call the page client for authorization. 433 auto* webFrame = m_page.process().webFrame(request->frameID()); 434 435 if (!webFrame || !SecurityOrigin::createFromString(m_page.pageLoadState().activeURL())->isSameSchemeHostPort(request->topLevelDocumentSecurityOrigin())) { 436 denyRequest(request->userMediaID(), UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints, emptyString()); 437 return; 438 } 439 440 // FIXME: Remove webFrame, userMediaOrigin and topLevelOrigin from this uiClient API call. 441 auto userMediaOrigin = API::SecurityOrigin::create(request->userMediaDocumentSecurityOrigin()); 442 auto topLevelOrigin = API::SecurityOrigin::create(request->topLevelDocumentSecurityOrigin()); 443 m_page.uiClient().decidePolicyForUserMediaPermissionRequest(m_page, *webFrame, WTFMove(userMediaOrigin), WTFMove(topLevelOrigin), request); 444 } 445 446 void UserMediaPermissionRequestManagerProxy::getUserMediaPermissionInfo(uint64_t frameID, Ref<SecurityOrigin>&& userMediaDocumentOrigin, Ref<SecurityOrigin>&& topLevelDocumentOrigin, CompletionHandler<void(Optional<bool>)>&& handler) 426 447 { 427 448 auto* webFrame = m_page.process().webFrame(frameID); 428 449 if (!webFrame || !SecurityOrigin::createFromString(m_page.pageLoadState().activeURL())->isSameSchemeHostPort(topLevelDocumentOrigin.get())) { 429 handler( false);450 handler({ }); 430 451 return; 431 452 } … … 433 454 auto userMediaOrigin = API::SecurityOrigin::create(userMediaDocumentOrigin.get()); 434 455 auto topLevelOrigin = API::SecurityOrigin::create(topLevelDocumentOrigin.get()); 435 auto request = UserMediaPermissionCheckProxy::create(frameID, WTFMove(handler), WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin)); 436 437 m_pendingDeviceRequests.add(requestID, request.copyRef()); 456 457 auto requestID = generateRequestID(); 458 m_pendingDeviceRequests.add(requestID); 459 460 auto request = UserMediaPermissionCheckProxy::create(frameID, [this, weakThis = makeWeakPtr(*this), requestID, handler = WTFMove(handler)](Optional<bool> allowed) mutable { 461 if (!weakThis || !m_pendingDeviceRequests.remove(requestID) || !allowed) { 462 handler({ }); 463 return; 464 } 465 handler(*allowed); 466 }, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin)); 467 438 468 // FIXME: Remove webFrame, userMediaOrigin and topLevelOrigin from this uiClient API call. 439 469 m_page.uiClient().checkUserMediaPermissionForOrigin(m_page, *webFrame, userMediaOrigin.get(), topLevelOrigin.get(), request.get()); … … 458 488 return false; 459 489 } 460 #endif 461 462 void UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, Ref<SecurityOrigin>&& userMediaDocumentOrigin, Ref<SecurityOrigin>&& topLevelDocumentOrigin) 463 { 464 #if ENABLE(MEDIA_STREAM) 465 490 491 Vector<CaptureDevice> UserMediaPermissionRequestManagerProxy::computeFilteredDeviceList(bool revealIdsAndLabels, const String& deviceIDHashSalt) 492 { 466 493 #if PLATFORM(IOS_FAMILY) 467 494 static const int defaultMaximumCameraCount = 2; … … 471 498 static const int defaultMaximumMicrophoneCount = 1; 472 499 473 auto requestID = generateRequestID(); 474 auto completionHandler = [this, weakThis = makeWeakPtr(*this), requestID, userMediaID, requestOrigin = userMediaDocumentOrigin.copyRef(), topOrigin = topLevelDocumentOrigin.copyRef()](bool originHasPersistentAccess) mutable { 475 if (!weakThis) 500 auto devices = RealtimeMediaSourceCenter::singleton().getMediaStreamDevices(); 501 int cameraCount = 0; 502 int microphoneCount = 0; 503 504 Vector<CaptureDevice> filteredDevices; 505 for (const auto& device : devices) { 506 if (!device.enabled() || (device.type() != WebCore::CaptureDevice::DeviceType::Camera && device.type() != WebCore::CaptureDevice::DeviceType::Microphone)) 507 continue; 508 509 if (!revealIdsAndLabels) { 510 if (device.type() == WebCore::CaptureDevice::DeviceType::Camera && ++cameraCount > defaultMaximumCameraCount) 511 continue; 512 if (device.type() == WebCore::CaptureDevice::DeviceType::Microphone && ++microphoneCount > defaultMaximumMicrophoneCount) 513 continue; 514 } 515 516 auto label = emptyString(); 517 auto id = emptyString(); 518 auto groupId = emptyString(); 519 if (revealIdsAndLabels) { 520 label = device.label(); 521 id = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(device.persistentId(), deviceIDHashSalt); 522 groupId = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(device.groupId(), deviceIDHashSalt); 523 } 524 525 filteredDevices.append(CaptureDevice(id, device.type(), label, groupId)); 526 } 527 528 m_hasFilteredDeviceList = !revealIdsAndLabels; 529 return filteredDevices; 530 } 531 #endif 532 533 void UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, Ref<SecurityOrigin>&& userMediaDocumentOrigin, Ref<SecurityOrigin>&& topLevelDocumentOrigin) 534 { 535 #if ENABLE(MEDIA_STREAM) 536 auto completionHandler = [this, userMediaID, frameID, userMediaDocumentOrigin = userMediaDocumentOrigin.copyRef(), topLevelDocumentOrigin = topLevelDocumentOrigin.copyRef()](Optional<bool> originHasPersistentAccess) mutable { 537 if (!originHasPersistentAccess) 476 538 return; 477 539 … … 479 541 return; 480 542 481 m_page.websiteDataStore().deviceIdHashSaltStorage().deviceIdHashSaltForOrigin(requestOrigin.get(), topOrigin.get(), [this, weakThis = WTFMove(weakThis), requestID, userMediaID, &originHasPersistentAccess] (String&& deviceIDHashSalt) { 482 if (!weakThis) 483 return; 484 auto pendingRequest = m_pendingDeviceRequests.take(requestID); 485 if (!pendingRequest) 543 auto requestID = generateRequestID(); 544 m_pendingDeviceRequests.add(requestID); 545 546 auto& requestOrigin = userMediaDocumentOrigin.get(); 547 auto& topOrigin = topLevelDocumentOrigin.get(); 548 m_page.websiteDataStore().deviceIdHashSaltStorage().deviceIdHashSaltForOrigin(requestOrigin, topOrigin, [this, weakThis = makeWeakPtr(*this), requestID, frameID, userMediaID, userMediaDocumentOrigin = WTFMove(userMediaDocumentOrigin), topLevelDocumentOrigin = WTFMove(topLevelDocumentOrigin), originHasPersistentAccess = *originHasPersistentAccess] (String&& deviceIDHashSalt) { 549 if (!weakThis || !m_pendingDeviceRequests.remove(requestID)) 486 550 return; 487 551 … … 491 555 syncWithWebCorePrefs(); 492 556 493 auto devices = RealtimeMediaSourceCenter::singleton().getMediaStreamDevices(); 494 auto& request = *pendingRequest; 495 bool revealIdsAndLabels = originHasPersistentAccess || wasGrantedVideoOrAudioAccess(request->frameID(), request->userMediaDocumentSecurityOrigin(), request->topLevelDocumentSecurityOrigin()); 496 int cameraCount = 0; 497 int microphoneCount = 0; 498 499 Vector<CaptureDevice> filteredDevices; 500 for (const auto& device : devices) { 501 if (!device.enabled() || (device.type() != WebCore::CaptureDevice::DeviceType::Camera && device.type() != WebCore::CaptureDevice::DeviceType::Microphone)) 502 continue; 503 504 if (!revealIdsAndLabels) { 505 if (device.type() == WebCore::CaptureDevice::DeviceType::Camera && ++cameraCount > defaultMaximumCameraCount) 506 continue; 507 if (device.type() == WebCore::CaptureDevice::DeviceType::Microphone && ++microphoneCount > defaultMaximumMicrophoneCount) 508 continue; 509 } 510 511 auto label = emptyString(); 512 auto id = emptyString(); 513 auto groupId = emptyString(); 514 if (revealIdsAndLabels) { 515 label = device.label(); 516 id = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(device.persistentId(), deviceIDHashSalt); 517 groupId = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(device.groupId(), deviceIDHashSalt); 518 } 519 520 filteredDevices.append(CaptureDevice(id, device.type(), label, groupId)); 521 } 522 523 m_hasFilteredDeviceList = !revealIdsAndLabels; 524 525 m_page.process().send(Messages::WebPage::DidCompleteMediaDeviceEnumeration(userMediaID, WTFMove(filteredDevices), WTFMove(deviceIDHashSalt), originHasPersistentAccess), m_page.pageID()); 557 bool revealIdsAndLabels = originHasPersistentAccess || wasGrantedVideoOrAudioAccess(frameID, userMediaDocumentOrigin.get(), topLevelDocumentOrigin.get()); 558 559 m_page.process().send(Messages::WebPage::DidCompleteMediaDeviceEnumeration { userMediaID, computeFilteredDeviceList(revealIdsAndLabels, deviceIDHashSalt), deviceIDHashSalt, originHasPersistentAccess }, m_page.pageID()); 526 560 }); 527 561 }; 528 562 529 getUserMediaPermissionInfo( requestID, frameID, WTFMove(completionHandler), WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin));563 getUserMediaPermissionInfo(frameID, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin), WTFMove(completionHandler)); 530 564 #else 531 565 UNUSED_PARAM(userMediaID); -
trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h
r241252 r241270 24 24 #include <WebCore/MediaProducer.h> 25 25 #include <WebCore/SecurityOrigin.h> 26 #include <wtf/CompletionHandler.h> 26 27 #include <wtf/HashMap.h> 27 28 #include <wtf/RunLoop.h> … … 49 50 void invalidatePendingRequests(); 50 51 51 void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, const WebCore::MediaStreamRequest&);52 void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, WebCore::MediaStreamRequest&&); 52 53 53 54 void resetAccess(uint64_t mainFrameID); … … 72 73 void denyRequest(uint64_t userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason, const String& invalidConstraint); 73 74 #if ENABLE(MEDIA_STREAM) 74 bool grantAccess( uint64_t userMediaID, const WebCore::CaptureDevice audioDevice, const WebCore::CaptureDevice videoDevice, const String& deviceIdentifierHashSalt);75 bool grantAccess(const UserMediaPermissionRequestProxy&); 75 76 76 77 const UserMediaPermissionRequestProxy* searchForGrantedRequest(uint64_t frameID, const WebCore::SecurityOrigin& userMediaDocumentOrigin, const WebCore::SecurityOrigin& topLevelDocumentOrigin, bool needsAudio, bool needsVideo) const; 77 78 bool wasRequestDenied(uint64_t mainFrameID, const WebCore::SecurityOrigin& userMediaDocumentOrigin, const WebCore::SecurityOrigin& topLevelDocumentOrigin, bool needsAudio, bool needsVideo, bool needsScreenCapture); 78 79 79 void getUserMediaPermissionInfo(uint64_t requestID, uint64_t frameID, UserMediaPermissionCheckProxy::CompletionHandler&&, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin);80 void getUserMediaPermissionInfo(uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, CompletionHandler<void(Optional<bool>)>&&); 80 81 81 82 enum class RequestAction { … … 84 85 Prompt 85 86 }; 86 RequestAction getRequestAction( uint64_t frameID, WebCore::SecurityOrigin& userMediaDocumentOrigin, WebCore::SecurityOrigin& topLevelDocumentOrigin, const WebCore::MediaStreamRequest&, Vector<WebCore::CaptureDevice>& audioDevices, Vector<WebCore::CaptureDevice>& videoDevices);87 RequestAction getRequestAction(const UserMediaPermissionRequestProxy&); 87 88 88 89 bool wasGrantedVideoOrAudioAccess(uint64_t, const WebCore::SecurityOrigin& userMediaDocumentOrigin, const WebCore::SecurityOrigin& topLevelDocumentOrigin); 90 91 Vector<WebCore::CaptureDevice> computeFilteredDeviceList(bool revealIdsAndLabels, const String& deviceIDHashSalt); 92 93 void processUserMediaPermissionRequest(Ref<UserMediaPermissionRequestProxy>&&, bool hasPersistentAccess); 94 void processUserMediaPermissionInvalidRequest(const UserMediaPermissionRequestProxy&, const String& invalidConstraint); 95 void processUserMediaPermissionValidRequest(Ref<UserMediaPermissionRequestProxy>&&, Vector<WebCore::CaptureDevice>&& audioDevices, Vector<WebCore::CaptureDevice>&& videoDevices, String&& deviceIdentifierHashSalt); 89 96 #endif 90 97 … … 92 99 93 100 HashMap<uint64_t, RefPtr<UserMediaPermissionRequestProxy>> m_pendingUserMediaRequests; 94 Hash Map<uint64_t, Ref<UserMediaPermissionCheckProxy>> m_pendingDeviceRequests;101 HashSet<uint64_t> m_pendingDeviceRequests; 95 102 96 103 WebPageProxy& m_page; -
trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestProxy.h
r241252 r241270 49 49 50 50 void invalidate(); 51 bool isPending() const { return m_manager; } 51 52 52 53 bool requiresAudioCapture() const { return m_eligibleAudioDevices.size(); } … … 54 55 bool requiresDisplayCapture() const { return m_request.type == WebCore::MediaStreamRequest::Type::DisplayMedia && m_eligibleVideoDevices.size(); } 55 56 57 void setEligibleVideoDeviceUIDs(Vector<WebCore::CaptureDevice>&& devices) { m_eligibleVideoDevices = WTFMove(devices); } 58 void setEligibleAudioDeviceUIDs(Vector<WebCore::CaptureDevice>&& devices) { m_eligibleAudioDevices = WTFMove(devices); } 59 56 60 Vector<String> videoDeviceUIDs() const; 57 61 Vector<String> audioDeviceUIDs() const; 62 bool hasAudioDevice() const { return !m_eligibleAudioDevices.isEmpty(); } 63 bool hasVideoDevice() const { return !m_eligibleVideoDevices.isEmpty(); } 58 64 65 bool hasPersistentAccess() const { return m_hasPersistentAccess; } 66 void setHasPersistentAccess() { m_hasPersistentAccess = true; } 67 68 uint64_t userMediaID() const { return m_userMediaID; } 59 69 uint64_t mainFrameID() const { return m_mainFrameID; } 60 70 uint64_t frameID() const { return m_frameID; } 71 61 72 WebCore::SecurityOrigin& topLevelDocumentSecurityOrigin() { return m_topLevelDocumentSecurityOrigin.get(); } 62 73 WebCore::SecurityOrigin& userMediaDocumentSecurityOrigin() { return m_userMediaDocumentSecurityOrigin.get(); } 74 const WebCore::SecurityOrigin& topLevelDocumentSecurityOrigin() const { return m_topLevelDocumentSecurityOrigin.get(); } 75 const WebCore::SecurityOrigin& userMediaDocumentSecurityOrigin() const { return m_userMediaDocumentSecurityOrigin.get(); } 76 77 const WebCore::MediaStreamRequest& userRequest() const { return m_request; } 63 78 64 79 WebCore::MediaStreamRequest::Type requestType() const { return m_request.type; } 80 81 void setDeviceIdentifierHashSalt(String&& salt) { m_deviceIdentifierHashSalt = WTFMove(salt); } 82 const String& deviceIdentifierHashSalt() const { return m_deviceIdentifierHashSalt; } 83 84 WebCore::CaptureDevice audioDevice() const { return m_eligibleAudioDevices.isEmpty() ? WebCore::CaptureDevice { } : m_eligibleAudioDevices[0]; } 85 WebCore::CaptureDevice videoDevice() const { return m_eligibleVideoDevices.isEmpty() ? WebCore::CaptureDevice { } : m_eligibleVideoDevices[0]; } 65 86 66 87 private: … … 76 97 Vector<WebCore::CaptureDevice> m_eligibleAudioDevices; 77 98 WebCore::MediaStreamRequest m_request; 99 bool m_hasPersistentAccess { false }; 100 String m_deviceIdentifierHashSalt; 78 101 }; 79 102 -
trunk/Source/WebKit/UIProcess/WebPageProxy.cpp
r241260 r241270 7023 7023 #endif 7024 7024 7025 void WebPageProxy::requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, const WebCore::SecurityOriginData& userMediaDocumentOriginData, const WebCore::SecurityOriginData& topLevelDocumentOriginData, const WebCore::MediaStreamRequest& request)7025 void WebPageProxy::requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, const WebCore::SecurityOriginData& userMediaDocumentOriginData, const WebCore::SecurityOriginData& topLevelDocumentOriginData, WebCore::MediaStreamRequest&& request) 7026 7026 { 7027 7027 #if ENABLE(MEDIA_STREAM) 7028 7028 MESSAGE_CHECK(m_process, m_process->webFrame(frameID)); 7029 7029 7030 userMediaPermissionRequestManager().requestUserMediaPermissionForFrame(userMediaID, frameID, userMediaDocumentOriginData.securityOrigin(), topLevelDocumentOriginData.securityOrigin(), request);7030 userMediaPermissionRequestManager().requestUserMediaPermissionForFrame(userMediaID, frameID, userMediaDocumentOriginData.securityOrigin(), topLevelDocumentOriginData.securityOrigin(), WTFMove(request)); 7031 7031 #else 7032 7032 UNUSED_PARAM(userMediaID); -
trunk/Source/WebKit/UIProcess/WebPageProxy.h
r241252 r241270 1604 1604 UserMediaPermissionRequestManagerProxy& userMediaPermissionRequestManager(); 1605 1605 #endif 1606 void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, const WebCore::SecurityOriginData& userMediaDocumentOriginIdentifier, const WebCore::SecurityOriginData& topLevelDocumentOriginIdentifier, const WebCore::MediaStreamRequest&);1606 void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, const WebCore::SecurityOriginData& userMediaDocumentOriginIdentifier, const WebCore::SecurityOriginData& topLevelDocumentOriginIdentifier, WebCore::MediaStreamRequest&&); 1607 1607 void enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, const WebCore::SecurityOriginData& userMediaDocumentOriginData, const WebCore::SecurityOriginData& topLevelDocumentOriginData); 1608 1608 void beginMonitoringCaptureDevices();
Note: See TracChangeset
for help on using the changeset viewer.