Make Legacy EME API controlled by RuntimeEnabled setting.
[WebKit-https.git] / Source / WebKit2 / UIProcess / API / Cocoa / WKWebViewConfiguration.mm
index b7e5485..fbf4a66 100644 (file)
 #import "WKPreferences.h"
 #import "WKProcessPool.h"
 #import "WKUserContentController.h"
+#import "WKWebView.h"
 #import "WKWebViewContentProviderRegistry.h"
 #import "WeakObjCPtr.h"
-#import "_WKVisitedLinkProvider.h"
+#import "WebKit2Initialize.h"
+#import "_WKVisitedLinkStore.h"
 #import "_WKWebsiteDataStoreInternal.h"
 #import <WebCore/RuntimeApplicationChecks.h>
+#import <WebCore/Settings.h>
+#import <WebCore/URLParser.h>
 #import <wtf/RetainPtr.h>
 
 #if PLATFORM(IOS)
@@ -84,6 +88,19 @@ private:
     T m_value;
 };
 
+#if PLATFORM(IOS)
+
+static _WKDragLiftDelay toDragLiftDelay(NSUInteger value)
+{
+    if (value == _WKDragLiftDelayMedium)
+        return _WKDragLiftDelayMedium;
+    if (value == _WKDragLiftDelayLong)
+        return _WKDragLiftDelayLong;
+    return _WKDragLiftDelayShort;
+}
+
+#endif
+
 @implementation WKWebViewConfiguration {
     LazyInitialized<RetainPtr<WKProcessPool>> _processPool;
     LazyInitialized<RetainPtr<WKPreferences>> _preferences;
@@ -92,12 +109,13 @@ private:
     LazyInitialized<RetainPtr<WKWebsiteDataStore>> _websiteDataStore;
     WebKit::WeakObjCPtr<WKWebView> _relatedWebView;
     WebKit::WeakObjCPtr<WKWebView> _alternateWebViewForNavigationGestures;
-    BOOL _treatsSHA1SignedCertificatesAsInsecure;
     RetainPtr<NSString> _groupIdentifier;
     LazyInitialized<RetainPtr<NSString>> _applicationNameForUserAgent;
+    LazyInitialized<RetainPtr<NSMutableDictionary<NSString *, id <WKURLSchemeHandler>>>> _urlSchemeHandlers;
+    NSTimeInterval _incrementalRenderingSuppressionTimeout;
+    BOOL _treatsSHA1SignedCertificatesAsInsecure;
     BOOL _respectsImageOrientation;
     BOOL _printsBackgrounds;
-    CGFloat _incrementalRenderingSuppressionTimeout;
     BOOL _allowsJavaScriptMarkup;
     BOOL _convertsPositionStyleOnCopy;
     BOOL _allowsMetaRefresh;
@@ -107,9 +125,10 @@ private:
     LazyInitialized<RetainPtr<WKWebViewContentProviderRegistry>> _contentProviderRegistry;
     BOOL _alwaysRunsAtForegroundPriority;
     BOOL _allowsInlineMediaPlayback;
-    BOOL _allowsInlineMediaPlaybackWithPlaysInlineAttribute;
-    BOOL _allowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute;
+    BOOL _inlineMediaPlaybackRequiresPlaysInlineAttribute;
     BOOL _allowsInlineMediaPlaybackAfterFullscreen;
+    BOOL _allowsBlockSelection;
+    _WKDragLiftDelay _dragLiftDelay;
 #endif
 
     BOOL _invisibleAutoplayNotPermitted;
@@ -124,43 +143,47 @@ private:
     BOOL _requiresUserActionForEditingControlsManager;
 #endif
     BOOL _initialCapitalizationEnabled;
+    BOOL _waitsForPaintAfterViewDidMoveToWindow;
+    BOOL _controlledByAutomation;
 
 #if ENABLE(APPLE_PAY)
     BOOL _applePayEnabled;
 #endif
+    BOOL _needsStorageAccessFromFileURLsQuirk;
+    BOOL _legacyEncryptedMediaAPIEnabled;
+
+    RetainPtr<NSString> _overrideContentSecurityPolicy;
+    RetainPtr<NSString> _mediaContentTypesRequiringHardwareSupport;
 }
 
 - (instancetype)init
 {
     if (!(self = [super init]))
         return nil;
-    
+
+    WebKit::InitializeWebKit2();
+
 #if PLATFORM(IOS)
     _allowsPictureInPictureMediaPlayback = YES;
     _allowsInlineMediaPlayback = WebCore::deviceClass() == MGDeviceClassiPad;
-    _allowsInlineMediaPlaybackWithPlaysInlineAttribute = !_allowsInlineMediaPlayback;
-    _allowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute = !_allowsInlineMediaPlayback;
+    _inlineMediaPlaybackRequiresPlaysInlineAttribute = !_allowsInlineMediaPlayback;
     _allowsInlineMediaPlaybackAfterFullscreen = !_allowsInlineMediaPlayback;
     _mediaDataLoadsAutomatically = NO;
-    if (linkedOnOrAfter(WebKit::LibraryVersion::FirstWithMediaTypesRequiringUserActionForPlayback))
+    if (WebKit::linkedOnOrAfter(WebKit::SDKVersion::FirstWithMediaTypesRequiringUserActionForPlayback))
         _mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeAudio;
     else
         _mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeAll;
     _ignoresViewportScaleLimits = NO;
+    _legacyEncryptedMediaAPIEnabled = NO;
 #else
     _mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
     _mediaDataLoadsAutomatically = YES;
     _userInterfaceDirectionPolicy = WKUserInterfaceDirectionPolicyContent;
+    _legacyEncryptedMediaAPIEnabled = YES;
 #endif
     _mainContentUserGestureOverrideEnabled = NO;
     _invisibleAutoplayNotPermitted = NO;
-
-// FIXME: <rdar://problem/25135244> Should default to NO once clients have adopted the setting.
-#if PLATFORM(IOS)
-    _attachmentElementEnabled = IOSApplication::isMobileMail();
-#else
-    _attachmentElementEnabled = MacApplication::isAppleMail();
-#endif
+    _attachmentElementEnabled = NO;
 
 #if PLATFORM(IOS)
     _respectsImageOrientation = YES;
@@ -176,6 +199,7 @@ private:
     _requiresUserActionForEditingControlsManager = NO;
 #endif
     _initialCapitalizationEnabled = YES;
+    _waitsForPaintAfterViewDidMoveToWindow = YES;
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     _allowsAirPlayForMediaPlayback = YES;
@@ -187,6 +211,15 @@ private:
     _allowsMetaRefresh = YES;
     _allowUniversalAccessFromFileURLs = NO;
     _treatsSHA1SignedCertificatesAsInsecure = YES;
+    _needsStorageAccessFromFileURLsQuirk = YES;
+
+#if PLATFORM(IOS)
+    _selectionGranularity = WKSelectionGranularityDynamic;
+    _allowsBlockSelection = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitDebugAllowBlockSelection"];
+    _dragLiftDelay = toDragLiftDelay([[NSUserDefaults standardUserDefaults] integerForKey:@"WebKitDebugDragLiftDelay"]);
+#endif
+
+    _mediaContentTypesRequiringHardwareSupport = Settings::defaultMediaContentTypesRequiringHardwareSupport();
 
     return self;
 }
@@ -217,6 +250,7 @@ private:
     [coder encodeInteger:self.selectionGranularity forKey:@"selectionGranularity"];
     [coder encodeBool:self.allowsPictureInPictureMediaPlayback forKey:@"allowsPictureInPictureMediaPlayback"];
     [coder encodeBool:self.ignoresViewportScaleLimits forKey:@"ignoresViewportScaleLimits"];
+    [coder encodeInteger:self._dragLiftDelay forKey:@"dragLiftDelay"];
 #else
     [coder encodeInteger:self.userInterfaceDirectionPolicy forKey:@"userInterfaceDirectionPolicy"];
 #endif
@@ -244,6 +278,7 @@ private:
     self.selectionGranularity = static_cast<WKSelectionGranularity>([coder decodeIntegerForKey:@"selectionGranularity"]);
     self.allowsPictureInPictureMediaPlayback = [coder decodeBoolForKey:@"allowsPictureInPictureMediaPlayback"];
     self.ignoresViewportScaleLimits = [coder decodeBoolForKey:@"ignoresViewportScaleLimits"];
+    self._dragLiftDelay = toDragLiftDelay([coder decodeIntegerForKey:@"dragLiftDelay"]);
 #else
     auto userInterfaceDirectionPolicyCandidate = static_cast<WKUserInterfaceDirectionPolicy>([coder decodeIntegerForKey:@"userInterfaceDirectionPolicy"]);
     if (userInterfaceDirectionPolicyCandidate == WKUserInterfaceDirectionPolicyContent || userInterfaceDirectionPolicyCandidate == WKUserInterfaceDirectionPolicySystem)
@@ -286,16 +321,19 @@ private:
     configuration->_mediaTypesRequiringUserActionForPlayback = self->_mediaTypesRequiringUserActionForPlayback;
     configuration->_mainContentUserGestureOverrideEnabled = self->_mainContentUserGestureOverrideEnabled;
     configuration->_initialCapitalizationEnabled = self->_initialCapitalizationEnabled;
+    configuration->_waitsForPaintAfterViewDidMoveToWindow = self->_waitsForPaintAfterViewDidMoveToWindow;
+    configuration->_controlledByAutomation = self->_controlledByAutomation;
 
 #if PLATFORM(IOS)
     configuration->_allowsInlineMediaPlayback = self->_allowsInlineMediaPlayback;
     configuration->_allowsInlineMediaPlaybackAfterFullscreen = self->_allowsInlineMediaPlaybackAfterFullscreen;
-    configuration->_allowsInlineMediaPlaybackWithPlaysInlineAttribute = self->_allowsInlineMediaPlaybackWithPlaysInlineAttribute;
-    configuration->_allowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute = self->_allowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute;
+    configuration->_inlineMediaPlaybackRequiresPlaysInlineAttribute = self->_inlineMediaPlaybackRequiresPlaysInlineAttribute;
     configuration->_allowsPictureInPictureMediaPlayback = self->_allowsPictureInPictureMediaPlayback;
     configuration->_alwaysRunsAtForegroundPriority = _alwaysRunsAtForegroundPriority;
     configuration->_selectionGranularity = self->_selectionGranularity;
+    configuration->_allowsBlockSelection = self->_allowsBlockSelection;
     configuration->_ignoresViewportScaleLimits = self->_ignoresViewportScaleLimits;
+    configuration->_dragLiftDelay = self->_dragLiftDelay;
 #endif
 #if PLATFORM(MAC)
     configuration->_userInterfaceDirectionPolicy = self->_userInterfaceDirectionPolicy;
@@ -313,6 +351,12 @@ private:
 #if ENABLE(APPLE_PAY)
     configuration->_applePayEnabled = self->_applePayEnabled;
 #endif
+    configuration->_needsStorageAccessFromFileURLsQuirk = self->_needsStorageAccessFromFileURLsQuirk;
+    configuration->_overrideContentSecurityPolicy = adoptNS([self->_overrideContentSecurityPolicy copyWithZone:zone]);
+
+    configuration->_urlSchemeHandlers.set(adoptNS([self._urlSchemeHandlers mutableCopyWithZone:zone]));
+    configuration->_mediaContentTypesRequiringHardwareSupport = adoptNS([self._mediaContentTypesRequiringHardwareSupport copyWithZone:zone]);
+    configuration->_legacyEncryptedMediaAPIEnabled = self->_legacyEncryptedMediaAPIEnabled;
 
     return configuration;
 }
@@ -386,6 +430,33 @@ static NSString *defaultApplicationNameForUserAgent()
     _visitedLinkStore.set(visitedLinkStore);
 }
 
+- (void)setURLSchemeHandler:(id <WKURLSchemeHandler>)urlSchemeHandler forURLScheme:(NSString *)urlScheme
+{
+    auto *urlSchemeHandlers = _urlSchemeHandlers.get([] { return adoptNS([[NSMutableDictionary alloc] init]); });
+
+    if ([WKWebView handlesURLScheme:urlScheme])
+        [NSException raise:NSInvalidArgumentException format:@"'%@' is a URL scheme that WKWebView handles natively", urlScheme];
+
+    auto canonicalScheme = WebCore::URLParser::maybeCanonicalizeScheme(urlScheme);
+    if (!canonicalScheme)
+        [NSException raise:NSInvalidArgumentException format:@"'%@' is not a valid URL scheme", urlScheme];
+
+    if ([urlSchemeHandlers objectForKey:(NSString *)canonicalScheme.value()])
+        [NSException raise:NSInvalidArgumentException format:@"URL scheme '%@' already has a registered URL scheme handler", urlScheme];
+
+    [urlSchemeHandlers setObject:urlSchemeHandler forKey:(NSString *)canonicalScheme.value()];
+}
+
+- (nullable id <WKURLSchemeHandler>)urlSchemeHandlerForURLScheme:(NSString *)urlScheme
+{
+    auto canonicalScheme = WebCore::URLParser::maybeCanonicalizeScheme(urlScheme);
+    if (!canonicalScheme)
+        return nil;
+
+    auto *urlSchemeHandlers = _urlSchemeHandlers.get([] { return adoptNS([[NSMutableDictionary alloc] init]); });
+    return [urlSchemeHandlers objectForKey:(NSString *)canonicalScheme.value()];
+}
+
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
 
@@ -399,18 +470,13 @@ static NSString *defaultApplicationNameForUserAgent()
     self.websiteDataStore = websiteDataStore ? websiteDataStore->_dataStore.get() : nullptr;
 }
 
--(_WKVisitedLinkProvider *)_visitedLinkProvider
-{
-    return (_WKVisitedLinkProvider *)self._visitedLinkStore;
-}
+#pragma clang diagnostic pop
 
-- (void)_setVisitedLinkProvider:(_WKVisitedLinkProvider *)_visitedLinkProvider
+- (NSMutableDictionary<NSString *, id <WKURLSchemeHandler>> *)_urlSchemeHandlers
 {
-    self._visitedLinkStore = _visitedLinkProvider;
+    return _urlSchemeHandlers.get([] { return adoptNS([[NSMutableDictionary alloc] init]); });
 }
 
-#pragma clang diagnostic pop
-
 #if PLATFORM(IOS)
 - (WKWebViewContentProviderRegistry *)_contentProviderRegistry
 {
@@ -510,12 +576,12 @@ static NSString *defaultApplicationNameForUserAgent()
     _printsBackgrounds = printsBackgrounds;
 }
 
-- (CGFloat)_incrementalRenderingSuppressionTimeout
+- (NSTimeInterval)_incrementalRenderingSuppressionTimeout
 {
     return _incrementalRenderingSuppressionTimeout;
 }
 
-- (void)_setIncrementalRenderingSuppressionTimeout:(CGFloat)incrementalRenderingSuppressionTimeout
+- (void)_setIncrementalRenderingSuppressionTimeout:(NSTimeInterval)incrementalRenderingSuppressionTimeout
 {
     _incrementalRenderingSuppressionTimeout = incrementalRenderingSuppressionTimeout;
 }
@@ -571,34 +637,44 @@ static NSString *defaultApplicationNameForUserAgent()
     _alwaysRunsAtForegroundPriority = alwaysRunsAtForegroundPriority;
 }
 
-- (BOOL)_allowsInlineMediaPlaybackWithPlaysInlineAttribute
+- (BOOL)_inlineMediaPlaybackRequiresPlaysInlineAttribute
 {
-    return _allowsInlineMediaPlaybackWithPlaysInlineAttribute;
+    return _inlineMediaPlaybackRequiresPlaysInlineAttribute;
 }
 
-- (void)_setAllowsInlineMediaPlaybackWithPlaysInlineAttribute:(BOOL)requires
+- (void)_setInlineMediaPlaybackRequiresPlaysInlineAttribute:(BOOL)requires
 {
-    _allowsInlineMediaPlaybackWithPlaysInlineAttribute = requires;
+    _inlineMediaPlaybackRequiresPlaysInlineAttribute = requires;
 }
 
-- (BOOL)_allowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute
+- (BOOL)_allowsInlineMediaPlaybackAfterFullscreen
 {
-    return _allowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute;
+    return _allowsInlineMediaPlaybackAfterFullscreen;
 }
 
-- (void)_setAllowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute:(BOOL)requires
+- (void)_setAllowsInlineMediaPlaybackAfterFullscreen:(BOOL)allows
 {
-    _allowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute = requires;
+    _allowsInlineMediaPlaybackAfterFullscreen = allows;
 }
 
-- (BOOL)_allowsInlineMediaPlaybackAfterFullscreen
+- (BOOL)_allowsBlockSelection
 {
-    return _allowsInlineMediaPlaybackAfterFullscreen;
+    return _allowsBlockSelection;
 }
 
-- (void)_setAllowsInlineMediaPlaybackAfterFullscreen:(BOOL)allows
+- (void)_setAllowsBlockSelection:(BOOL)allowsBlockSelection
 {
-    _allowsInlineMediaPlaybackAfterFullscreen = allows;
+    _allowsBlockSelection = allowsBlockSelection;
+}
+
+- (_WKDragLiftDelay)_dragLiftDelay
+{
+    return _dragLiftDelay;
+}
+
+- (void)_setDragLiftDelay:(_WKDragLiftDelay)dragLiftDelay
+{
+    _dragLiftDelay = dragLiftDelay;
 }
 #endif // PLATFORM(IOS)
 
@@ -678,6 +754,26 @@ static NSString *defaultApplicationNameForUserAgent()
     _initialCapitalizationEnabled = initialCapitalizationEnabled;
 }
 
+- (BOOL)_waitsForPaintAfterViewDidMoveToWindow
+{
+    return _waitsForPaintAfterViewDidMoveToWindow;
+}
+
+- (void)_setWaitsForPaintAfterViewDidMoveToWindow:(BOOL)shouldSynchronize
+{
+    _waitsForPaintAfterViewDidMoveToWindow = shouldSynchronize;
+}
+
+- (BOOL)_isControlledByAutomation
+{
+    return _controlledByAutomation;
+}
+
+- (void)_setControlledByAutomation:(BOOL)controlledByAutomation
+{
+    _controlledByAutomation = controlledByAutomation;
+}
+
 #if PLATFORM(MAC)
 - (BOOL)_showsURLsInToolTips
 {
@@ -737,6 +833,46 @@ static NSString *defaultApplicationNameForUserAgent()
 #endif
 }
 
+- (BOOL)_needsStorageAccessFromFileURLsQuirk
+{
+    return _needsStorageAccessFromFileURLsQuirk;
+}
+
+- (void)_setNeedsStorageAccessFromFileURLsQuirk:(BOOL)needsLocalStorageQuirk
+{
+    _needsStorageAccessFromFileURLsQuirk = needsLocalStorageQuirk;
+}
+
+- (NSString *)_overrideContentSecurityPolicy
+{
+    return _overrideContentSecurityPolicy.get();
+}
+
+- (void)_setOverrideContentSecurityPolicy:(NSString *)overrideContentSecurityPolicy
+{
+    _overrideContentSecurityPolicy = adoptNS([overrideContentSecurityPolicy copy]);
+}
+
+- (NSString *)_mediaContentTypesRequiringHardwareSupport
+{
+    return _mediaContentTypesRequiringHardwareSupport.get();
+}
+
+- (void)_setMediaContentTypesRequiringHardwareSupport:(NSString *)mediaContentTypesRequiringHardwareSupport
+{
+    _mediaContentTypesRequiringHardwareSupport = adoptNS([mediaContentTypesRequiringHardwareSupport copy]);
+}
+
+- (void)_setLegacyEncryptedMediaAPIEnabled:(BOOL)enabled
+{
+    _legacyEncryptedMediaAPIEnabled = enabled;
+}
+
+- (BOOL)_legacyEncryptedMediaAPIEnabled
+{
+    return _legacyEncryptedMediaAPIEnabled;
+}
+
 @end
 
 @implementation WKWebViewConfiguration (WKDeprecated)
@@ -776,4 +912,18 @@ static NSString *defaultApplicationNameForUserAgent()
 
 @end
 
+@implementation WKWebViewConfiguration (WKBinaryCompatibilityWithIOS10)
+
+-(_WKVisitedLinkStore *)_visitedLinkProvider
+{
+    return self._visitedLinkStore;
+}
+
+- (void)_setVisitedLinkProvider:(_WKVisitedLinkStore *)visitedLinkProvider
+{
+    self._visitedLinkStore = visitedLinkProvider;
+}
+
+@end
+
 #endif // WK_API_ENABLED