blob: 79a73bcebde6ea42f6d709be3a4f9a30e02543ee [file] [log] [blame]
// Copyright 2019 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/main/model/browser_agent_util.h"
#import "base/check_op.h"
#import "base/feature_list.h"
#import "components/breadcrumbs/core/breadcrumbs_status.h"
#import "ios/chrome/browser/app_launcher/model/app_launcher_browser_agent.h"
#import "ios/chrome/browser/browser_view/model/browser_view_visibility_notifier_browser_agent.h"
#import "ios/chrome/browser/bubble/model/tab_based_iph_browser_agent.h"
#import "ios/chrome/browser/crash_report/model/breadcrumbs/breadcrumb_manager_browser_agent.h"
#import "ios/chrome/browser/credential_provider/model/credential_provider_buildflags.h"
#import "ios/chrome/browser/device_sharing/model/device_sharing_browser_agent.h"
#import "ios/chrome/browser/discover_feed/model/discover_feed_visibility_browser_agent.h"
#import "ios/chrome/browser/favicon/model/favicon_browser_agent.h"
#import "ios/chrome/browser/follow/model/follow_browser_agent.h"
#import "ios/chrome/browser/fullscreen/ui_bundled/fullscreen_controller.h"
#import "ios/chrome/browser/infobars/model/overlays/browser_agent/infobar_overlay_browser_agent_util.h"
#import "ios/chrome/browser/intelligence/bwg/model/bwg_browser_agent.h"
#import "ios/chrome/browser/intelligence/features/features.h"
#import "ios/chrome/browser/intents/model/user_activity_browser_agent.h"
#import "ios/chrome/browser/lens/model/lens_browser_agent.h"
#import "ios/chrome/browser/metrics/model/tab_usage_recorder_browser_agent.h"
#import "ios/chrome/browser/metrics/model/web_state_list_metrics_browser_agent.h"
#import "ios/chrome/browser/omnibox/model/omnibox_position/omnibox_position_browser_agent.h"
#import "ios/chrome/browser/policy/model/policy_watcher_browser_agent.h"
#import "ios/chrome/browser/reader_mode/model/features.h"
#import "ios/chrome/browser/reader_mode/model/reader_mode_browser_agent.h"
#import "ios/chrome/browser/reading_list/model/reading_list_browser_agent.h"
#import "ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent.h"
#import "ios/chrome/browser/sessions/model/ios_chrome_tab_restore_browser_agent.h"
#import "ios/chrome/browser/sessions/model/live_tab_context_browser_agent.h"
#import "ios/chrome/browser/shared/model/application_context/application_context.h"
#import "ios/chrome/browser/shared/model/profile/profile_ios.h"
#import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
#import "ios/chrome/browser/shared/public/commands/reader_mode_commands.h"
#import "ios/chrome/browser/shared/public/features/features.h"
#import "ios/chrome/browser/snapshots/model/snapshot_browser_agent.h"
#import "ios/chrome/browser/start_surface/ui_bundled/start_surface_recent_tab_browser_agent.h"
#import "ios/chrome/browser/sync/model/sync_error_browser_agent.h"
#import "ios/chrome/browser/tab_insertion/model/tab_insertion_browser_agent.h"
#import "ios/chrome/browser/tabs/model/synced_window_delegate_browser_agent.h"
#import "ios/chrome/browser/url_loading/model/url_loading_browser_agent.h"
#import "ios/chrome/browser/url_loading/model/url_loading_notifier_browser_agent.h"
#import "ios/chrome/browser/view_source/model/view_source_browser_agent.h"
#import "ios/chrome/browser/web/model/page_placeholder_browser_agent.h"
#import "ios/chrome/browser/web/model/web_navigation_browser_agent.h"
#import "ios/chrome/browser/web/model/web_state_delegate_browser_agent.h"
#import "ios/chrome/browser/web/model/web_state_update_browser_agent.h"
#import "ios/chrome/browser/web_state_list/model/session_metrics.h"
#import "ios/chrome/browser/web_state_list/model/web_usage_enabler/web_usage_enabler_browser_agent.h"
#import "ios/public/provider/chrome/browser/app_utils/app_utils_api.h"
#if BUILDFLAG(IOS_CREDENTIAL_PROVIDER_ENABLED)
#import "ios/chrome/browser/credential_provider/model/credential_provider_browser_agent.h"
#endif
namespace {
// Feature controlling for which Browser to create agents.
BASE_FEATURE(kLimitBrowserAgentsForInactiveBrowser,
"LimitBrowserAgentsForInactiveBrowser",
base::FEATURE_DISABLED_BY_DEFAULT);
// Attach agents for a regular, incognito or inactive Browser.
void AttachBrowserAgentsForInactiveBrowser(Browser* browser) {
if (base::FeatureList::IsEnabled(kLimitBrowserAgentsForInactiveBrowser)) {
CHECK_NE(Browser::Type::kTemporary, browser->type());
}
// DO NOT ADD NEW BROWSER AGENTS HERE.
//
// Add new agents to AttachBrowserAgentsForActiveBrowser(...) instead.
SnapshotBrowserAgent::CreateForBrowser(browser);
SyncedWindowDelegateBrowserAgent::CreateForBrowser(browser);
WebUsageEnablerBrowserAgent::CreateForBrowser(browser);
if (breadcrumbs::IsEnabled(GetApplicationContext()->GetLocalState())) {
BreadcrumbManagerBrowserAgent::CreateForBrowser(browser);
}
}
// Attach agents for a regular or incognito Browser.
void AttachBrowserAgentsForActiveBrowser(Browser* browser) {
if (base::FeatureList::IsEnabled(kLimitBrowserAgentsForInactiveBrowser)) {
CHECK_NE(Browser::Type::kTemporary, browser->type());
CHECK_NE(Browser::Type::kInactive, browser->type());
}
// TODO(crbug.com/433229469): Once kLimitBrowserAgentsForInactiveBrowser is
// fully launched the variables browser_is_inactive and browser_is_temporary
// can be removed as they will always be false. Cleanup the variables and
// their use when the feature launch.
const bool browser_is_off_record = browser->GetProfile()->IsOffTheRecord();
const bool browser_is_inactive = browser->IsInactive();
const bool browser_is_temporary =
browser->type() == Browser::Type::kTemporary;
LiveTabContextBrowserAgent::CreateForBrowser(browser);
TabInsertionBrowserAgent::CreateForBrowser(browser);
AttachInfobarOverlayBrowserAgent(browser);
DeviceSharingBrowserAgent::CreateForBrowser(browser);
UrlLoadingNotifierBrowserAgent::CreateForBrowser(browser);
AppLauncherBrowserAgent::CreateForBrowser(browser);
OmniboxPositionBrowserAgent::CreateForBrowser(browser);
// Only create the FullscreenBrowserAgent and ReaderModeBrowserAgent for
// regular and incognito Browser (since the other Browser do not present the
// WebStates, and may not create the tab helpers which would lead to crashes).
if (!browser_is_inactive && !browser_is_temporary) {
FullscreenController::CreateForBrowser(browser);
if (IsReaderModeAvailable()) {
ReaderModeBrowserAgent::CreateForBrowser(browser);
}
}
// LensBrowserAgent must be created before WebNavigationBrowserAgent.
LensBrowserAgent::CreateForBrowser(browser);
WebNavigationBrowserAgent::CreateForBrowser(browser);
if (!browser_is_off_record) {
IOSChromeTabRestoreBrowserAgent::CreateForBrowser(browser);
}
if (IsWebChannelsEnabled() && !browser_is_off_record) {
FollowBrowserAgent::CreateForBrowser(browser);
}
// PolicyWatcher is non-OTR only.
if (!browser_is_off_record) {
PolicyWatcherBrowserAgent::CreateForBrowser(browser);
}
// Send Tab To Self is non-OTR only.
if (!browser_is_off_record) {
SendTabToSelfBrowserAgent::CreateForBrowser(browser);
}
WebStateDelegateBrowserAgent::CreateForBrowser(
browser, TabInsertionBrowserAgent::FromBrowser(browser));
// ViewSourceBrowserAgent requires TabInsertionBrowserAgent, and is only used
// in debug builds.
#if !defined(NDEBUG)
ViewSourceBrowserAgent::CreateForBrowser(browser);
#endif // !defined(NDEBUG)
// UrlLoadingBrowserAgent requires UrlLoadingNotifierBrowserAgent.
UrlLoadingBrowserAgent::CreateForBrowser(browser);
WebStateListMetricsBrowserAgent::CreateForBrowser(
browser, SessionMetrics::FromProfile(browser->GetProfile()));
// Normal profiles are the only ones to get tab usage recorder.
if (!browser_is_off_record) {
TabUsageRecorderBrowserAgent::CreateForBrowser(browser);
}
if (!browser_is_off_record) {
StartSurfaceRecentTabBrowserAgent::CreateForBrowser(browser);
}
if (!browser_is_inactive) {
SyncErrorBrowserAgent::CreateForBrowser(browser);
}
WebStateUpdateBrowserAgent::CreateForBrowser(browser);
ReadingListBrowserAgent::CreateForBrowser(browser);
PagePlaceholderBrowserAgent::CreateForBrowser(browser);
FaviconBrowserAgent::CreateForBrowser(browser);
UserActivityBrowserAgent::CreateForBrowser(browser);
if (!browser_is_inactive) {
BrowserViewVisibilityNotifierBrowserAgent::CreateForBrowser(browser);
TabBasedIPHBrowserAgent::CreateForBrowser(browser);
}
if (!browser_is_off_record && !browser_is_inactive) {
DiscoverFeedVisibilityBrowserAgent::CreateForBrowser(browser);
}
#if BUILDFLAG(IOS_CREDENTIAL_PROVIDER_ENABLED)
CredentialProviderBrowserAgent::CreateForBrowser(browser);
#endif
if (!browser_is_off_record && IsPageActionMenuEnabled()) {
BwgBrowserAgent::CreateForBrowser(browser);
}
// This needs to be called last in case any downstream browser agents need to
// access upstream agents created earlier in this function.
ios::provider::AttachBrowserAgents(browser);
}
} // anonymous namespace
void AttachBrowserAgents(Browser* browser) {
// If the feature is not enabled, treat all Browser identically.
if (!base::FeatureList::IsEnabled(kLimitBrowserAgentsForInactiveBrowser)) {
AttachBrowserAgentsForInactiveBrowser(browser);
AttachBrowserAgentsForActiveBrowser(browser);
return;
}
switch (browser->type()) {
case Browser::Type::kRegular:
case Browser::Type::kIncognito:
// Attach all browser agents for regular and incognito Browsers.
AttachBrowserAgentsForInactiveBrowser(browser);
AttachBrowserAgentsForActiveBrowser(browser);
break;
case Browser::Type::kInactive:
// Attach only limited selection of browser agents for inactive
// Browsers.
AttachBrowserAgentsForInactiveBrowser(browser);
break;
case Browser::Type::kTemporary:
// Do not attach any browser agents for tempory Browsers.
break;
}
}