Commit 11fe3c86 authored by Eugene But's avatar Eugene But Committed by Commit Bot

Added feature flags for FileDownload and PassKitDownload features.

This CL adds kNewPassKitDownload and kNewFileDownload flags usage
to the web layer. Turning on kNewPassKitDownload flag will disable
CRWPassKitDownloader and webController:didLoadPassKitObject: callback.
Turning on kNewFileDownload will disable
controllerForUnhandledContentAtURL: callback.
Turning either of these flags on will add a logic, which discards
pending item if that item is download.

Both flags are turned off by default and there is no way to enable
them via chrome://flags yet.

This CL slightly changes the code inside WKNavigationDelegate's
webView:decidePolicyForNavigationResponse:decisionHandler: as follows:
 - CRWPassKitDownloader download is moved behind |!allowNavigation|
 - allowNavigation is not set to no if MIME type is PassKit
These are non functional changes because if MIME type is PassKit, then
|allowNavigation| is always NO.

Bug: 780646
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: I948ae3e1f38d266eda8aa7b99900900d8c02fef3
Reviewed-on: https://chromium-review.googlesource.com/783671
Commit-Queue: Eugene But <eugenebut@chromium.org>
Reviewed-by: default avatarGregory Chatzinoff <gchatz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#519795}
parent 783ff5e8
...@@ -25,6 +25,7 @@ typedef void (^PassKitCompletionHandler)(NSData*); ...@@ -25,6 +25,7 @@ typedef void (^PassKitCompletionHandler)(NSData*);
// CRWPassKitDownloader downloads PassKit data and passes it to a completion // CRWPassKitDownloader downloads PassKit data and passes it to a completion
// handler. // handler.
// DEPRECATED - Do not use this class. http://crbug.com/787943
@interface CRWPassKitDownloader : NSObject @interface CRWPassKitDownloader : NSObject
// Initializes the CRWPassKitDownloader. |getter| must not be null and // Initializes the CRWPassKitDownloader. |getter| must not be null and
......
...@@ -6,10 +6,12 @@ ...@@ -6,10 +6,12 @@
#include <memory> #include <memory>
#include "base/feature_list.h"
#include "base/mac/scoped_block.h" #include "base/mac/scoped_block.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "ios/web/public/features.h"
#include "net/http/http_response_headers.h" #include "net/http/http_response_headers.h"
#include "net/url_request/url_fetcher.h" #include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h" #include "net/url_request/url_fetcher_delegate.h"
...@@ -97,6 +99,7 @@ class PassKitFetcherDelegate : public URLFetcherDelegate { ...@@ -97,6 +99,7 @@ class PassKitFetcherDelegate : public URLFetcherDelegate {
- (instancetype)initWithContextGetter:(net::URLRequestContextGetter*)getter - (instancetype)initWithContextGetter:(net::URLRequestContextGetter*)getter
completionHandler:(web::PassKitCompletionHandler)handler { completionHandler:(web::PassKitCompletionHandler)handler {
DCHECK(!base::FeatureList::IsEnabled(web::features::kNewPassKitDownload));
self = [super init]; self = [super init];
if (self) { if (self) {
DCHECK(getter); DCHECK(getter);
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/containers/mru_cache.h" #include "base/containers/mru_cache.h"
#include "base/feature_list.h"
#import "base/ios/block_types.h" #import "base/ios/block_types.h"
#include "base/ios/ios_util.h" #include "base/ios/ios_util.h"
#import "base/ios/ns_error_util.h" #import "base/ios/ns_error_util.h"
...@@ -49,6 +50,7 @@ ...@@ -49,6 +50,7 @@
#include "ios/web/public/browser_state.h" #include "ios/web/public/browser_state.h"
#import "ios/web/public/download/download_controller.h" #import "ios/web/public/download/download_controller.h"
#include "ios/web/public/favicon_url.h" #include "ios/web/public/favicon_url.h"
#include "ios/web/public/features.h"
#import "ios/web/public/java_script_dialog_presenter.h" #import "ios/web/public/java_script_dialog_presenter.h"
#import "ios/web/public/navigation_item.h" #import "ios/web/public/navigation_item.h"
#import "ios/web/public/navigation_manager.h" #import "ios/web/public/navigation_manager.h"
...@@ -429,6 +431,7 @@ NSError* WKWebViewErrorWithSource(NSError* error, WKWebViewErrorSource source) { ...@@ -429,6 +431,7 @@ NSError* WKWebViewErrorWithSource(NSError* error, WKWebViewErrorSource source) {
// changed. // changed.
@property(weak, nonatomic, readonly) NSDictionary* WKWebViewObservers; @property(weak, nonatomic, readonly) NSDictionary* WKWebViewObservers;
// Downloader for PassKit files. Lazy initialized. // Downloader for PassKit files. Lazy initialized.
// DEPRECATED - Do not use this property. http://crbug.com/787943
@property(weak, nonatomic, readonly) CRWPassKitDownloader* passKitDownloader; @property(weak, nonatomic, readonly) CRWPassKitDownloader* passKitDownloader;
// The web view's view of the current URL. During page transitions // The web view's view of the current URL. During page transitions
...@@ -1941,7 +1944,9 @@ registerLoadRequestForURL:(const GURL&)requestURL ...@@ -1941,7 +1944,9 @@ registerLoadRequestForURL:(const GURL&)requestURL
} }
- (void)loadCancelled { - (void)loadCancelled {
[_passKitDownloader cancelPendingDownload]; if (!base::FeatureList::IsEnabled(web::features::kNewPassKitDownload)) {
[_passKitDownloader cancelPendingDownload];
}
if (_loadPhase != web::PAGE_LOADED) { if (_loadPhase != web::PAGE_LOADED) {
_loadPhase = web::PAGE_LOADED; _loadPhase = web::PAGE_LOADED;
if (!_isHalted) { if (!_isHalted) {
...@@ -2123,6 +2128,7 @@ registerLoadRequestForURL:(const GURL&)requestURL ...@@ -2123,6 +2128,7 @@ registerLoadRequestForURL:(const GURL&)requestURL
} }
- (CRWPassKitDownloader*)passKitDownloader { - (CRWPassKitDownloader*)passKitDownloader {
DCHECK(!base::FeatureList::IsEnabled(web::features::kNewPassKitDownload));
if (_passKitDownloader) { if (_passKitDownloader) {
return _passKitDownloader; return _passKitDownloader;
} }
...@@ -2908,8 +2914,10 @@ registerLoadRequestForURL:(const GURL&)requestURL ...@@ -2908,8 +2914,10 @@ registerLoadRequestForURL:(const GURL&)requestURL
- (void)handleLoadError:(NSError*)error - (void)handleLoadError:(NSError*)error
forNavigation:(WKNavigation*)navigation { forNavigation:(WKNavigation*)navigation {
NSString* MIMEType = [_pendingNavigationInfo MIMEType]; NSString* MIMEType = [_pendingNavigationInfo MIMEType];
if ([_passKitDownloader isMIMETypePassKitType:MIMEType]) if (!base::FeatureList::IsEnabled(web::features::kNewPassKitDownload) &&
[_passKitDownloader isMIMETypePassKitType:MIMEType]) {
return; return;
}
if ([error code] == NSURLErrorUnsupportedURL) if ([error code] == NSURLErrorUnsupportedURL)
return; return;
// In cases where a Plug-in handles the load do not take any further action. // In cases where a Plug-in handles the load do not take any further action.
...@@ -2936,34 +2944,47 @@ registerLoadRequestForURL:(const GURL&)requestURL ...@@ -2936,34 +2944,47 @@ registerLoadRequestForURL:(const GURL&)requestURL
[_navigationStates contextForNavigation:navigation]; [_navigationStates contextForNavigation:navigation];
navigationContext->SetError(error); navigationContext->SetError(error);
// Handles Frame Load Interrupted errors from WebView.
if ([error.domain isEqual:base::SysUTF8ToNSString(web::kWebKitErrorDomain)] && if ([error.domain isEqual:base::SysUTF8ToNSString(web::kWebKitErrorDomain)] &&
error.code == web::kWebKitErrorFrameLoadInterruptedByPolicyChange) { error.code == web::kWebKitErrorFrameLoadInterruptedByPolicyChange) {
// Handle Frame Load Interrupted errors from WebView. This block is executed
// when web controller rejected the load inside
// decidePolicyForNavigationAction: or decidePolicyForNavigationResponse:.
// Load rejection may happen if embedder denied the load via
// WebStatePolicyDecider or the navigation was a download navigation.
NSString* errorURLSpec = error.userInfo[NSURLErrorFailingURLStringErrorKey]; NSString* errorURLSpec = error.userInfo[NSURLErrorFailingURLStringErrorKey];
NSURL* errorURL = [NSURL URLWithString:errorURLSpec]; NSURL* errorURL = [NSURL URLWithString:errorURLSpec];
const GURL errorGURL = net::GURLWithNSURL(errorURL); if (!base::FeatureList::IsEnabled(web::features::kNewFileDownload) &&
![MIMEType isEqualToString:@"application/vnd.apple.pkpass"]) {
// See if the delegate wants to handle this case. // This block is executed to handle legacy download navigation.
if (errorGURL.is_valid() && const GURL errorGURL = net::GURLWithNSURL(errorURL);
[_delegate if (errorGURL.is_valid() &&
respondsToSelector:@selector( [_delegate respondsToSelector:@selector
controllerForUnhandledContentAtURL:)]) { (controllerForUnhandledContentAtURL:)]) {
id<CRWNativeContent> controller = id<CRWNativeContent> controller =
[_delegate controllerForUnhandledContentAtURL:errorGURL]; [_delegate controllerForUnhandledContentAtURL:errorGURL];
if (controller) { if (controller) {
[self loadCompleteWithSuccess:NO forNavigation:navigation]; [self loadCompleteWithSuccess:NO forNavigation:navigation];
[self removeWebView]; [self removeWebView];
[self setNativeController:controller]; [self setNativeController:controller];
[self loadNativeViewWithSuccess:YES [self loadNativeViewWithSuccess:YES
navigationContext:navigationContext]; navigationContext:navigationContext];
return; return;
}
} }
} }
// Ignore errors that originate from URLs that are opened in external apps. // The load was rejected, because embedder launched an external application.
if ([_openedApplicationURL containsObject:errorURL]) if ([_openedApplicationURL containsObject:errorURL])
return; return;
if (base::FeatureList::IsEnabled(web::features::kNewPassKitDownload) ||
base::FeatureList::IsEnabled(web::features::kNewFileDownload)) {
// This navigation was a download navigation and embedder now has a chance
// to start the download task.
_webStateImpl->SetIsLoading(false);
return;
}
// The wrapper error uses the URL of the error and not the requested URL // The wrapper error uses the URL of the error and not the requested URL
// (which can be different in case of a redirect) to match desktop Chrome // (which can be different in case of a redirect) to match desktop Chrome
// behavior. // behavior.
...@@ -4285,24 +4306,32 @@ registerLoadRequestForURL:(const GURL&)requestURL ...@@ -4285,24 +4306,32 @@ registerLoadRequestForURL:(const GURL&)requestURL
->CreateDownloadTask(_webStateImpl, [NSUUID UUID].UUIDString, ->CreateDownloadTask(_webStateImpl, [NSUUID UUID].UUIDString,
responseURL, contentDisposition, contentLength, responseURL, contentDisposition, contentLength,
base::SysNSStringToUTF8(MIMEType)); base::SysNSStringToUTF8(MIMEType));
}
if ([self.passKitDownloader isMIMETypePassKitType:MIMEType]) { BOOL downloadItem =
[self.passKitDownloader downloadPassKitFileWithURL:responseURL]; (base::FeatureList::IsEnabled(web::features::kNewPassKitDownload) ||
allowNavigation = NO; base::FeatureList::IsEnabled(web::features::kNewFileDownload));
// Discard the pending PassKit entry to ensure that the current URL is not if (!base::FeatureList::IsEnabled(web::features::kNewPassKitDownload) &&
// different from what is displayed on the view. If there is no previous [self.passKitDownloader isMIMETypePassKitType:MIMEType]) {
// committed URL, which can happen when a link is opened in a new tab via a [self.passKitDownloader downloadPassKitFileWithURL:responseURL];
// context menu or window.open, the pending entry should not be downloadItem = YES;
// discarded so that the NavigationManager is never empty. Also, URLs loaded }
// in a native view should be excluded to avoid an ugly animation where the
// web view is inserted and quickly removed. if (downloadItem) {
GURL lastCommittedURL = self.webState->GetLastCommittedURL(); // Discard the pending item to ensure that the current URL is not
BOOL isFirstLoad = lastCommittedURL.is_empty(); // different from what is displayed on the view. If there is no previous
BOOL previousItemWasLoadedInNativeView = // committed URL, which can happen when a link is opened in a new tab via
[self shouldLoadURLInNativeView:lastCommittedURL]; // a context menu or window.open, the pending entry should not be
if (!isFirstLoad && !previousItemWasLoadedInNativeView) // discarded so that the NavigationManager is never empty. Also, URLs
self.navigationManagerImpl->DiscardNonCommittedItems(); // loaded in a native view should be excluded to avoid an ugly animation
// where the web view is inserted and quickly removed.
GURL lastCommittedURL = self.webState->GetLastCommittedURL();
BOOL isFirstLoad = lastCommittedURL.is_empty();
BOOL previousItemWasLoadedInNativeView =
[self shouldLoadURLInNativeView:lastCommittedURL];
if (!isFirstLoad && !previousItemWasLoadedInNativeView)
self.navigationManagerImpl->DiscardNonCommittedItems();
}
} }
handler(allowNavigation ? WKNavigationResponsePolicyAllow handler(allowNavigation ? WKNavigationResponsePolicyAllow
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment