Commit c3289815 authored by David Jean's avatar David Jean Committed by Commit Bot

[ios] add url loading service

Add an url_loading_service (and factory) that will handle all url loading and will pass on UI actions to a delegate (here implemented in BrowserCoordinator, which in turn passes it on to BVC)

This will make chipping at URLLoader much easier.  The delegate api will change drastically in upcoming CL, as for now, it just reflects the current url load data structure and existing methods.

Bug: 907527
Change-Id: I6c72ad307d9e80249cac909149129dc593f9cbd1
Reviewed-on: https://chromium-review.googlesource.com/c/1442715
Commit-Queue: David Jean <djean@chromium.org>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#628273}
parent 0631a1ce
...@@ -96,6 +96,7 @@ source_set("unit_tests") { ...@@ -96,6 +96,7 @@ source_set("unit_tests") {
"//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/browser_state:test_support",
"//ios/chrome/browser/favicon", "//ios/chrome/browser/favicon",
"//ios/chrome/browser/find_in_page", "//ios/chrome/browser/find_in_page",
"//ios/chrome/browser/main:test_support",
"//ios/chrome/browser/search_engines", "//ios/chrome/browser/search_engines",
"//ios/chrome/browser/sessions", "//ios/chrome/browser/sessions",
"//ios/chrome/browser/snapshots", "//ios/chrome/browser/snapshots",
...@@ -108,6 +109,7 @@ source_set("unit_tests") { ...@@ -108,6 +109,7 @@ source_set("unit_tests") {
"//ios/chrome/browser/ui/ntp:ntp_controller", "//ios/chrome/browser/ui/ntp:ntp_controller",
"//ios/chrome/browser/ui/toolbar/public", "//ios/chrome/browser/ui/toolbar/public",
"//ios/chrome/browser/ui/toolbar/test", "//ios/chrome/browser/ui/toolbar/test",
"//ios/chrome/browser/url_loading",
"//ios/chrome/browser/web", "//ios/chrome/browser/web",
"//ios/chrome/browser/web:web_internal", "//ios/chrome/browser/web:web_internal",
"//ios/chrome/browser/web_state_list", "//ios/chrome/browser/web_state_list",
......
...@@ -24,6 +24,10 @@ ...@@ -24,6 +24,10 @@
- (void)clearPresentedStateWithCompletion:(ProceduralBlock)completion - (void)clearPresentedStateWithCompletion:(ProceduralBlock)completion
dismissOmnibox:(BOOL)dismissOmnibox; dismissOmnibox:(BOOL)dismissOmnibox;
// Switch to the tab best represented by the given |params|.
- (void)switchToTabWithParams:
(const web::NavigationManager::WebLoadParams&)params;
// Called before the instance is deallocated. // Called before the instance is deallocated.
- (void)shutdown; - (void)shutdown;
......
...@@ -159,6 +159,8 @@ ...@@ -159,6 +159,8 @@
#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_notifier_factory.h" #import "ios/chrome/browser/url_loading/url_loading_notifier_factory.h"
#import "ios/chrome/browser/url_loading/url_loading_observer_bridge.h" #import "ios/chrome/browser/url_loading/url_loading_observer_bridge.h"
#import "ios/chrome/browser/url_loading/url_loading_service.h"
#import "ios/chrome/browser/url_loading/url_loading_service_factory.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/voice/voice_search_navigations_tab_helper.h" #import "ios/chrome/browser/voice/voice_search_navigations_tab_helper.h"
#import "ios/chrome/browser/web/blocked_popup_tab_helper.h" #import "ios/chrome/browser/web/blocked_popup_tab_helper.h"
...@@ -1376,6 +1378,11 @@ NSString* const kBrowserViewControllerSnackbarCategory = ...@@ -1376,6 +1378,11 @@ NSString* const kBrowserViewControllerSnackbarCategory =
_browserState); _browserState);
if (webUsageEnabler) if (webUsageEnabler)
webUsageEnabler->SetWebStateList(nullptr); webUsageEnabler->SetWebStateList(nullptr);
UrlLoadingNotifier* urlLoadingNotifier =
UrlLoadingNotifierFactory::GetForBrowserState(_browserState);
if (urlLoadingNotifier)
urlLoadingNotifier->RemoveObserver(_URLLoadingObserverBridge.get());
} }
// Disconnect child coordinators. // Disconnect child coordinators.
...@@ -1861,7 +1868,7 @@ NSString* const kBrowserViewControllerSnackbarCategory = ...@@ -1861,7 +1868,7 @@ NSString* const kBrowserViewControllerSnackbarCategory =
_URLLoadingObserverBridge = std::make_unique<UrlLoadingObserverBridge>(self); _URLLoadingObserverBridge = std::make_unique<UrlLoadingObserverBridge>(self);
UrlLoadingNotifier* urlLoadingNotifier = UrlLoadingNotifier* urlLoadingNotifier =
ios::UrlLoadingNotifierFactory::GetForBrowserState(_browserState); UrlLoadingNotifierFactory::GetForBrowserState(_browserState);
urlLoadingNotifier->AddObserver(_URLLoadingObserverBridge.get()); urlLoadingNotifier->AddObserver(_URLLoadingObserverBridge.get());
NSUInteger count = self.tabModel.count; NSUInteger count = self.tabModel.count;
...@@ -3944,34 +3951,16 @@ NSString* const kBrowserViewControllerSnackbarCategory = ...@@ -3944,34 +3951,16 @@ NSString* const kBrowserViewControllerSnackbarCategory =
#pragma mark - UrlLoader (Public) #pragma mark - UrlLoader (Public)
- (void)loadURLWithParams:(const ChromeLoadParams&)chromeParams { - (void)loadURLWithParams:(const ChromeLoadParams&)chromeParams {
URLLoadResult result = // TODO(crbug.com/907527): call UrlLoadingService directly where we call
LoadURL(chromeParams, self.browserState, self.tabModel.webStateList, // this method.
/* SessionWindowRestoring */ self.tabModel); UrlLoadingService* urlLoadingService =
switch (result) { UrlLoadingServiceFactory::GetForBrowserState(self.browserState);
case URLLoadResult::SWITCH_TO_TAB: { urlLoadingService->LoadUrlInCurrentTab(chromeParams);
[self switchToTabWithParams:chromeParams.web_params];
break;
}
case URLLoadResult::DISALLOWED_IN_INCOGNITO: {
OpenNewTabCommand* command =
[[OpenNewTabCommand alloc] initWithURL:chromeParams.web_params.url
referrer:web::Referrer()
inIncognito:NO
inBackground:NO
appendTo:kCurrentTab];
[self webPageOrderedOpen:command];
break;
}
case URLLoadResult::INDUCED_CRASH:
case URLLoadResult::LOADED_PRERENDER:
case URLLoadResult::RELOADED:
case URLLoadResult::NORMAL_LOAD:
// Page load was handled, so nothing else to do.
break;
}
} }
- (void)webPageOrderedOpen:(OpenNewTabCommand*)command { - (void)webPageOrderedOpen:(OpenNewTabCommand*)command {
// TODO(crbug.com/907527): move to UrlLoadingService::OpenUrlInNewTab.
// Send either the "New Tab Opened" or "New Incognito Tab" opened to the // Send either the "New Tab Opened" or "New Incognito Tab" opened to the
// feature_engagement::Tracker based on |inIncognito|. // feature_engagement::Tracker based on |inIncognito|.
feature_engagement::NotifyNewTabEvent(self.tabModel.browserState, feature_engagement::NotifyNewTabEvent(self.tabModel.browserState,
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "ios/chrome/browser/chrome_paths.h" #include "ios/chrome/browser/chrome_paths.h"
#include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/chrome_url_constants.h"
#include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h" #include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h"
#include "ios/chrome/browser/main/test_browser.h"
#include "ios/chrome/browser/search_engines/template_url_service_factory.h" #include "ios/chrome/browser/search_engines/template_url_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"
#import "ios/chrome/browser/snapshots/snapshot_tab_helper.h" #import "ios/chrome/browser/snapshots/snapshot_tab_helper.h"
...@@ -46,6 +47,8 @@ ...@@ -46,6 +47,8 @@
#import "ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h" #import "ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h"
#include "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/browser/ui/ui_feature_flags.h"
#include "ios/chrome/browser/ui/util/ui_util.h" #include "ios/chrome/browser/ui/util/ui_util.h"
#import "ios/chrome/browser/url_loading/url_loading_service.h"
#import "ios/chrome/browser/url_loading/url_loading_service_factory.h"
#import "ios/chrome/browser/web/sad_tab_tab_helper.h" #import "ios/chrome/browser/web/sad_tab_tab_helper.h"
#include "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h" #include "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h"
#include "ios/chrome/browser/web_state_list/web_state_list.h" #include "ios/chrome/browser/web_state_list/web_state_list.h"
...@@ -149,6 +152,32 @@ using web::WebStateImpl; ...@@ -149,6 +152,32 @@ using web::WebStateImpl;
} }
@end @end
@interface URLLoadingServiceTestDelegate : NSObject <URLLoadingServiceDelegate>
@property(nonatomic, readonly) BrowserViewController* bvc;
@end
@implementation URLLoadingServiceTestDelegate
- (instancetype)initWithBrowserViewController:(BrowserViewController*)bvc {
if ((self = [super init])) {
_bvc = bvc;
}
return self;
}
#pragma mark - URLLoadingServiceDelegate
- (void)switchToTabWithParams:
(const web::NavigationManager::WebLoadParams&)params {
[self.bvc switchToTabWithParams:params];
}
- (void)openURLInNewTabWithCommand:(OpenNewTabCommand*)command {
[self.bvc webPageOrderedOpen:command];
}
@end
#pragma mark - #pragma mark -
namespace { namespace {
...@@ -246,6 +275,16 @@ class BrowserViewControllerTest : public BlockCleanupTest { ...@@ -246,6 +275,16 @@ class BrowserViewControllerTest : public BlockCleanupTest {
chrome_browser_state_.get()); chrome_browser_state_.get());
template_url_service->Load(); template_url_service->Load();
browser_ = new TestBrowser(chrome_browser_state_.get(), tabModel);
url_loading_delegate_ = [[URLLoadingServiceTestDelegate alloc]
initWithBrowserViewController:bvc_];
UrlLoadingService* urlLoadingService =
UrlLoadingServiceFactory::GetForBrowserState(
chrome_browser_state_.get());
urlLoadingService->SetDelegate(url_loading_delegate_);
urlLoadingService->SetBrowser(browser_);
// Force the view to load. // Force the view to load.
UIWindow* window = [[UIWindow alloc] initWithFrame:CGRectZero]; UIWindow* window = [[UIWindow alloc] initWithFrame:CGRectZero];
[window addSubview:[bvc_ view]]; [window addSubview:[bvc_ view]];
...@@ -256,6 +295,11 @@ class BrowserViewControllerTest : public BlockCleanupTest { ...@@ -256,6 +295,11 @@ class BrowserViewControllerTest : public BlockCleanupTest {
[[bvc_ view] removeFromSuperview]; [[bvc_ view] removeFromSuperview];
[bvc_ shutdown]; [bvc_ shutdown];
// Cleanup to avoid debugger crash in non empty observer lists.
WebStateList* web_state_list = tabModel_.webStateList;
web_state_list->CloseAllWebStates(
WebStateList::ClosingFlags::CLOSE_NO_FLAGS);
BlockCleanupTest::TearDown(); BlockCleanupTest::TearDown();
} }
...@@ -284,6 +328,8 @@ class BrowserViewControllerTest : public BlockCleanupTest { ...@@ -284,6 +328,8 @@ class BrowserViewControllerTest : public BlockCleanupTest {
OCMockObject* dependencyFactory_; OCMockObject* dependencyFactory_;
CommandDispatcher* command_dispatcher_; CommandDispatcher* command_dispatcher_;
BrowserViewController* bvc_; BrowserViewController* bvc_;
Browser* browser_;
URLLoadingServiceTestDelegate* url_loading_delegate_;
UIWindow* window_; UIWindow* window_;
}; };
......
...@@ -48,6 +48,7 @@ source_set("main") { ...@@ -48,6 +48,7 @@ source_set("main") {
"//ios/chrome/browser/ui/recent_tabs", "//ios/chrome/browser/ui/recent_tabs",
"//ios/chrome/browser/ui/snackbar", "//ios/chrome/browser/ui/snackbar",
"//ios/chrome/browser/ui/translate", "//ios/chrome/browser/ui/translate",
"//ios/chrome/browser/url_loading",
"//ios/chrome/browser/web", "//ios/chrome/browser/web",
"//ios/chrome/browser/web:tab_helper_delegates", "//ios/chrome/browser/web:tab_helper_delegates",
"//ios/chrome/browser/web:web_internal", "//ios/chrome/browser/web:web_internal",
......
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
#import "ios/chrome/browser/ui/snackbar/snackbar_coordinator.h" #import "ios/chrome/browser/ui/snackbar/snackbar_coordinator.h"
#import "ios/chrome/browser/ui/translate/language_selection_coordinator.h" #import "ios/chrome/browser/ui/translate/language_selection_coordinator.h"
#import "ios/chrome/browser/ui/translate/translate_infobar_coordinator.h" #import "ios/chrome/browser/ui/translate/translate_infobar_coordinator.h"
#import "ios/chrome/browser/url_loading/url_loading_service.h"
#import "ios/chrome/browser/url_loading/url_loading_service_factory.h"
#import "ios/chrome/browser/web/print_tab_helper.h" #import "ios/chrome/browser/web/print_tab_helper.h"
#import "ios/chrome/browser/web/repost_form_tab_helper.h" #import "ios/chrome/browser/web/repost_form_tab_helper.h"
#import "ios/chrome/browser/web/repost_form_tab_helper_delegate.h" #import "ios/chrome/browser/web/repost_form_tab_helper_delegate.h"
...@@ -53,6 +55,7 @@ ...@@ -53,6 +55,7 @@
@interface BrowserCoordinator () <FormInputAccessoryCoordinatorDelegate, @interface BrowserCoordinator () <FormInputAccessoryCoordinatorDelegate,
RepostFormTabHelperDelegate, RepostFormTabHelperDelegate,
URLLoadingServiceDelegate,
WebStateListObserving> WebStateListObserving>
// Whether the coordinator is started. // Whether the coordinator is started.
...@@ -142,6 +145,7 @@ ...@@ -142,6 +145,7 @@
startDispatchingToTarget:self startDispatchingToTarget:self
forProtocol:@protocol(BrowserCoordinatorCommands)]; forProtocol:@protocol(BrowserCoordinatorCommands)];
[self installDelegatesForAllWebStates]; [self installDelegatesForAllWebStates];
[self installDelegatesForBrowserState];
[self addWebStateListObserver]; [self addWebStateListObserver];
[super start]; [super start];
self.started = YES; self.started = YES;
...@@ -152,6 +156,7 @@ ...@@ -152,6 +156,7 @@
return; return;
[super stop]; [super stop];
[self removeWebStateListObserver]; [self removeWebStateListObserver];
[self uninstallDelegatesForBrowserState];
[self uninstallDelegatesForAllWebStates]; [self uninstallDelegatesForAllWebStates];
[self.dispatcher stopDispatchingToTarget:self]; [self.dispatcher stopDispatchingToTarget:self];
[self stopChildCoordinators]; [self stopChildCoordinators];
...@@ -424,6 +429,17 @@ ...@@ -424,6 +429,17 @@
self.repostFormCoordinator = nil; self.repostFormCoordinator = nil;
} }
#pragma mark - URLLoadingServiceDelegate
- (void)switchToTabWithParams:
(const web::NavigationManager::WebLoadParams&)params {
[self.viewController switchToTabWithParams:params];
}
- (void)openURLInNewTabWithCommand:(OpenNewTabCommand*)command {
[self.viewController webPageOrderedOpen:command];
}
// TODO(crbug.com/906525) : Move WebStateListObserving out of // TODO(crbug.com/906525) : Move WebStateListObserving out of
// BrowserCoordinator. // BrowserCoordinator.
#pragma mark - WebStateListObserving #pragma mark - WebStateListObserving
...@@ -477,6 +493,26 @@ ...@@ -477,6 +493,26 @@
} }
} }
// Installs delegates for self.browserState.
- (void)installDelegatesForBrowserState {
UrlLoadingService* urlLoadingService =
UrlLoadingServiceFactory::GetForBrowserState(self.browserState);
if (urlLoadingService) {
urlLoadingService->SetDelegate(self);
urlLoadingService->SetBrowser(self.browser);
}
}
// Uninstalls delegates for self.browserState.
- (void)uninstallDelegatesForBrowserState {
UrlLoadingService* urlLoadingService =
UrlLoadingServiceFactory::GetForBrowserState(self.browserState);
if (urlLoadingService) {
urlLoadingService->SetDelegate(nil);
urlLoadingService->SetBrowser(nil);
}
}
// Uninstalls delegates for each WebState in WebStateList. // Uninstalls delegates for each WebState in WebStateList.
- (void)uninstallDelegatesForAllWebStates { - (void)uninstallDelegatesForAllWebStates {
for (int i = 0; i < self.tabModel.webStateList->count(); i++) { for (int i = 0; i < self.tabModel.webStateList->count(); i++) {
......
...@@ -11,6 +11,10 @@ source_set("url_loading") { ...@@ -11,6 +11,10 @@ source_set("url_loading") {
"url_loading_notifier_factory.h", "url_loading_notifier_factory.h",
"url_loading_observer_bridge.h", "url_loading_observer_bridge.h",
"url_loading_observer_bridge.mm", "url_loading_observer_bridge.mm",
"url_loading_service.h",
"url_loading_service.mm",
"url_loading_service_factory.h",
"url_loading_service_factory.mm",
"url_loading_util.h", "url_loading_util.h",
"url_loading_util.mm", "url_loading_util.mm",
] ]
...@@ -20,10 +24,12 @@ source_set("url_loading") { ...@@ -20,10 +24,12 @@ source_set("url_loading") {
"//components/sessions", "//components/sessions",
"//ios/chrome/browser", "//ios/chrome/browser",
"//ios/chrome/browser/browser_state", "//ios/chrome/browser/browser_state",
"//ios/chrome/browser/main",
"//ios/chrome/browser/prerender", "//ios/chrome/browser/prerender",
"//ios/chrome/browser/sessions", "//ios/chrome/browser/sessions",
"//ios/chrome/browser/tabs", "//ios/chrome/browser/tabs",
"//ios/chrome/browser/ui", "//ios/chrome/browser/ui",
"//ios/chrome/browser/ui/commands",
"//ios/chrome/browser/web", "//ios/chrome/browser/web",
"//ios/chrome/browser/web_state_list", "//ios/chrome/browser/web_state_list",
"//ios/web/public", "//ios/web/public",
......
...@@ -9,9 +9,6 @@ ...@@ -9,9 +9,6 @@
#include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" #include "ios/chrome/browser/browser_state/browser_state_otr_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/url_loading/url_loading_notifier.h" #include "ios/chrome/browser/url_loading/url_loading_notifier.h"
#include "ios/chrome/browser/url_loading/url_loading_notifier_factory.h"
namespace ios {
// static // static
UrlLoadingNotifier* UrlLoadingNotifierFactory::GetForBrowserState( UrlLoadingNotifier* UrlLoadingNotifierFactory::GetForBrowserState(
...@@ -29,11 +26,7 @@ UrlLoadingNotifierFactory* UrlLoadingNotifierFactory::GetInstance() { ...@@ -29,11 +26,7 @@ UrlLoadingNotifierFactory* UrlLoadingNotifierFactory::GetInstance() {
UrlLoadingNotifierFactory::UrlLoadingNotifierFactory() UrlLoadingNotifierFactory::UrlLoadingNotifierFactory()
: BrowserStateKeyedServiceFactory( : BrowserStateKeyedServiceFactory(
"UrlLoadingNotifier", "UrlLoadingNotifier",
BrowserStateDependencyManager::GetInstance()) { BrowserStateDependencyManager::GetInstance()) {}
// TODO(crbug.com/907527): add when available:
// DependsOn(UrlLoadingServiceFactory::GetInstance());
}
UrlLoadingNotifierFactory::~UrlLoadingNotifierFactory() {} UrlLoadingNotifierFactory::~UrlLoadingNotifierFactory() {}
std::unique_ptr<KeyedService> std::unique_ptr<KeyedService>
...@@ -46,5 +39,3 @@ web::BrowserState* UrlLoadingNotifierFactory::GetBrowserStateToUse( ...@@ -46,5 +39,3 @@ web::BrowserState* UrlLoadingNotifierFactory::GetBrowserStateToUse(
web::BrowserState* context) const { web::BrowserState* context) const {
return GetBrowserStateOwnInstanceInIncognito(context); return GetBrowserStateOwnInstanceInIncognito(context);
} }
} // namespace ios
...@@ -11,11 +11,11 @@ ...@@ -11,11 +11,11 @@
#include "base/no_destructor.h" #include "base/no_destructor.h"
#include "components/keyed_service/ios/browser_state_keyed_service_factory.h" #include "components/keyed_service/ios/browser_state_keyed_service_factory.h"
class UrlLoadingNotifier;
namespace ios { namespace ios {
class ChromeBrowserState; class ChromeBrowserState;
}
class UrlLoadingNotifier;
// Singleton that owns all UrlLoadingNotifiers and associates them with // Singleton that owns all UrlLoadingNotifiers and associates them with
// ios::ChromeBrowserState. // ios::ChromeBrowserState.
...@@ -40,6 +40,4 @@ class UrlLoadingNotifierFactory : public BrowserStateKeyedServiceFactory { ...@@ -40,6 +40,4 @@ class UrlLoadingNotifierFactory : public BrowserStateKeyedServiceFactory {
DISALLOW_COPY_AND_ASSIGN(UrlLoadingNotifierFactory); DISALLOW_COPY_AND_ASSIGN(UrlLoadingNotifierFactory);
}; };
} // namespace ios
#endif // IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_NOTIFIER_FACTORY_H_ #endif // IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_NOTIFIER_FACTORY_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_SERVICE_H_
#define IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_SERVICE_H_
#import <Foundation/Foundation.h>
#include "components/keyed_service/core/keyed_service.h"
#import "ios/chrome/browser/ui/chrome_load_params.h"
#import "ios/web/public/navigation_manager.h"
#include "ui/base/page_transition_types.h"
#include "url/gurl.h"
class Browser;
class UrlLoadingNotifier;
@class OpenNewTabCommand;
// TODO(crbug.com/907527): normalize all parameters to open a url in
// UrlLoadingService and URLLoadingServiceDelegate.
// Objective-C delegate for UrlLoadingService.
@protocol URLLoadingServiceDelegate
// Implementing delegate must switch to a tab that matches |params| or open in a
// new tab.
- (void)switchToTabWithParams:
(const web::NavigationManager::WebLoadParams&)params;
// Implementing delegate must open the url in |command| in a new tab.
- (void)openURLInNewTabWithCommand:(OpenNewTabCommand*)command;
@end
// Observer used to update listeners of change of state in url loading.
class UrlLoadingService : public KeyedService {
public:
UrlLoadingService(UrlLoadingNotifier* notifier);
void SetDelegate(id<URLLoadingServiceDelegate> delegate);
void SetBrowser(Browser* browser);
// Opens a url based on |chrome_params|.
void LoadUrlInCurrentTab(const ChromeLoadParams& chrome_params);
// Switches to a tab that matches |web_params| or opens in a new tab.
void SwitchToTab(const web::NavigationManager::WebLoadParams& web_params);
// Opens a url based on |command| in a new tab.
void OpenUrlInNewTab(OpenNewTabCommand* command);
private:
__weak id<URLLoadingServiceDelegate> delegate_;
Browser* browser_;
UrlLoadingNotifier* notifier_;
};
#endif // IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_SERVICE_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/url_loading/url_loading_service.h"
#import "ios/chrome/browser/main/browser.h"
#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
#import "ios/chrome/browser/url_loading/url_loading_notifier.h"
#import "ios/chrome/browser/url_loading/url_loading_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
UrlLoadingService::UrlLoadingService(UrlLoadingNotifier* notifier)
: notifier_(notifier) {}
void UrlLoadingService::SetDelegate(id<URLLoadingServiceDelegate> delegate) {
delegate_ = delegate;
}
void UrlLoadingService::SetBrowser(Browser* browser) {
browser_ = browser;
}
void UrlLoadingService::LoadUrlInCurrentTab(
const ChromeLoadParams& chrome_params) {
URLLoadResult result = LoadURL(chrome_params, browser_, notifier_);
switch (result) {
case URLLoadResult::SWITCH_TO_TAB: {
SwitchToTab(chrome_params.web_params);
break;
}
case URLLoadResult::DISALLOWED_IN_INCOGNITO: {
OpenNewTabCommand* command =
[[OpenNewTabCommand alloc] initWithURL:chrome_params.web_params.url
referrer:web::Referrer()
inIncognito:NO
inBackground:NO
appendTo:kCurrentTab];
OpenUrlInNewTab(command);
break;
}
case URLLoadResult::INDUCED_CRASH:
case URLLoadResult::LOADED_PRERENDER:
case URLLoadResult::RELOADED:
case URLLoadResult::NORMAL_LOAD:
// Page load was handled, so nothing else to do.
break;
}
}
void UrlLoadingService::SwitchToTab(
const web::NavigationManager::WebLoadParams& web_params) {
DCHECK(delegate_);
// TODO(crbug.com/907527): chip at BVC::switchToTabWithParams by moving some
// of it here.
[delegate_ switchToTabWithParams:web_params];
}
void UrlLoadingService::OpenUrlInNewTab(OpenNewTabCommand* command) {
DCHECK(delegate_);
[delegate_ openURLInNewTabWithCommand:command];
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_SERVICE_FACTORY_H_
#define IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_SERVICE_FACTORY_H_
#include <memory>
#include "base/macros.h"
#include "base/no_destructor.h"
#include "components/keyed_service/ios/browser_state_keyed_service_factory.h"
namespace ios {
class ChromeBrowserState;
}
class UrlLoadingService;
// Singleton that owns all UrlLoadingServices and associates them with
// ios::ChromeBrowserState.
class UrlLoadingServiceFactory : public BrowserStateKeyedServiceFactory {
public:
static UrlLoadingService* GetForBrowserState(
ios::ChromeBrowserState* browser_state);
static UrlLoadingServiceFactory* GetInstance();
private:
friend class base::NoDestructor<UrlLoadingServiceFactory>;
UrlLoadingServiceFactory();
~UrlLoadingServiceFactory() override;
std::unique_ptr<KeyedService> BuildServiceInstanceFor(
web::BrowserState* context) const override;
web::BrowserState* GetBrowserStateToUse(
web::BrowserState* context) const override;
DISALLOW_COPY_AND_ASSIGN(UrlLoadingServiceFactory);
};
#endif // IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_SERVICE_FACTORY_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ios/chrome/browser/url_loading/url_loading_service_factory.h"
#include "base/no_destructor.h"
#include "components/keyed_service/ios/browser_state_dependency_manager.h"
#include "ios/chrome/browser/browser_state/browser_state_otr_helper.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#include "ios/chrome/browser/url_loading/url_loading_notifier_factory.h"
#include "ios/chrome/browser/url_loading/url_loading_service.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
// static
UrlLoadingService* UrlLoadingServiceFactory::GetForBrowserState(
ios::ChromeBrowserState* browser_state) {
return static_cast<UrlLoadingService*>(
GetInstance()->GetServiceForBrowserState(browser_state, true));
}
// static
UrlLoadingServiceFactory* UrlLoadingServiceFactory::GetInstance() {
static base::NoDestructor<UrlLoadingServiceFactory> instance;
return instance.get();
}
UrlLoadingServiceFactory::UrlLoadingServiceFactory()
: BrowserStateKeyedServiceFactory(
"UrlLoadingService",
BrowserStateDependencyManager::GetInstance()) {
DependsOn(UrlLoadingNotifierFactory::GetInstance());
}
UrlLoadingServiceFactory::~UrlLoadingServiceFactory() {}
std::unique_ptr<KeyedService> UrlLoadingServiceFactory::BuildServiceInstanceFor(
web::BrowserState* context) const {
ios::ChromeBrowserState* browser_state =
ios::ChromeBrowserState::FromBrowserState(context);
return std::make_unique<UrlLoadingService>(
UrlLoadingNotifierFactory::GetForBrowserState(browser_state));
}
web::BrowserState* UrlLoadingServiceFactory::GetBrowserStateToUse(
web::BrowserState* context) const {
return GetBrowserStateOwnInstanceInIncognito(context);
}
...@@ -19,7 +19,8 @@ class ChromeBrowserState; ...@@ -19,7 +19,8 @@ class ChromeBrowserState;
namespace web { namespace web {
class WebState; class WebState;
} }
class WebStateList; class Browser;
class UrlLoadingNotifier;
// Possible results from calling LoadURL(). // Possible results from calling LoadURL().
enum class URLLoadResult { enum class URLLoadResult {
...@@ -60,12 +61,11 @@ void RestoreTab(const SessionID session_id, ...@@ -60,12 +61,11 @@ void RestoreTab(const SessionID session_id,
ios::ChromeBrowserState* browser_state); ios::ChromeBrowserState* browser_state);
// Returns the result (as defined in the enum definition above) of initiating a // Returns the result (as defined in the enum definition above) of initiating a
// URL load as defined in |chrome_params|, using |browser_state| and the active // URL load as defined in |chrome_params|.
// webState in |web_state_list|. |restorer| is provied for dependencies which // TODO(crbug.com/907527): hoist into url_loading_service and remove
// may need to save the current session window. // URLLoadResult.
URLLoadResult LoadURL(const ChromeLoadParams& chrome_params, URLLoadResult LoadURL(const ChromeLoadParams& chrome_params,
ios::ChromeBrowserState* browser_state, Browser* browser,
WebStateList* web_state_list, UrlLoadingNotifier* notifier);
id<SessionWindowRestoring> restorer);
#endif // IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_UTIL_H_ #endif // IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_UTIL_H_
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#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"
...@@ -93,20 +94,17 @@ void RestoreTab(const SessionID session_id, ...@@ -93,20 +94,17 @@ void RestoreTab(const SessionID session_id,
restoreService->RestoreEntryById(delegate, session_id, disposition); restoreService->RestoreEntryById(delegate, session_id, disposition);
} }
// TODO(crbug.com/907527): make this into a url loading service in this folder.
URLLoadResult LoadURL(const ChromeLoadParams& chrome_params, URLLoadResult LoadURL(const ChromeLoadParams& chrome_params,
ios::ChromeBrowserState* browser_state, Browser* browser,
WebStateList* web_state_list, UrlLoadingNotifier* notifier) {
id<SessionWindowRestoring> restorer) {
web::NavigationManager::WebLoadParams params = chrome_params.web_params; web::NavigationManager::WebLoadParams params = chrome_params.web_params;
if (chrome_params.disposition == WindowOpenDisposition::SWITCH_TO_TAB) { if (chrome_params.disposition == WindowOpenDisposition::SWITCH_TO_TAB) {
return URLLoadResult::SWITCH_TO_TAB; return URLLoadResult::SWITCH_TO_TAB;
} }
UrlLoadingNotifier* urlLoadingNotifier = ios::ChromeBrowserState* browser_state = browser->GetBrowserState();
ios::UrlLoadingNotifierFactory::GetForBrowserState(browser_state);
urlLoadingNotifier->TabWillOpenUrl(params.url, params.transition_type); notifier->TabWillOpenUrl(params.url, params.transition_type);
// NOTE: This check for the Crash Host URL is here to avoid the URL from // 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 // ending up in the history causing the app to crash at every subsequent
...@@ -115,7 +113,7 @@ URLLoadResult LoadURL(const ChromeLoadParams& chrome_params, ...@@ -115,7 +113,7 @@ URLLoadResult LoadURL(const ChromeLoadParams& chrome_params,
InduceBrowserCrash(params.url); InduceBrowserCrash(params.url);
// Under a debugger, the app can continue working even after the CHECK. // Under a debugger, the app can continue working even after the CHECK.
// Adding a return avoids adding the crash url to history. // Adding a return avoids adding the crash url to history.
urlLoadingNotifier->TabFailedToOpenUrl(params.url, params.transition_type); notifier->TabFailedToOpenUrl(params.url, params.transition_type);
return URLLoadResult::INDUCED_CRASH; return URLLoadResult::INDUCED_CRASH;
} }
...@@ -123,17 +121,20 @@ URLLoadResult LoadURL(const ChromeLoadParams& chrome_params, ...@@ -123,17 +121,20 @@ URLLoadResult LoadURL(const ChromeLoadParams& chrome_params,
// so. // so.
PrerenderService* prerenderService = PrerenderService* prerenderService =
PrerenderServiceFactory::GetForBrowserState(browser_state); PrerenderServiceFactory::GetForBrowserState(browser_state);
WebStateList* web_state_list = browser->GetWebStateList();
id<SessionWindowRestoring> restorer =
(id<SessionWindowRestoring>)browser->GetTabModel();
if (prerenderService && if (prerenderService &&
prerenderService->MaybeLoadPrerenderedURL( prerenderService->MaybeLoadPrerenderedURL(
params.url, params.transition_type, web_state_list, restorer)) { params.url, params.transition_type, web_state_list, restorer)) {
urlLoadingNotifier->TabDidPrerenderUrl(params.url, params.transition_type); notifier->TabDidPrerenderUrl(params.url, params.transition_type);
return URLLoadResult::LOADED_PRERENDER; return URLLoadResult::LOADED_PRERENDER;
} }
// Some URLs are not allowed while in incognito. If we are in incognito and // 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. // load a disallowed URL, instead create a new tab not in the incognito state.
if (browser_state->IsOffTheRecord() && !IsURLAllowedInIncognito(params.url)) { if (browser_state->IsOffTheRecord() && !IsURLAllowedInIncognito(params.url)) {
urlLoadingNotifier->TabFailedToOpenUrl(params.url, params.transition_type); notifier->TabFailedToOpenUrl(params.url, params.transition_type);
return URLLoadResult::DISALLOWED_IN_INCOGNITO; return URLLoadResult::DISALLOWED_IN_INCOGNITO;
} }
...@@ -156,13 +157,13 @@ URLLoadResult LoadURL(const ChromeLoadParams& chrome_params, ...@@ -156,13 +157,13 @@ URLLoadResult LoadURL(const ChromeLoadParams& chrome_params,
ui::PAGE_TRANSITION_RELOAD)) { ui::PAGE_TRANSITION_RELOAD)) {
current_web_state->GetNavigationManager()->Reload( current_web_state->GetNavigationManager()->Reload(
web::ReloadType::NORMAL, true /* check_for_repost */); web::ReloadType::NORMAL, true /* check_for_repost */);
urlLoadingNotifier->TabDidReloadUrl(params.url, params.transition_type); notifier->TabDidReloadUrl(params.url, params.transition_type);
return URLLoadResult::RELOADED; return URLLoadResult::RELOADED;
} }
current_web_state->GetNavigationManager()->LoadURLWithParams(params); current_web_state->GetNavigationManager()->LoadURLWithParams(params);
urlLoadingNotifier->TabDidOpenUrl(params.url, params.transition_type); notifier->TabDidOpenUrl(params.url, params.transition_type);
return URLLoadResult::NORMAL_LOAD; 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