| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "ios/web/web_state/ui/wk_web_view_configuration_provider.h" | 5 #import "ios/web/web_state/ui/wk_web_view_configuration_provider.h" |
| 6 | 6 |
| 7 #import <Foundation/Foundation.h> | 7 #import <Foundation/Foundation.h> |
| 8 #import <objc/runtime.h> | |
| 9 #import <WebKit/WebKit.h> | 8 #import <WebKit/WebKit.h> |
| 10 | 9 |
| 11 #include "base/ios/ios_util.h" | 10 #include "base/ios/ios_util.h" |
| 12 #import "base/ios/weak_nsobject.h" | 11 #import "base/ios/weak_nsobject.h" |
| 13 #import "base/logging.h" | 12 #import "base/logging.h" |
| 14 #import "ios/web/alloc_with_zone_interceptor.h" | |
| 15 #include "ios/web/public/browser_state.h" | 13 #include "ios/web/public/browser_state.h" |
| 16 #import "ios/web/web_state/js/page_script_util.h" | 14 #import "ios/web/web_state/js/page_script_util.h" |
| 17 #import "ios/web/web_state/ui/crw_wk_script_message_router.h" | 15 #import "ios/web/web_state/ui/crw_wk_script_message_router.h" |
| 18 #import "ios/web/web_state/web_view_internal_creation_util.h" | |
| 19 | |
| 20 #if !defined(NDEBUG) | |
| 21 | |
| 22 namespace { | |
| 23 BOOL gAllowWKProcessPoolCreation = NO; | |
| 24 | |
| 25 // By default WKProcessPool creation is not allowed by embedder to prevent | |
| 26 // issues with browsing data clearing. However some iOS system methods do create | |
| 27 // WKProcessPool inside, which is perfectly fine and should be allowed. This | |
| 28 // method whitelists given |klass| with given |selector|, so creation of | |
| 29 // WKProcessPool is allowed inside that selector call. This function currently | |
| 30 // supports Objective-C methods with up to 4 arguments and needs to be updated | |
| 31 // if support for more arguments is required. | |
| 32 void AllowWKProcessPoolCreation(Class klass, SEL selector) { | |
| 33 Method method = class_getInstanceMethod(klass, selector); | |
| 34 IMP originalImp = method_getImplementation(method); | |
| 35 IMP safeImp = imp_implementationWithBlock( | |
| 36 ^(id self, id arg1, id arg2, id arg3, id arg4) { | |
| 37 BOOL oldAllowWKProcessPoolCreation = gAllowWKProcessPoolCreation; | |
| 38 gAllowWKProcessPoolCreation = YES; | |
| 39 id result = originalImp(self, selector, arg1, arg2, arg3, arg4); | |
| 40 gAllowWKProcessPoolCreation = oldAllowWKProcessPoolCreation; | |
| 41 return result; | |
| 42 }); | |
| 43 | |
| 44 method_setImplementation(method, safeImp); | |
| 45 } | |
| 46 } | |
| 47 | |
| 48 @interface WKProcessPool (CRWAdditions) | |
| 49 @end | |
| 50 | |
| 51 @implementation WKProcessPool (CRWAdditions) | |
| 52 | |
| 53 + (void)load { | |
| 54 id (^allocator)(Class klass, NSZone* zone) = ^id(Class klass, NSZone* zone) { | |
| 55 if (gAllowWKProcessPoolCreation || web::IsWebViewAllocInitAllowed()) { | |
| 56 return NSAllocateObject(klass, 0, zone); | |
| 57 } | |
| 58 // You have hit this because you are trying to create a WKProcessPool | |
| 59 // directly or indirectly (f.e. by creating WKWebViewConfiguration | |
| 60 // manually). Please use GetWebViewConfiguration() to get | |
| 61 // WKWebViewConfiguration object. | |
| 62 NOTREACHED(); | |
| 63 return nil; | |
| 64 }; | |
| 65 web::AddAllocWithZoneMethod([WKProcessPool class], allocator); | |
| 66 | |
| 67 if (!base::ios::IsRunningOnIOS9OrLater()) | |
| 68 return; | |
| 69 | |
| 70 // Make sure that WKWebsiteDataStore is allowed to create WKProcessPool for | |
| 71 // internal implementation purposes. | |
| 72 AllowWKProcessPoolCreation( | |
| 73 [WKWebsiteDataStore class], | |
| 74 @selector(fetchDataRecordsOfTypes:completionHandler:completionHandler:)); | |
| 75 AllowWKProcessPoolCreation( | |
| 76 [WKWebsiteDataStore class], | |
| 77 @selector(removeDataOfTypes:forDataRecords:completionHandler:)); | |
| 78 AllowWKProcessPoolCreation( | |
| 79 [WKWebsiteDataStore class], | |
| 80 @selector(removeDataOfTypes:modifiedSince:completionHandler:)); | |
| 81 } | |
| 82 | |
| 83 @end | |
| 84 | |
| 85 #endif // !defined(NDEBUG) | |
| 86 | 16 |
| 87 namespace web { | 17 namespace web { |
| 88 | 18 |
| 89 namespace { | 19 namespace { |
| 90 // A key used to associate a WKWebViewConfigurationProvider with a BrowserState. | 20 // A key used to associate a WKWebViewConfigurationProvider with a BrowserState. |
| 91 const char kWKWebViewConfigProviderKeyName[] = "wk_web_view_config_provider"; | 21 const char kWKWebViewConfigProviderKeyName[] = "wk_web_view_config_provider"; |
| 92 | 22 |
| 93 // Returns an autoreleased instance of WKUserScript to be added to | 23 // Returns an autoreleased instance of WKUserScript to be added to |
| 94 // configuration's userContentController. | 24 // configuration's userContentController. |
| 95 WKUserScript* GetEarlyPageScript() { | 25 WKUserScript* GetEarlyPageScript() { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 if (!configuration_) { | 59 if (!configuration_) { |
| 130 configuration_.reset([[WKWebViewConfiguration alloc] init]); | 60 configuration_.reset([[WKWebViewConfiguration alloc] init]); |
| 131 if (is_off_the_record_ && base::ios::IsRunningOnIOS9OrLater()) { | 61 if (is_off_the_record_ && base::ios::IsRunningOnIOS9OrLater()) { |
| 132 // WKWebsiteDataStore is iOS9 only. | 62 // WKWebsiteDataStore is iOS9 only. |
| 133 [configuration_ | 63 [configuration_ |
| 134 setWebsiteDataStore:[WKWebsiteDataStore nonPersistentDataStore]]; | 64 setWebsiteDataStore:[WKWebsiteDataStore nonPersistentDataStore]]; |
| 135 } | 65 } |
| 136 // setJavaScriptCanOpenWindowsAutomatically is required to support popups. | 66 // setJavaScriptCanOpenWindowsAutomatically is required to support popups. |
| 137 [[configuration_ preferences] setJavaScriptCanOpenWindowsAutomatically:YES]; | 67 [[configuration_ preferences] setJavaScriptCanOpenWindowsAutomatically:YES]; |
| 138 [[configuration_ userContentController] addUserScript:GetEarlyPageScript()]; | 68 [[configuration_ userContentController] addUserScript:GetEarlyPageScript()]; |
| 139 #if !defined(NDEBUG) | |
| 140 // Lazily load WKProcessPool. -[[WKProcessPool alloc] init] call is not | |
| 141 // allowed except when creating config object inside this class. | |
| 142 // Unmanaged creation of WKProcessPool may lead to issues with cookie | |
| 143 // clearing and Browsing Data Partitioning implementation. | |
| 144 gAllowWKProcessPoolCreation = YES; | |
| 145 CHECK([configuration_ processPool]); | |
| 146 gAllowWKProcessPoolCreation = NO; | |
| 147 #endif // !defined(NDEBUG) | |
| 148 } | 69 } |
| 149 // Prevent callers from changing the internals of configuration. | 70 // Prevent callers from changing the internals of configuration. |
| 150 return [[configuration_ copy] autorelease]; | 71 return [[configuration_ copy] autorelease]; |
| 151 } | 72 } |
| 152 | 73 |
| 153 CRWWKScriptMessageRouter* | 74 CRWWKScriptMessageRouter* |
| 154 WKWebViewConfigurationProvider::GetScriptMessageRouter() { | 75 WKWebViewConfigurationProvider::GetScriptMessageRouter() { |
| 155 DCHECK([NSThread isMainThread]); | 76 DCHECK([NSThread isMainThread]); |
| 156 if (!router_) { | 77 if (!router_) { |
| 157 WKUserContentController* userContentController = | 78 WKUserContentController* userContentController = |
| (...skipping 14 matching lines...) Expand all Loading... |
| 172 configuration_.reset(); | 93 configuration_.reset(); |
| 173 router_.reset(); | 94 router_.reset(); |
| 174 // Make sure that no one retains configuration, router, processPool. | 95 // Make sure that no one retains configuration, router, processPool. |
| 175 DCHECK(!weak_configuration); | 96 DCHECK(!weak_configuration); |
| 176 DCHECK(!weak_router); | 97 DCHECK(!weak_router); |
| 177 // TODO(crbug.com/522672): Enable this DCHECK. | 98 // TODO(crbug.com/522672): Enable this DCHECK. |
| 178 // DCHECK(!weak_process_pool); | 99 // DCHECK(!weak_process_pool); |
| 179 } | 100 } |
| 180 | 101 |
| 181 } // namespace web | 102 } // namespace web |
| OLD | NEW |