Commit 6cc10d03 authored by David Jean's avatar David Jean Committed by Commit Bot

[ios] merged LoadURL inside url loading service

Merged LoadURL directly in UrlLoadingService::LoadUrlInCurrentTab.
Removed URLLoadResult enum.
Exported InduceBRowserCrash.

Bug: 907527
Change-Id: I7070a954db76c1466564538e3896b402be8516ab
Reviewed-on: https://chromium-review.googlesource.com/c/1488914
Commit-Queue: David Jean <djean@chromium.org>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#636729}
parent ad0f43e7
...@@ -4,20 +4,60 @@ ...@@ -4,20 +4,60 @@
#import "ios/chrome/browser/url_loading/url_loading_service.h" #import "ios/chrome/browser/url_loading/url_loading_service.h"
#include "base/strings/string_number_conversions.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#include "ios/chrome/browser/chrome_url_constants.h"
#import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/main/browser.h"
#import "ios/chrome/browser/prerender/prerender_service.h"
#import "ios/chrome/browser/prerender/prerender_service_factory.h"
#import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab.h"
#import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/tabs/tab_model.h"
#import "ios/chrome/browser/ui/commands/open_new_tab_command.h" #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
#import "ios/chrome/browser/ui/ntp/ntp_util.h" #import "ios/chrome/browser/ui/ntp/ntp_util.h"
#import "ios/chrome/browser/url_loading/url_loading_notifier.h" #import "ios/chrome/browser/url_loading/url_loading_notifier.h"
#import "ios/chrome/browser/url_loading/url_loading_util.h" #import "ios/chrome/browser/url_loading/url_loading_util.h"
#import "ios/chrome/browser/web/load_timing_tab_helper.h"
#import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_list.h"
#include "net/base/url_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #endif
namespace {
// Helper method for inducing intentional freezes and crashes, in a separate
// function so it will show up in stack traces.
// If a delay parameter is present, the main thread will be frozen for that
// number of seconds.
// If a crash parameter is "true" (which is the default value), the browser will
// crash after this delay. Any other value will not trigger a crash.
void InduceBrowserCrash(const GURL& url) {
int delay = 0;
std::string delay_string;
if (net::GetValueForKeyInQuery(url, "delay", &delay_string)) {
base::StringToInt(delay_string, &delay);
}
if (delay > 0) {
sleep(delay);
}
bool crash = true;
std::string crash_string;
if (net::GetValueForKeyInQuery(url, "crash", &crash_string)) {
crash = crash_string == "" || crash_string == "true";
}
if (crash) {
// Induce an intentional crash in the browser process.
CHECK(false);
// Call another function, so that the above CHECK can't be tail-call
// optimized. This ensures that this method's name will show up in the stack
// for easier identification.
CHECK(true);
}
}
}
@interface UrlLoadingServiceUrlLoader : NSObject <UrlLoader> @interface UrlLoadingServiceUrlLoader : NSObject <UrlLoader>
- (instancetype)initWithUrlLoadingService:(UrlLoadingService*)service; - (instancetype)initWithUrlLoadingService:(UrlLoadingService*)service;
@end @end
...@@ -57,29 +97,81 @@ void UrlLoadingService::SetBrowser(Browser* browser) { ...@@ -57,29 +97,81 @@ void UrlLoadingService::SetBrowser(Browser* browser) {
void UrlLoadingService::LoadUrlInCurrentTab( void UrlLoadingService::LoadUrlInCurrentTab(
const ChromeLoadParams& chrome_params) { const ChromeLoadParams& chrome_params) {
URLLoadResult result = LoadURL(chrome_params, browser_, notifier_); web::NavigationManager::WebLoadParams params = chrome_params.web_params;
switch (result) { if (chrome_params.disposition == WindowOpenDisposition::SWITCH_TO_TAB) {
case URLLoadResult::SWITCH_TO_TAB: { SwitchToTab(chrome_params.web_params);
SwitchToTab(chrome_params.web_params); return;
break; }
}
case URLLoadResult::DISALLOWED_IN_INCOGNITO: { ios::ChromeBrowserState* browser_state = browser_->GetBrowserState();
OpenNewTabCommand* command =
[[OpenNewTabCommand alloc] initWithURL:chrome_params.web_params.url notifier_->TabWillOpenUrl(params.url, params.transition_type);
referrer:web::Referrer()
inIncognito:NO // NOTE: This check for the Crash Host URL is here to avoid the URL from
inBackground:NO // ending up in the history causing the app to crash at every subsequent
appendTo:kCurrentTab]; // restart.
OpenUrlInNewTab(command); if (params.url.host() == kChromeUIBrowserCrashHost) {
break; InduceBrowserCrash(params.url);
} // Under a debugger, the app can continue working even after the CHECK.
case URLLoadResult::INDUCED_CRASH: // Adding a return avoids adding the crash url to history.
case URLLoadResult::LOADED_PRERENDER: notifier_->TabFailedToOpenUrl(params.url, params.transition_type);
case URLLoadResult::RELOADED: return;
case URLLoadResult::NORMAL_LOAD: }
// Page load was handled, so nothing else to do.
break; // Ask the prerender service to load this URL if it can, and return if it does
// so.
PrerenderService* prerenderService =
PrerenderServiceFactory::GetForBrowserState(browser_state);
WebStateList* web_state_list = browser_->GetWebStateList();
id<SessionWindowRestoring> restorer =
(id<SessionWindowRestoring>)browser_->GetTabModel();
if (prerenderService &&
prerenderService->MaybeLoadPrerenderedURL(
params.url, params.transition_type, web_state_list, restorer)) {
notifier_->TabDidPrerenderUrl(params.url, params.transition_type);
return;
}
// Some URLs are not allowed while in incognito. If we are in incognito and
// load a disallowed URL, instead create a new tab not in the incognito state.
if (browser_state->IsOffTheRecord() && !IsURLAllowedInIncognito(params.url)) {
notifier_->TabFailedToOpenUrl(params.url, params.transition_type);
OpenNewTabCommand* command =
[[OpenNewTabCommand alloc] initWithURL:chrome_params.web_params.url
referrer:web::Referrer()
inIncognito:NO
inBackground:NO
appendTo:kCurrentTab];
OpenUrlInNewTab(command);
return;
} }
web::WebState* current_web_state = web_state_list->GetActiveWebState();
DCHECK(current_web_state);
BOOL typedOrGeneratedTransition =
PageTransitionCoreTypeIs(params.transition_type,
ui::PAGE_TRANSITION_TYPED) ||
PageTransitionCoreTypeIs(params.transition_type,
ui::PAGE_TRANSITION_GENERATED);
if (typedOrGeneratedTransition) {
LoadTimingTabHelper::FromWebState(current_web_state)->DidInitiatePageLoad();
}
// If this is a reload initiated from the omnibox.
// TODO(crbug.com/730192): Add DCHECK to verify that whenever urlToLoad is the
// same as the old url, the transition type is ui::PAGE_TRANSITION_RELOAD.
if (PageTransitionCoreTypeIs(params.transition_type,
ui::PAGE_TRANSITION_RELOAD)) {
current_web_state->GetNavigationManager()->Reload(
web::ReloadType::NORMAL, true /* check_for_repost */);
notifier_->TabDidReloadUrl(params.url, params.transition_type);
return;
}
current_web_state->GetNavigationManager()->LoadURLWithParams(params);
notifier_->TabDidOpenUrl(params.url, params.transition_type);
} }
void UrlLoadingService::SwitchToTab( void UrlLoadingService::SwitchToTab(
......
...@@ -19,30 +19,6 @@ class ChromeBrowserState; ...@@ -19,30 +19,6 @@ class ChromeBrowserState;
namespace web { namespace web {
class WebState; class WebState;
} }
class Browser;
class UrlLoadingNotifier;
// Possible results from calling LoadURL().
enum class URLLoadResult {
// No load performed, calling code should switch to an existing tab with the
// URL already loaded instead.
SWITCH_TO_TAB,
// A crash was intentionally induced as part of the URL load (typically this
// means the URL was an 'induce crash' URL). Technically this result is
// unlikely to actually be returned, but it identifies a specific result for
// the LoadURL() call.
INDUCED_CRASH,
// The URL to be loaded was already prerendered, so the prerendered web_state
// was swapped into the target tab model to perform the load.
LOADED_PRERENDER,
// No load performed, since the requested URL couldn't be loaded in incognito.
// Calling code should instead load the URL in non-incognito.
DISALLOWED_IN_INCOGNITO,
// The requested URL load was a reload, and it was performed as a reload.
RELOADED,
// The URL load was initiated normally.
NORMAL_LOAD
};
// true if |url| can be loaded in an incognito tab. // true if |url| can be loaded in an incognito tab.
bool IsURLAllowedInIncognito(const GURL& url); bool IsURLAllowedInIncognito(const GURL& url);
...@@ -60,12 +36,4 @@ void RestoreTab(const SessionID session_id, ...@@ -60,12 +36,4 @@ void RestoreTab(const SessionID session_id,
WindowOpenDisposition disposition, WindowOpenDisposition disposition,
ios::ChromeBrowserState* browser_state); ios::ChromeBrowserState* browser_state);
// Returns the result (as defined in the enum definition above) of initiating a
// URL load as defined in |chrome_params|.
// TODO(crbug.com/907527): hoist into url_loading_service and remove
// URLLoadResult.
URLLoadResult LoadURL(const ChromeLoadParams& chrome_params,
Browser* browser,
UrlLoadingNotifier* notifier);
#endif // IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_UTIL_H_ #endif // IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_UTIL_H_
...@@ -9,14 +9,11 @@ ...@@ -9,14 +9,11 @@
#include "components/sessions/core/tab_restore_service_helper.h" #include "components/sessions/core/tab_restore_service_helper.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/chrome_url_constants.h"
#import "ios/chrome/browser/main/browser.h"
#import "ios/chrome/browser/prerender/prerender_service.h" #import "ios/chrome/browser/prerender/prerender_service.h"
#import "ios/chrome/browser/prerender/prerender_service_factory.h" #import "ios/chrome/browser/prerender/prerender_service_factory.h"
#include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h" #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h"
#include "ios/chrome/browser/sessions/tab_restore_service_delegate_impl_ios.h" #include "ios/chrome/browser/sessions/tab_restore_service_delegate_impl_ios.h"
#include "ios/chrome/browser/sessions/tab_restore_service_delegate_impl_ios_factory.h" #include "ios/chrome/browser/sessions/tab_restore_service_delegate_impl_ios_factory.h"
#import "ios/chrome/browser/url_loading/url_loading_notifier.h"
#import "ios/chrome/browser/url_loading/url_loading_notifier_factory.h"
#import "ios/chrome/browser/web/load_timing_tab_helper.h" #import "ios/chrome/browser/web/load_timing_tab_helper.h"
#import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_list.h"
#import "ios/web/public/web_state/web_state.h" #import "ios/web/public/web_state/web_state.h"
...@@ -27,40 +24,6 @@ ...@@ -27,40 +24,6 @@
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #endif
namespace {
// Helper method for inducing intentional freezes and crashes, in a separate
// function so it will show up in stack traces.
// If a delay parameter is present, the main thread will be frozen for that
// number of seconds.
// If a crash parameter is "true" (which is the default value), the browser will
// crash after this delay. Any other value will not trigger a crash.
void InduceBrowserCrash(const GURL& url) {
int delay = 0;
std::string delay_string;
if (net::GetValueForKeyInQuery(url, "delay", &delay_string)) {
base::StringToInt(delay_string, &delay);
}
if (delay > 0) {
sleep(delay);
}
bool crash = true;
std::string crash_string;
if (net::GetValueForKeyInQuery(url, "crash", &crash_string)) {
crash = crash_string == "" || crash_string == "true";
}
if (crash) {
// Induce an intentional crash in the browser process.
CHECK(false);
// Call another function, so that the above CHECK can't be tail-call
// optimized. This ensures that this method's name will show up in the stack
// for easier identification.
CHECK(true);
}
}
}
bool IsURLAllowedInIncognito(const GURL& url) { bool IsURLAllowedInIncognito(const GURL& url) {
// Most URLs are allowed in incognito; the following is an exception. // Most URLs are allowed in incognito; the following is an exception.
return !(url.SchemeIs(kChromeUIScheme) && url.host() == kChromeUIHistoryHost); return !(url.SchemeIs(kChromeUIScheme) && url.host() == kChromeUIHistoryHost);
...@@ -93,77 +56,3 @@ void RestoreTab(const SessionID session_id, ...@@ -93,77 +56,3 @@ void RestoreTab(const SessionID session_id,
browser_state->GetOriginalChromeBrowserState()); browser_state->GetOriginalChromeBrowserState());
restoreService->RestoreEntryById(delegate, session_id, disposition); restoreService->RestoreEntryById(delegate, session_id, disposition);
} }
URLLoadResult LoadURL(const ChromeLoadParams& chrome_params,
Browser* browser,
UrlLoadingNotifier* notifier) {
web::NavigationManager::WebLoadParams params = chrome_params.web_params;
if (chrome_params.disposition == WindowOpenDisposition::SWITCH_TO_TAB) {
return URLLoadResult::SWITCH_TO_TAB;
}
ios::ChromeBrowserState* browser_state = browser->GetBrowserState();
notifier->TabWillOpenUrl(params.url, params.transition_type);
// NOTE: This check for the Crash Host URL is here to avoid the URL from
// ending up in the history causing the app to crash at every subsequent
// restart.
if (params.url.host() == kChromeUIBrowserCrashHost) {
InduceBrowserCrash(params.url);
// Under a debugger, the app can continue working even after the CHECK.
// Adding a return avoids adding the crash url to history.
notifier->TabFailedToOpenUrl(params.url, params.transition_type);
return URLLoadResult::INDUCED_CRASH;
}
// Ask the prerender service to load this URL if it can, and return if it does
// so.
PrerenderService* prerenderService =
PrerenderServiceFactory::GetForBrowserState(browser_state);
WebStateList* web_state_list = browser->GetWebStateList();
id<SessionWindowRestoring> restorer =
(id<SessionWindowRestoring>)browser->GetTabModel();
if (prerenderService &&
prerenderService->MaybeLoadPrerenderedURL(
params.url, params.transition_type, web_state_list, restorer)) {
notifier->TabDidPrerenderUrl(params.url, params.transition_type);
return URLLoadResult::LOADED_PRERENDER;
}
// Some URLs are not allowed while in incognito. If we are in incognito and
// load a disallowed URL, instead create a new tab not in the incognito state.
if (browser_state->IsOffTheRecord() && !IsURLAllowedInIncognito(params.url)) {
notifier->TabFailedToOpenUrl(params.url, params.transition_type);
return URLLoadResult::DISALLOWED_IN_INCOGNITO;
}
web::WebState* current_web_state = web_state_list->GetActiveWebState();
DCHECK(current_web_state);
BOOL typedOrGeneratedTransition =
PageTransitionCoreTypeIs(params.transition_type,
ui::PAGE_TRANSITION_TYPED) ||
PageTransitionCoreTypeIs(params.transition_type,
ui::PAGE_TRANSITION_GENERATED);
if (typedOrGeneratedTransition) {
LoadTimingTabHelper::FromWebState(current_web_state)->DidInitiatePageLoad();
}
// If this is a reload initiated from the omnibox.
// TODO(crbug.com/730192): Add DCHECK to verify that whenever urlToLoad is the
// same as the old url, the transition type is ui::PAGE_TRANSITION_RELOAD.
if (PageTransitionCoreTypeIs(params.transition_type,
ui::PAGE_TRANSITION_RELOAD)) {
current_web_state->GetNavigationManager()->Reload(
web::ReloadType::NORMAL, true /* check_for_repost */);
notifier->TabDidReloadUrl(params.url, params.transition_type);
return URLLoadResult::RELOADED;
}
current_web_state->GetNavigationManager()->LoadURLWithParams(params);
notifier->TabDidOpenUrl(params.url, params.transition_type);
return URLLoadResult::NORMAL_LOAD;
}
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