// 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 #include "base/memory/raw_ptr.h" #include "build/build_config.h" #include "content/public/browser/page_navigator.h" #if !BUILDFLAG(IS_ANDROID) #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 web_modal { class WebContentsModalDialogHost; } // namespace web_modal class Browser; class BrowserActions; class BrowserWindowFeatures; class DesktopBrowserWindowCapabilities; class GURL; class TabStripModel; #endif // BUILDFLAG(IS_ANDROID) namespace base { class CallbackListSubscription; } // namespace base namespace ui { class BaseWindow; class UnownedUserDataHost; } // namespace ui class Profile; class SessionID; namespace internal { class ScopedBrowserShower; } 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; // Returns true if the browser window is currently scheduled for deletion. At // this stage, the browser window will definitely be closed, and it cannot be // stopped. This is true after all the various tab unload handlers and similar // have ran. virtual bool IsDeleteScheduled() const = 0; // Register callbacks invoked when browser has successfully processed its // close request and has been scheduled for deletion. using BrowserDidCloseCallback = base::RepeatingCallback; virtual base::CallbackListSubscription RegisterBrowserDidClose( BrowserDidCloseCallback callback) = 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_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 BUILDFLAG(IS_ANDROID) // TODO(https://crbug.com/493668475): Revisit if this type is needed. // Android Custom Tab browser. TYPE_CUSTOM_TAB, #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. kErrorShuttingDown, // 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) or if the profile is shutting // down. kErrorProfileUnsuitable, #if BUILDFLAG(IS_CHROMEOS) // Indicates the profile is currently loading kiosk mode, so no new windows // should be allowed. kErrorLoadingKiosk, #endif }; // 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 bwi_; // // Conceptually, this member should only be set if bwi_ is set. // std::optional 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 bwi_; // std::optional color_of_browser_; // }; virtual base::WeakPtr GetWeakPtr() = 0; // 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. // // As alternatives, consider: // Tab/Navigation: `TabListInterface::From(BrowserWindowInterface*)`. // Windowing: `base::Window* GetWindow()`. // // For other methods, consult the leads above for guidance. // // 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); // 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; // Register callbacks invoked when browser attempted to close but the close // operation was cancelled. using BrowserCloseCancelledCallback = base::RepeatingCallback; virtual base::CallbackListSubscription RegisterBrowserCloseCancelled( BrowserCloseCancelledCallback callback) = 0; using ActiveTabChangeCallback = base::RepeatingCallback; 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 on platforms other than Windows, this might not reflect the // actual OS level window activation status, as Chrome internally marks any // browser window as "active" as soon as it starts the (asynchronous) process // to activate the window. However there is no guarantee that the window will // actually be activated on the OS level, so this field can easily get out of // sync with reality. virtual bool IsActive() const = 0; // Register for these two callbacks to detect changes to IsActive(). using DidBecomeActiveCallback = base::RepeatingCallback; virtual base::CallbackListSubscription RegisterDidBecomeActive( DidBecomeActiveCallback callback) = 0; using DidBecomeInactiveCallback = base::RepeatingCallback; virtual base::CallbackListSubscription RegisterDidBecomeInactive( DidBecomeInactiveCallback callback) = 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; // 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 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; virtual const Browser* GetBrowserForMigrationOnly() const = 0; // Checks if the browser popup is tab modal dialog. virtual bool IsTabModalPopup() const = 0; virtual void SetIsTabModalPopup( bool is_tab_modal_popup, base::PassKey) = 0; // Checks if the browser was created by session restore. virtual bool CreatedBySessionRestore() const = 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_