1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
|
// Copyright 2025 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_GLIC_FRE_GLIC_FRE_CONTROLLER_H_
#define CHROME_BROWSER_GLIC_FRE_GLIC_FRE_CONTROLLER_H_
#include <memory>
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/glic/fre/glic_fre.mojom.h"
#include "chrome/browser/glic/host/auth_controller.h"
#include "chrome/browser/glic/host/glic.mojom.h"
#include "chrome/browser/shell_integration.h"
#include "components/tabs/public/tab_interface.h"
#include "ui/views/widget/widget.h"
class Browser;
class Profile;
namespace content {
class WebContents;
}
namespace version_info {
enum class Channel;
}
namespace views {
class Widget;
}
namespace glic {
class GlicFreDialogView;
// This enum is used to record the reason for the FRE error state.
// These values are persisted to logs.
// LINT.IfChange(FreErrorStateReason)
enum class FreErrorStateReason {
// Sign-in is required.
kSignInRequired = 0,
// Error while re-syncing cookies before showing FRE.
kErrorResyncingCookies = 1,
// Timeout exceeded during loading error.
kTimeoutExceeded = 2,
kMaxValue = kTimeoutExceeded,
};
// LINT.ThenChange(tools/metrics/histograms/metadata/glic/enums.xml:FreErrorStateReason)
// This class owns and manages the glic FRE modal dialog, and is owned by a
// GlicWindowController.
class GlicFreController {
public:
GlicFreController(const GlicFreController&) = delete;
GlicFreController& operator=(const GlicFreController&) = delete;
GlicFreController(Profile* profile,
signin::IdentityManager* identity_manager);
~GlicFreController();
mojom::FreWebUiState GetWebUiState() const { return webui_state_; }
void WebUiStateChanged(mojom::FreWebUiState new_state);
using WebUiStateChangedCallback =
base::RepeatingCallback<void(mojom::FreWebUiState new_state)>;
// Registers |callback| to be called whenever the WebUi state changes.
base::CallbackListSubscription AddWebUiStateChangedCallback(
WebUiStateChangedCallback callback);
// Close any windows and destroy web contents.
void Shutdown();
// Returns whether the FRE dialog should be shown.
bool ShouldShowFreDialog();
// Returns whether the FRE dialog can be shown. This function also checks
// `TabInterface::CanShowModalUI`, which is a mandatory precondition to
// showing the dialog.
bool CanShowFreDialog(Browser* browser);
// Open the new tab page in the browser and show the FRE in that tab if
// possible.
void OpenFreDialogInNewTab(BrowserWindowInterface* bwi,
mojom::InvocationSource source);
// Shows the FRE dialog. This should only be called if `ShouldShowFreDialog`
// and `CanShowFreDialog` are both satisfied.
void ShowFreDialog(Browser* browser, mojom::InvocationSource source);
// Closes the FRE dialog if it is open on the active tab of `browser`.
void DismissFreIfOpenOnActiveTab(Browser* browser);
// Closes the FRE dialog and immediately opens a glic window attached to
// the same browser.
void AcceptFre();
// Closes the FRE dialog.
void DismissFre(mojom::FreWebUiState panel);
// Used when the native window is closed directly.
void CloseWithReason(views::Widget::ClosedReason reason);
// Re-sync cookies to FRE webview.
void PrepareForClient(base::OnceCallback<void(bool)> callback);
// Loading timeout was exceeded.
void ExceededTimeoutError();
// Notify FRE controller that the user clicked on a link.
void OnLinkClicked(const GURL& url);
// Attempts to warm the FRE web contents.
void TryPreload();
// Returns true if the FRE web contents are loaded (either because it has been
// preloaded or because it is visible).
bool IsWarmed() const;
// Returns the WebContents from the dialog view.
content::WebContents* GetWebContents();
// Preconnect to the server that hosts the FRE, so that it loads faster.
// Does nothing if the FRE should not be shown.
void MaybePreconnect();
bool IsShowingDialog() const;
bool IsShowingDialogAndStateInitialized() const;
gfx::Size GetFreInitialSize();
void UpdateFreWidgetSize(const gfx::Size& new_size);
void LogWebUiLoadComplete();
AuthController& GetAuthControllerForTesting() { return auth_controller_; }
Profile* profile() { return profile_; }
base::WeakPtr<GlicFreController> GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
private:
FRIEND_TEST_ALL_PREFIXES(GlicFreControllerTest,
UpdateLauncherOnFreCompletion);
void ShowFreDialogAfterAuthCheck(base::WeakPtr<Browser> browser,
mojom::InvocationSource source);
static void OnCheckIsDefaultBrowserFinished(
version_info::Channel channel,
shell_integration::DefaultWebClientState state);
// Called when the tab showing the FRE dialog is detached.
void OnTabShowingModalWillDetach(tabs::TabInterface* tab,
tabs::TabInterface::DetachReason reason);
void CreateView();
void RecordMetricsIfDialogIsShowingAndReady();
raw_ptr<Profile> const profile_;
std::unique_ptr<views::Widget> fre_widget_;
std::unique_ptr<GlicFreDialogView> fre_view_;
// This is owned by the GlicFreDialogView but we retain a pointer to it so
// that we can continue to reference it even after `fre_view_` relinquishes
// ownership to the widget.
raw_ptr<content::WebContents> web_contents_ = nullptr;
AuthController auth_controller_;
// The invocation source browser.
raw_ptr<Browser> source_browser_ = nullptr;
// Tracks the tab that the FRE dialog is shown on.
raw_ptr<tabs::TabInterface> tab_showing_modal_;
base::CallbackListSubscription will_detach_subscription_;
mojom::FreWebUiState webui_state_ = mojom::FreWebUiState::kUninitialized;
// List of callbacks to be notified when webui state has changed.
base::RepeatingCallbackList<void(mojom::FreWebUiState)>
webui_state_callback_list_;
// The timestamp when the FRE window is requested to be shown.
base::TimeTicks show_start_time_;
// The timestamp when the FRE widget creation starts.
base::TimeTicks widget_creation_start_time_;
// The timestamp when the FRE WebUI loading starts.
base::TimeTicks webui_load_start_time_;
// The timestamp when the FRE web content loading starts.
base::TimeTicks web_client_load_start_time_;
base::WeakPtrFactory<GlicFreController> weak_ptr_factory_{this};
};
} // namespace glic
#endif // CHROME_BROWSER_GLIC_FRE_GLIC_FRE_CONTROLLER_H_
|