From b9d2a049bac931d3841b04f59b79837741f150a5 Mon Sep 17 00:00:00 2001 From: Jan Cabadaj Date: Mon, 16 Dec 2024 20:00:31 +0100 Subject: [PATCH] (iOS) Avoid repetitive permission prompts --- .../CDVWebViewEngine/CDVWebViewEngine.m | 24 +++++++++++++++++ .../CDVWebViewEngine/CDVWebViewUIDelegate.h | 9 +++++++ .../CDVWebViewEngine/CDVWebViewUIDelegate.m | 26 +++++++++++++++++++ templates/cordova/defaults.xml | 1 + 4 files changed, 60 insertions(+) diff --git a/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewEngine.m b/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewEngine.m index 88f2d9a9dc..45ad8ff8c9 100644 --- a/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewEngine.m +++ b/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewEngine.m @@ -189,6 +189,7 @@ - (void)pluginInitialize CDVWebViewUIDelegate* uiDelegate = [[CDVWebViewUIDelegate alloc] initWithViewController:self.viewController]; uiDelegate.title = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; + uiDelegate.mediaPermissionGrantType = [self parsePermissionGrantType:[settings cordovaSettingForKey:@"MediaPermissionGrantType"]]; uiDelegate.allowNewWindows = [settings cordovaBoolSettingForKey:@"AllowNewWindows" defaultValue:NO]; self.uiDelegate = uiDelegate; @@ -453,6 +454,29 @@ - (UIView*)webView return self.engineWebView; } +- (CDVWebViewPermissionGrantType)parsePermissionGrantType:(NSString*)optionString +{ + CDVWebViewPermissionGrantType result = CDVWebViewPermissionGrantType_GrantIfSameHost_ElsePrompt; + + if (optionString != nil){ + if ([optionString isEqualToString:@"prompt"]) { + result = CDVWebViewPermissionGrantType_Prompt; + } else if ([optionString isEqualToString:@"deny"]) { + result = CDVWebViewPermissionGrantType_Deny; + } else if ([optionString isEqualToString:@"grant"]) { + result = CDVWebViewPermissionGrantType_Grant; + } else if ([optionString isEqualToString:@"grantIfSameHostElsePrompt"]) { + result = CDVWebViewPermissionGrantType_GrantIfSameHost_ElsePrompt; + } else if ([optionString isEqualToString:@"grantIfSameHostElseDeny"]) { + result = CDVWebViewPermissionGrantType_GrantIfSameHost_ElseDeny; + } else { + NSLog(@"Invalid \"MediaPermissionGrantType\" was detected. Fallback to default value of \"grantIfSameHostElsePrompt\""); + } + } + + return result; +} + #pragma mark WKScriptMessageHandler implementation - (void)userContentController:(WKUserContentController*)userContentController didReceiveScriptMessage:(WKScriptMessage*)message diff --git a/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewUIDelegate.h b/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewUIDelegate.h index 581eea0cd5..2e4ac894ee 100644 --- a/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewUIDelegate.h +++ b/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewUIDelegate.h @@ -32,8 +32,17 @@ NS_ASSUME_NONNULL_BEGIN CDV_SWIFT_UI_ACTOR @interface CDVWebViewUIDelegate : NSObject +typedef NS_ENUM(NSInteger, CDVWebViewPermissionGrantType) { + CDVWebViewPermissionGrantType_Prompt, + CDVWebViewPermissionGrantType_Deny, + CDVWebViewPermissionGrantType_Grant, + CDVWebViewPermissionGrantType_GrantIfSameHost_ElsePrompt, + CDVWebViewPermissionGrantType_GrantIfSameHost_ElseDeny +}; + @property (nonatomic, nullable, copy) NSString* title; @property (nonatomic, assign) BOOL allowNewWindows; +@property (nonatomic, assign) CDVWebViewPermissionGrantType mediaPermissionGrantType; - (instancetype)initWithViewController:(CDVViewController*)vc; diff --git a/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewUIDelegate.m b/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewUIDelegate.m index e06e54529b..b07d7aaeeb 100644 --- a/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewUIDelegate.m +++ b/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewUIDelegate.m @@ -159,6 +159,32 @@ - (void)webViewDidClose:(WKWebView*)webView // We do not allow closing the primary WebView } +- (void)webView:(WKWebView *)webView requestMediaCapturePermissionForOrigin:(nonnull WKSecurityOrigin *)origin initiatedByFrame:(nonnull WKFrameInfo *)frame type:(WKMediaCaptureType)type decisionHandler:(nonnull void (^)(WKPermissionDecision))decisionHandler + API_AVAILABLE(ios(15.0)) +{ + WKPermissionDecision decision; + + if (_mediaPermissionGrantType == CDVWebViewPermissionGrantType_Prompt) { + decision = WKPermissionDecisionPrompt; + } + else if (_mediaPermissionGrantType == CDVWebViewPermissionGrantType_Deny) { + decision = WKPermissionDecisionDeny; + } + else if (_mediaPermissionGrantType == CDVWebViewPermissionGrantType_Grant) { + decision = WKPermissionDecisionGrant; + } + else { + if ([origin.host isEqualToString:webView.URL.host]) { + decision = WKPermissionDecisionGrant; + } + else { + decision =_mediaPermissionGrantType == CDVWebViewPermissionGrantType_GrantIfSameHost_ElsePrompt ? WKPermissionDecisionPrompt : WKPermissionDecisionDeny; + } + } + + decisionHandler(decision); +} + #pragma mark - Utility Methods - (nullable UIViewController *)topViewController diff --git a/templates/cordova/defaults.xml b/templates/cordova/defaults.xml index 1a7287d221..e7f2776d51 100644 --- a/templates/cordova/defaults.xml +++ b/templates/cordova/defaults.xml @@ -25,6 +25,7 @@ +