blob: 807f9986c7f9cd668d8aa1c43e23f60e2493fedc [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_BROWSER_WINDOW_PUBLIC_BROWSER_WINDOW_INTERFACE_H_
#define CHROME_BROWSER_UI_BROWSER_WINDOW_PUBLIC_BROWSER_WINDOW_INTERFACE_H_
#include <vector>
#include "base/memory/raw_ptr.h"
#include "build/build_config.h"
#include "content/public/browser/page_navigator.h"
#if !BUILDFLAG(IS_ANDROID)
#include "base/callback_list.h"
#include "ui/base/window_open_disposition.h"
#endif
// This is the public interface for a browser window. Most features in
// //chrome/browser depend on this interface, and thus to prevent circular
// dependencies this interface should not depend on anything else in //chrome.
// Ping erikchen for assistance if this class does not have the functionality
// your feature needs. This comment will be deleted after there are 10+ features
// in BrowserWindowFeatures.
//
// This interface is shared between desktop platforms and the experimental
// desktop android platform. As such, the features exposed directly on this
// class should only be those that apply to all these platforms, and should only
// be features that are core to the concept of a browser window. Classes related
// to specific features should likely instead be stored either as an entry in
// the UnownedUserData (via BrowserWindowInterface::GetUnownedUserDataHost())
// or on DesktopBrowserWindowCapabilities.
#if !BUILDFLAG(IS_ANDROID)
namespace tabs {
class TabInterface;
} // namespace tabs
namespace views {
class WebView;
class View;
} // namespace views
namespace web_app {
class AppBrowserController;
} // namespace web_app
namespace web_modal {
class WebContentsModalDialogHost;
} // namespace web_modal
class Browser;
class BrowserActions;
class BrowserWindowFeatures;
class DesktopBrowserWindowCapabilities;
class ExclusiveAccessManager;
class GURL;
class ImmersiveModeController;
class TabStripModel;
#endif // BUILDFLAG(IS_ANDROID)
namespace ui {
class BaseWindow;
class UnownedUserDataHost;
} // namespace ui
class Profile;
class SessionID;
#if !BUILDFLAG(IS_ANDROID)
// A feature which wants to show window level call to action UI should call
// BrowserWindowInterface::ShowCallToAction and keep alive the instance of
// ScopedWindowCallToAction for the duration of the window-modal UI.
class ScopedWindowCallToAction {
public:
ScopedWindowCallToAction() = default;
virtual ~ScopedWindowCallToAction() = default;
};
#endif // !BUILDFLAG(IS_ANDROID)
class BrowserWindowInterface : public content::PageNavigator {
public:
// TODO(crbug.com/421758609): Hoist other enums above method declarations.
enum class ClosingStatus {
kPermitted,
kDeniedByUser,
kDeniedByPolicy,
kDeniedUnloadHandlersNeedTime
};
// Returns the UnownedUserDataHost associated with this browser window. This
// is used to retrieve arbitrary features from the browser window without
// requiring BrowserWindowInterface to have knowledge of them.
virtual ui::UnownedUserDataHost& GetUnownedUserDataHost() = 0;
virtual const ui::UnownedUserDataHost& GetUnownedUserDataHost() const = 0;
// Returns the ui::BaseWindow for this browser window. This allows for
// generic window actions, such as activation, querying minimize/maximized
// state, etc.
virtual ui::BaseWindow* GetWindow() = 0;
virtual const ui::BaseWindow* GetWindow() const = 0;
// Returns the profile that semantically owns this browser window.
// On most desktop platforms, there is only one profile per browser window.
// This will never be null and never changes for the lifetime of a given
// browser window. All tabs contained in a browser window have the same
// Profile / BrowserContext as the browser window itself.
// On mobile platforms, this is not the case -- browser windows may have
// multiple profiles. Since this is currently not needed on mobile platforms,
// this is okay.
// On the experimental desktop android platform, we are adapting the mobile
// version to have the same guarantees as existing desktop platforms. Thus,
// when implemented, this will return a single Profile for the given browser
// window.
virtual Profile* GetProfile() = 0;
virtual const Profile* GetProfile() const = 0;
// Returns a session-unique ID.
virtual const SessionID& GetSessionID() const = 0;
// SessionService::WindowType mirrors these values. If you add to this
// enum, look at SessionService::WindowType to see if it needs to be
// updated.
//
// TODO(https://crbug.com/331031753): Several of these existing Window Types
// likely should not have been using Browser as a base to begin with and
// should be migrated. Other types are not available on all platforms.
// Please refrain from adding new types.
//
// GENERATED_JAVA_ENUM_PACKAGE: (
// org.chromium.chrome.browser.ui.browser_window)
// GENERATED_JAVA_CLASS_NAME_OVERRIDE: BrowserWindowType
// GENERATED_JAVA_PREFIX_TO_STRIP: TYPE_
enum Type {
// Normal tabbed non-app browser (previously TYPE_TABBED).
TYPE_NORMAL,
// Popup browser.
TYPE_POPUP,
// App browser. Specifically, one of these:
// * Web app; comes in different flavors but is backed by the same code:
// - Progressive Web App (PWA)
// - Shortcut app (from 3-dot menu > More tools > Create shortcut)
// - System web app (Chrome OS only)
// * Legacy packaged app ("v1 packaged app")
// * Hosted app (e.g. the Web Store "app" preinstalled on Chromebooks)
TYPE_APP,
#if !BUILDFLAG(IS_ANDROID)
// Devtools browser.
TYPE_DEVTOOLS,
#endif
// App popup browser. It behaves like an app browser (e.g. it should have an
// AppBrowserController) but looks like a popup (e.g. it never has a tab
// strip).
TYPE_APP_POPUP,
#if BUILDFLAG(IS_CHROMEOS)
// Browser for ARC++ Chrome custom tabs.
// It's an enhanced version of TYPE_POPUP, and is used to show the Chrome
// Custom Tab toolbar for ARC++ apps. It has UI customizations like using
// the Android app's theme color, and the three dot menu in
// CustomTabToolbarview.
TYPE_CUSTOM_TAB,
#endif
#if !BUILDFLAG(IS_ANDROID)
// Document picture-in-picture browser. It's mostly the same as a
// TYPE_POPUP, except that it floats above other windows. It also has some
// additional restrictions, like it cannot navigated, to prevent misuse.
TYPE_PICTURE_IN_PICTURE,
#endif
// If you add a new type, consider updating the test
// BrowserTest.StartMaximized.
};
virtual Type GetType() const = 0;
// Represents the result of a check for whether a new browser window can be
// created. See also CreateBrowserWindow().
// TODO(devlin): The naming here implies that this is the *result* of a
// creation request, but this is only used to indicate *whether* a new request
// is allowed. Tweak to "CreationAllowed" or similar?
enum class CreationStatus {
// A new browser window can be created.
kOk,
// Indicates that the browser is shutting down.
// TODO(devlin): Why not call this kErrorShuttingDown? That's more clear.
kErrorNoProcess,
// Indicates the profile is unsuitable for a new window. This can happen for
// profiles that don't allow new windows, like certain incognito profiles or
// other special profiles (signin screen, etc).
kErrorProfileUnsuitable,
// TODO(devlin): Update this to be BUILDFLAG(IS_CHROMEOS). That's the only
// spot we have kiosk mode.
#if !BUILDFLAG(IS_ANDROID)
// Indicates the profile is currently loading kiosk mode, so no new windows
// should be allowed.
kErrorLoadingKiosk,
#endif
};
// S T O P
// Please do not add new features here without consulting desktop leads
// (erikchen@) and Clank leads (twellington@, dtrainor@). See comment at the
// top of this file.
// The following methods will be removed in the future.
#if !BUILDFLAG(IS_ANDROID)
// Returns nullptr if no browser window with the given session ID exists.
static BrowserWindowInterface* FromSessionID(const SessionID& session_id);
// The contents of the active tab is rendered in a views::WebView. When the
// active tab switches, the contents of the views::WebView is modified, but
// the instance itself remains the same.
virtual views::WebView* GetWebView() = 0;
// Opens a URL, with the given disposition. This is a convenience wrapper
// around OpenURL from content::PageNavigator.
virtual void OpenGURL(const GURL& gurl,
WindowOpenDisposition disposition) = 0;
virtual TabStripModel* GetTabStripModel() = 0;
virtual const TabStripModel* GetTabStripModel() const = 0;
// Returns true if the tab strip is currently visible for this browser window.
// Will return false on browser initialization before the tab strip is
// initialized.
virtual bool IsTabStripVisible() = 0;
// Returns true if the browser controls are hidden due to being in fullscreen.
virtual bool ShouldHideUIForFullscreen() const = 0;
// Register callbacks invoked when browser has successfully processed its
// close request and has been scheduled for deletion.
using BrowserDidCloseCallback =
base::RepeatingCallback<void(BrowserWindowInterface*)>;
virtual base::CallbackListSubscription RegisterBrowserDidClose(
BrowserDidCloseCallback callback) = 0;
// Register callbacks invoked when browser attempted to close but the close
// operation was cancelled.
using BrowserCloseCancelledCallback =
base::RepeatingCallback<void(BrowserWindowInterface*, ClosingStatus)>;
virtual base::CallbackListSubscription RegisterBrowserCloseCancelled(
BrowserCloseCancelledCallback callback) = 0;
// Returns the top container view.
virtual views::View* TopContainer() = 0;
// WARNING: Many uses of base::WeakPtr are inappropriate and lead to bugs.
// An appropriate use case is as a variable passed to an asynchronously
// invoked PostTask.
// An inappropriate use case is to store as a member of an object that can
// outlive BrowserWindowInterface. This leads to inconsistent state machines.
// For example (don't do this):
// class FooOutlivesBrowser {
// base::WeakPtr<BrowserWindowInterface> bwi_;
// // Conceptually, this member should only be set if bwi_ is set.
// std::optional<SkColor> color_of_browser_;
// };
// For example (do this):
// class FooOutlivesBrowser {
// // Use RegisterBrowserDidClose() to clear both bwi_ and
// // color_of_browser_ prior to bwi_ destruction.
// raw_ptr<BrowserWindowInterface> bwi_;
// std::optional<SkColor> color_of_browser_;
// };
virtual base::WeakPtr<BrowserWindowInterface> GetWeakPtr() = 0;
// Returns the view that houses the Lens overlay.
virtual views::View* LensOverlayView() = 0;
using ActiveTabChangeCallback =
base::RepeatingCallback<void(BrowserWindowInterface*)>;
virtual base::CallbackListSubscription RegisterActiveTabDidChange(
ActiveTabChangeCallback callback) = 0;
// Returns the foreground tab. This can be nullptr very early during
// BrowserWindow initialization, and very late during BrowserWindow teardown.
virtual tabs::TabInterface* GetActiveTabInterface() = 0;
// Returns the feature controllers scoped to this browser window.
// BrowserWindowFeatures that depend on other BrowserWindowFeatures should not
// use this method. Instead they should use use dependency injection to pass
// dependencies at construction or initialization. This method exists for
// three purposes:
// (1) TabFeatures often depend on state of BrowserWindowFeatures for the
// attached window, which can change. TabFeatures need a way to dynamically
// fetch BrowserWindowFeatures.
// (2) To expose BrowserWindowFeatures for tests.
// (3) It is not possible to perform dependency injection for legacy code
// that is conceptually a BrowserWindowFeature and needs access to other
// BrowserWindowFeature.
virtual BrowserWindowFeatures& GetFeatures() = 0;
virtual const BrowserWindowFeatures& GetFeatures() const = 0;
// Returns the web contents modal dialog host pertaining to this
// BrowserWindow.
virtual web_modal::WebContentsModalDialogHost*
GetWebContentsModalDialogHostForWindow() = 0;
// Returns the web contents modal dialog host for the `tab_interface`.
virtual web_modal::WebContentsModalDialogHost*
GetWebContentsModalDialogHostForTab(tabs::TabInterface* tab_interface) = 0;
// Whether the window is active.
// The definition of "active" aligns with the window being painted as active
// instead of the top level widget having focus.
// Note that this does not work correctly for mac PWA windows, as those are
// hosted in a separate application with a stub in the browser process.
virtual bool IsActive() const = 0;
// Register for these two callbacks to detect changes to IsActive().
using DidBecomeActiveCallback =
base::RepeatingCallback<void(BrowserWindowInterface*)>;
virtual base::CallbackListSubscription RegisterDidBecomeActive(
DidBecomeActiveCallback callback) = 0;
using DidBecomeInactiveCallback =
base::RepeatingCallback<void(BrowserWindowInterface*)>;
virtual base::CallbackListSubscription RegisterDidBecomeInactive(
DidBecomeInactiveCallback callback) = 0;
// This class is responsible for controlling fullscreen and pointer lock.
virtual ExclusiveAccessManager* GetExclusiveAccessManager() = 0;
// This class is responsible for controlling the top chrome reveal state while
// in immersive fullscreen.
virtual ImmersiveModeController* GetImmersiveModeController() = 0;
// This class manages actions that a user can take that are scoped to a
// browser window (e.g. most of the 3-dot menu actions).
virtual BrowserActions* GetActions() = 0;
virtual web_app::AppBrowserController* GetAppBrowserController() = 0;
virtual const web_app::AppBrowserController* GetAppBrowserController()
const = 0;
// This is used by features that need to operate on most or all tabs in the
// browser window. Do not use this method to find a specific tab.
virtual std::vector<tabs::TabInterface*> GetAllTabInterfaces() = 0;
// Downcasts to a Browser*. The only valid use for this method is when
// migrating a large chunk of code to BrowserWindowInterface, to allow
// incremental migration.
virtual Browser* GetBrowserForMigrationOnly() = 0;
// Checks if the browser popup is tab modal dialog.
virtual bool IsTabModalPopupDeprecated() const = 0;
// Features that want to show a window level call to action UI can be mutually
// exclusive. Before gating on call to action UI first check
// `CanShowModCanShowCallToActionalUI`. Then call ShowCallToAction() and keep
// `ScopedWindowCallToAction` alive to prevent other features from showing
// window level call to action Uis.
virtual bool CanShowCallToAction() const = 0;
virtual std::unique_ptr<ScopedWindowCallToAction> ShowCallToAction() = 0;
virtual DesktopBrowserWindowCapabilities* capabilities() = 0;
virtual const DesktopBrowserWindowCapabilities* capabilities() const = 0;
#endif // !BUILDFLAG(IS_ANDROID)
// S T O P
// Please do not add new features here without consulting desktop leads
// (erikchen@) and Clank leads (twellington@, dtrainor@). See comment at the
// top of this file.
// The following methods will be removed in the future.
};
#endif // CHROME_BROWSER_UI_BROWSER_WINDOW_PUBLIC_BROWSER_WINDOW_INTERFACE_H_