| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #import "ios/web/public/browsing_data/browsing_data_removing_util.h" |
| |
| #import <WebKit/WebKit.h> |
| |
| #import "base/functional/callback_helpers.h" |
| #import "base/time/time.h" |
| #import "ios/web/common/uikit_ui_util.h" |
| #import "ios/web/public/browser_state.h" |
| #import "ios/web/public/browser_state_utils.h" |
| #import "ios/web/web_state/ui/wk_web_view_configuration_provider.h" |
| |
| namespace web { |
| namespace { |
| |
| // Converts ClearBrowsingDataMask to WKWebsiteDataStore strings. |
| NSSet<NSString*>* ConvertClearBrowsingDataMask(ClearBrowsingDataMask types) { |
| NSMutableSet<NSString*>* result = [[NSMutableSet alloc] init]; |
| if (IsRemoveDataMaskSet(types, ClearBrowsingDataMask::kRemoveCacheStorage)) { |
| [result addObject:WKWebsiteDataTypeDiskCache]; |
| [result addObject:WKWebsiteDataTypeMemoryCache]; |
| } |
| if (IsRemoveDataMaskSet(types, ClearBrowsingDataMask::kRemoveAppCache)) { |
| [result addObject:WKWebsiteDataTypeOfflineWebApplicationCache]; |
| } |
| if (IsRemoveDataMaskSet(types, ClearBrowsingDataMask::kRemoveLocalStorage)) { |
| [result addObject:WKWebsiteDataTypeSessionStorage]; |
| [result addObject:WKWebsiteDataTypeLocalStorage]; |
| } |
| if (IsRemoveDataMaskSet(types, ClearBrowsingDataMask::kRemoveWebSQL)) { |
| [result addObject:WKWebsiteDataTypeWebSQLDatabases]; |
| } |
| if (IsRemoveDataMaskSet(types, ClearBrowsingDataMask::kRemoveIndexedDB)) { |
| [result addObject:WKWebsiteDataTypeIndexedDBDatabases]; |
| } |
| if (IsRemoveDataMaskSet(types, ClearBrowsingDataMask::kRemoveCookies)) { |
| [result addObject:WKWebsiteDataTypeCookies]; |
| } |
| return result; |
| } |
| |
| } // anonymous namespace |
| |
| void ClearBrowsingData(BrowserState* browser_state, |
| ClearBrowsingDataMask types, |
| base::Time modified_since, |
| base::OnceClosure closure) { |
| NSSet<NSString*>* types_to_remove = ConvertClearBrowsingDataMask(types); |
| if (![types_to_remove count]) { |
| std::move(closure).Run(); |
| return; |
| } |
| |
| if (IsRemoveDataMaskSet(types, ClearBrowsingDataMask::kRemoveVisitedLinks)) { |
| // TODO(crbug.com/41219991): Purging the WKProcessPool is a workaround for |
| // the fact that there is no public API to clear visited links in |
| // WKWebView. Remove this workaround if/when that API is made public. |
| // Note: Purging the WKProcessPool for clearing visisted links does have |
| // the side-effect of also losing the in-memory cookies of WKWebView but |
| // it is not a problem in practice since there is no UI to only have |
| // visited links be removed but not cookies. |
| base::OnceClosure purge_process_pool = base::BindOnce( |
| &WKWebViewConfigurationProvider::Purge, |
| WKWebViewConfigurationProvider::FromBrowserState(browser_state) |
| .AsWeakPtr()); |
| |
| closure = std::move(purge_process_pool).Then(std::move(closure)); |
| } |
| |
| if (IsRemoveDataMaskSet(types, ClearBrowsingDataMask::kRemoveCookies)) { |
| // TODO(crbug.com/40491729): Create a dummy WKWebView to allow the APO |
| // -[WKWebsiteDataStore removeDataOfType:] to access the cookie store |
| // and clear cookies. This is a workaround that for the WebKit bug |
| // https://bugs.webkit.org/show_bug.cgi?id=149078 and needs to be |
| // removed when no longer necessary. |
| WKWebView* dummy_web_view; |
| dummy_web_view = [[WKWebView alloc] initWithFrame:CGRectZero]; |
| dummy_web_view.hidden = YES; |
| |
| // It seems that the WKWebView needs to be part of the view hierarchy to |
| // prevent its out-of-process process from being suspended. If it is not |
| // added to the view hierarchy, tests are failing when trying to |
| // remove/check the cookies which indicates that we might have the same |
| // issue with cookies. Adding the web view to the view hierarchy as a safe |
| // guard. |
| [GetAnyKeyWindow() insertSubview:dummy_web_view atIndex:0]; |
| |
| base::OnceClosure remove_dummy_web_view = base::BindOnce(^{ |
| [dummy_web_view removeFromSuperview]; |
| }); |
| |
| closure = std::move(remove_dummy_web_view).Then(std::move(closure)); |
| } |
| |
| WKWebsiteDataStore* data_store = GetDataStoreForBrowserState(browser_state); |
| [data_store removeDataOfTypes:types_to_remove |
| modifiedSince:modified_since.ToNSDate() |
| completionHandler:base::CallbackToBlock(std::move(closure))]; |
| } |
| |
| } // namespace web |