blob: 163066abe5d819a28396adefec8e0e709ba0d614 [file] [log] [blame]
// Copyright 2022 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/chrome/browser/ui/omnibox/zero_suggest_prefetch_helper.h"
#import "base/feature_list.h"
#import "components/omnibox/browser/autocomplete_controller.h"
#import "components/omnibox/browser/autocomplete_input.h"
#import "components/omnibox/common/omnibox_features.h"
#import "ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h"
#import "ios/chrome/browser/url/chrome_url_constants.h"
#import "ios/chrome/browser/web_state_list/active_web_state_observation_forwarder.h"
#import "ios/chrome/browser/web_state_list/web_state_list.h"
#import "ios/web/public/web_state.h"
#import "ios/web/public/web_state_observer_bridge.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
using web::WebState;
using web::WebStateObserverBridge;
@interface ZeroSuggestPrefetchHelper () <CRWWebStateObserver>
@end
@implementation ZeroSuggestPrefetchHelper {
/// Bridge to receive active web state events
std::unique_ptr<ActiveWebStateObservationForwarder>
_activeWebStateObservationForwarder;
/// Bridge to receive WS events for the active web state.
std::unique_ptr<WebStateObserverBridge> _webStateObserverBridge;
}
- (void)dealloc {
/// Reset the web state observation forwarder, which will remove
/// `_webStateObserverBridge` from the relevant observer list.
_activeWebStateObservationForwarder.reset();
}
- (instancetype)initWithWebStateList:(WebStateList*)webStateList
autocompleteController:
(AutocompleteController*)autocompleteController {
self = [super init];
if (self) {
DCHECK(webStateList);
DCHECK(autocompleteController);
DCHECK(base::FeatureList::IsEnabled(omnibox::kZeroSuggestPrefetching));
_webStateList = webStateList;
_autocompleteController = autocompleteController;
_webStateObserverBridge = std::make_unique<WebStateObserverBridge>(self);
_activeWebStateObservationForwarder =
std::make_unique<ActiveWebStateObservationForwarder>(
webStateList, _webStateObserverBridge.get());
[self startPrefetchIfNecessary];
}
return self;
}
#pragma mark - CRWWebStateObserver
- (void)webStateWasShown:(web::WebState*)webState {
[self startPrefetchIfNecessary];
}
- (void)webState:(web::WebState*)webState
didFinishNavigation:(web::NavigationContext*)navigationContext {
[self startPrefetchIfNecessary];
}
#pragma mark - private
+ (BOOL)isNTPURL:(GURL)url {
return url == kChromeUINewTabURL || url == kChromeUIAboutNewTabURL;
}
/// Start prefetching if the active web state is displaying an NTP.
- (void)startPrefetchIfNecessary {
WebState* activeWebState = _webStateList->GetActiveWebState();
if (activeWebState == nullptr ||
![ZeroSuggestPrefetchHelper
isNTPURL:activeWebState->GetLastCommittedURL()]) {
return;
}
AutocompleteInput autocomplete_input(
u"", metrics::OmniboxEventProto::NTP_ZPS_PREFETCH,
AutocompleteSchemeClassifierImpl());
autocomplete_input.set_focus_type(
metrics::OmniboxFocusType::INTERACTION_FOCUS);
self.autocompleteController->StartPrefetch(autocomplete_input);
}
@end