blob: 5190e45a5a5c23f5c758e31cfbfb90b757bb2e63 [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/omnibox_edit_model.h"
#import "ios/chrome/browser/shared/model/web_state_list/active_web_state_observation_forwarder.h"
#import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
#import "ios/chrome/browser/shared/model/web_state_list/web_state_list_observer_bridge.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,
WebStateListObserving>
@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;
/// Bridge to receive WSL events.
std::unique_ptr<WebStateListObserverBridge> _webStateListObserverBridge;
}
- (void)dealloc {
/// Reset the web state observation forwarder, which will remove
/// `_webStateObserverBridge` from the relevant observer list.
_activeWebStateObservationForwarder.reset();
if (_webStateList) {
_webStateList->RemoveObserver(_webStateListObserverBridge.get());
_webStateListObserverBridge.reset();
_webStateList = nullptr;
}
}
- (instancetype)initWithWebStateList:(WebStateList*)webStateList
editModel:(OmniboxEditModel*)editModel {
self = [super init];
if (self) {
DCHECK(webStateList);
DCHECK(editModel);
_webStateList = webStateList;
_editModel = editModel;
_webStateObserverBridge = std::make_unique<WebStateObserverBridge>(self);
_activeWebStateObservationForwarder =
std::make_unique<ActiveWebStateObservationForwarder>(
webStateList, _webStateObserverBridge.get());
_webStateListObserverBridge =
std::make_unique<WebStateListObserverBridge>(self);
_webStateList->AddObserver(_webStateListObserverBridge.get());
[self startPrefetchIfNecessary];
}
return self;
}
#pragma mark - CRWWebStateObserver
- (void)webState:(web::WebState*)webState
didFinishNavigation:(web::NavigationContext*)navigationContext {
[self startPrefetchIfNecessary];
}
#pragma mark - WebStateListObserving
- (void)webStateList:(WebStateList*)webStateList
didChangeActiveWebState:(web::WebState*)newWebState
oldWebState:(web::WebState*)oldWebState
atIndex:(int)atIndex
reason:(ActiveWebStateChangeReason)reason {
if (newWebState) {
[self startPrefetchIfNecessary];
}
}
#pragma mark - private
/// Tell edit model to start prefetching whenever there's an active web state.
/// The prefetching is expected on navigation, tab switch, and page reload.
- (void)startPrefetchIfNecessary {
WebState* activeWebState = _webStateList->GetActiveWebState();
if (activeWebState == nullptr) {
return;
}
self.editModel->StartPrefetch();
}
@end