blob: 9fe1fe18b2b9c31e6a973a10753238249f9abfeb [file] [log] [blame] [edit]
/*
* Copyright (C) 2021-2022 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "config.h"
#import "UserMediaCaptureUIDelegate.h"
#if ENABLE(MEDIA_STREAM)
#import "PlatformUtilities.h"
#import "Utilities.h"
#import <WebKit/WKMockMediaDevice.h>
#import <WebKit/WKString.h>
#import <WebKit/WKWebpagePreferencesPrivate.h>
@implementation UserMediaCaptureUIDelegate {
Vector<RetainPtr<WKWebView>> _createdWebViews;
}
@synthesize createWebViewWithConfiguration = _createWebViewWithConfiguration;
@synthesize numberOfPrompts = _numberOfPrompts;
@synthesize decision = _decision;
-(id)init {
self = [super init];
if (self != nil) {
_wasPrompted = false;
_numberOfPrompts = 0;
_audioDecision = WKPermissionDecisionGrant;
_videoDecision = WKPermissionDecisionGrant;
_getDisplayMediaDecision = WKDisplayCapturePermissionDecisionDeny;
}
return self;
}
-(BOOL)wasPrompted {
return _wasPrompted ? YES : NO;
}
-(void)resetWasPrompted {
_wasPrompted = false;
}
-(void)waitUntilPrompted {
TestWebKitAPI::Util::run(&_wasPrompted);
_wasPrompted = false;
}
-(void)setAudioDecision:(WKPermissionDecision)decision {
_audioDecision = decision;
}
-(void)setVideoDecision:(WKPermissionDecision)decision {
_videoDecision = decision;
}
-(void)setGetDisplayMediaDecision:(WKDisplayCapturePermissionDecision)decision {
_getDisplayMediaDecision = decision;
}
- (void)_webView:(WKWebView *)webView queryPermission:(NSString*) name forOrigin:(WKSecurityOrigin *)origin completionHandler:(void (^)(WKPermissionDecision state))completionHandler {
if ([name isEqualToString:@"camera"]) {
completionHandler(_videoDecision);
return;
}
if ([name isEqualToString:@"microphone"]) {
completionHandler(_audioDecision);
return;
}
ASSERT_NOT_REACHED();
completionHandler(WKPermissionDecisionDeny);
}
- (void)webView:(WKWebView *)webView requestMediaCapturePermissionForOrigin:(WKSecurityOrigin *)origin initiatedByFrame:(WKFrameInfo *)frame type:(WKMediaCaptureType)type decisionHandler:(void (^)(WKPermissionDecision decision))decisionHandler {
++_numberOfPrompts;
_wasPrompted = true;
switch (type) {
case WKMediaCaptureTypeCamera:
if (_videoDecision == WKPermissionDecisionDeny) {
decisionHandler(WKPermissionDecisionDeny);
return;
}
break;
case WKMediaCaptureTypeMicrophone:
if (_audioDecision == WKPermissionDecisionDeny) {
decisionHandler(WKPermissionDecisionDeny);
return;
}
break;
case WKMediaCaptureTypeCameraAndMicrophone:
if (_audioDecision == WKPermissionDecisionDeny || _videoDecision == WKPermissionDecisionDeny) {
decisionHandler(WKPermissionDecisionDeny);
return;
}
break;
}
decisionHandler(WKPermissionDecisionGrant);
}
- (void)_webView:(WKWebView *)webView checkUserMediaPermissionForURL:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL frameIdentifier:(NSUInteger)frameIdentifier decisionHandler:(void (^)(NSString *salt, BOOL authorized))decisionHandler {
decisionHandler(@"0x9876543210", YES);
}
- (void)_webView:(WKWebView *)webView requestDisplayCapturePermissionForOrigin:(WKSecurityOrigin *)origin initiatedByFrame:(WKFrameInfo *)frame withSystemAudio:(BOOL)withSystemAudio decisionHandler:(void (^)(WKDisplayCapturePermissionDecision decision))decisionHandler
{
++_numberOfPrompts;
_wasPrompted = true;
decisionHandler(_getDisplayMediaDecision);
}
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
{
if (_createWebViewWithConfiguration)
return _createWebViewWithConfiguration(configuration, navigationAction, windowFeatures);
_createdWebViews.append(adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]));
return _createdWebViews.last().get();
}
- (void)_webView:(WKWebView *)webView decidePolicyForScreenCaptureUnmutingForOrigin:(WKSecurityOrigin *)origin initiatedByFrame:(WKFrameInfo *)frame decisionHandler:(void (^)(BOOL authorized))decisionHandler
{
++_numberOfPrompts;
_wasPrompted = true;
decisionHandler(_getDisplayMediaDecision != WKDisplayCapturePermissionDecisionDeny);
}
#if PLATFORM(IOS_FAMILY)
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction preferences:(WKWebpagePreferences *)preferences decisionHandler:(void (^)(WKNavigationActionPolicy, WKWebpagePreferences *))decisionHandler
{
auto websitePolicies = adoptNS([[WKWebpagePreferences alloc] init]);
[websitePolicies _setPopUpPolicy:_WKWebsitePopUpPolicyAllow];
decisionHandler(WKNavigationActionPolicyAllow, websitePolicies.get());
}
#endif
@end
@implementation UserMediaCaptureUIDelegateWithDeviceChange {
}
-(id)init {
self = [super init];
return self;
}
- (void)webView:(WKWebView *)webView requestMediaCapturePermissionForOrigin:(WKSecurityOrigin *)origin initiatedByFrame:(WKFrameInfo *)frame type:(WKMediaCaptureType)type decisionHandler:(void (^)(WKPermissionDecision decision))decisionHandler {
WKResetMockMediaDevices((__bridge WKContextRef)webView.configuration.processPool);
decisionHandler(WKPermissionDecisionGrant);
}
-(void)addDefaultCamera:(WKWebViewConfiguration*)configuration {
auto persistentId = adoptWK(WKStringCreateWithUTF8CString("PERSISTENTCAMERAID1"));
auto label = adoptWK(WKStringCreateWithUTF8CString("NEWDEFAULTCAMERA"));
auto type = adoptWK(WKStringCreateWithUTF8CString("camera"));
WKAddMockMediaDevice((__bridge WKContextRef)configuration.processPool, persistentId.get(), label.get(), type.get(), nullptr, true);
}
-(void)addDefaultMicrophone:(WKWebViewConfiguration*)configuration {
auto persistentId = adoptWK(WKStringCreateWithUTF8CString("PERSISTENTMICROPHONEID1"));
auto label = adoptWK(WKStringCreateWithUTF8CString("NEWDEFAULTMICROPHONE"));
auto type = adoptWK(WKStringCreateWithUTF8CString("microphone"));
WKAddMockMediaDevice((__bridge WKContextRef)configuration.processPool, persistentId.get(), label.get(), type.get(), nullptr, true);
}
@end
#endif // ENABLE(MEDIA_STREAM)