#include "chrome/browser/ui/views/profiles/profile_picker_view.h"
#include "base/containers/contains.h"
#include "base/debug/dump_without_crashing.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/not_fatal_until.h"
#include "base/notreached.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/feature_engagement/tracker_factory.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h"
#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_avatar_icon_util.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_window.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/signin/signin_promo.h"
#include "chrome/browser/signin/signin_util.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/ui/color/chrome_color_id.h"
#include "chrome/browser/ui/views/accelerator_table.h"
#include "chrome/browser/ui/views/profiles/profile_management_flow_controller.h"
#include "chrome/browser/ui/views/profiles/profile_management_flow_controller_impl.h"
#include "chrome/browser/ui/views/profiles/profile_picker_feature_promo_controller.h"
#include "chrome/browser/ui/views/profiles/profile_picker_flow_controller.h"
#include "chrome/browser/ui/webui/signin/profile_picker_handler.h"
#include "chrome/browser/ui/webui/signin/profile_picker_ui.h"
#include "chrome/browser/ui/webui/signin/signin_url_utils.h"
#include "chrome/browser/user_education/user_education_service_factory.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/grit/branded_strings.h"
#include "components/keep_alive_registry/keep_alive_types.h"
#include "components/prefs/pref_service.h"
#include "components/signin/public/base/signin_metrics.h"
#include "components/signin/public/base/signin_switches.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/startup_metric_utils/browser/startup_metric_utils.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/context_menu_params.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/views/controls/webview/webview.h"
#include "ui/views/layout/flex_layout.h"
#include "ui/views/view.h"
#include "ui/views/view_class_properties.h"
#include "ui/views/widget/widget.h"
#include "url/gurl.h"
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
#include "chrome/browser/ui/views/profiles/first_run_flow_controller_dice.h"
#include "chrome/browser/ui/views/profiles/profile_picker_dice_sign_in_toolbar.h"
#endif
#if BUILDFLAG(IS_WIN)
#include "chrome/browser/shell_integration_win.h"
#include "ui/base/win/shell.h"
#include "ui/views/win/hwnd_util.h"
#endif
#if BUILDFLAG(IS_MAC)
#include "chrome/browser/global_keyboard_shortcuts_mac.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chrome/browser/ui/views/profiles/first_run_flow_controller_lacros.h"
#endif
#if BUILDFLAG(IS_LINUX)
#include "chrome/browser/shell_integration_linux.h"
#endif
namespace {
ProfilePickerView* g_profile_picker_view = …;
base::OnceClosure* g_profile_picker_opened_callback_for_testing = …;
constexpr int kWindowTitleId = …;
constexpr int kWindowWidth = …;
constexpr int kWindowHeight = …;
constexpr float kMaxRatioOfWorkArea = …;
constexpr int kSupportedAcceleratorCommands[] = …;
class ProfilePickerWidget : public views::Widget { … };
bool IsClassicProfilePickerFlow(const ProfilePicker::Params& params) { … }
void ClearLockedProfilesFirstBrowserKeepAlive() { … }
}
void ProfilePicker::Show(Params&& params) { … }
GURL ProfilePicker::GetOnSelectProfileTargetUrl() { … }
base::FilePath ProfilePicker::GetSwitchProfilePath() { … }
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
void ProfilePicker::SwitchToDiceSignIn(
ProfilePicker::ProfileInfo profile_info,
base::OnceCallback<void(bool)> switch_finished_callback) { … }
void ProfilePicker::SwitchToReauth(
Profile* profile,
base::OnceCallback<void(ReauthUIError)> on_error_callback) { … }
#endif
void ProfilePicker::SwitchToSignedOutPostIdentityFlow(
std::optional<SkColor> profile_color,
base::TimeTicks profile_picked_time_on_startup,
base::OnceCallback<void(bool)> switch_finished_callback) { … }
#if BUILDFLAG(IS_CHROMEOS_LACROS)
void ProfilePicker::SwitchToSignedInFlow(std::optional<SkColor> profile_color,
Profile* signed_in_profile) {
if (g_profile_picker_view) {
g_profile_picker_view->SwitchToSignedInFlow(
signed_in_profile, profile_color,
content::WebContents::Create(
content::WebContents::CreateParams(signed_in_profile)));
}
}
#endif
void ProfilePicker::CancelSignedInFlow() { … }
base::FilePath ProfilePicker::GetPickerProfilePath() { … }
void ProfilePicker::ShowDialog(Profile* profile, const GURL& url) { … }
void ProfilePicker::HideDialog() { … }
void ProfilePicker::Hide() { … }
bool ProfilePicker::IsOpen() { … }
bool ProfilePicker::IsFirstRunOpen() { … }
bool ProfilePicker::IsActive() { … }
views::WebView* ProfilePicker::GetWebViewForTesting() { … }
views::View* ProfilePicker::GetViewForTesting() { … }
void ProfilePicker::AddOnProfilePickerOpenedCallbackForTesting(
base::OnceClosure callback) { … }
void ProfilePicker::ShowDialogAndDisplayErrorMessage(Profile* profile) { … }
void ProfilePickerForceSigninDialog::ShowReauthDialog(
Profile* profile,
const std::string& email) { … }
void ProfilePickerForceSigninDialog::ShowForceSigninDialog(Profile* profile) { … }
void ProfilePickerForceSigninDialog::DisplayErrorMessage() { … }
ProfilePickerView::NavigationFinishedObserver::NavigationFinishedObserver(
const GURL& requested_url,
base::OnceClosure closure,
content::WebContents* contents)
: … { … }
ProfilePickerView::NavigationFinishedObserver::~NavigationFinishedObserver() =
default;
void ProfilePickerView::NavigationFinishedObserver::DidFinishNavigation(
content::NavigationHandle* navigation_handle) { … }
void ProfilePickerView::UpdateParams(ProfilePicker::Params&& params) { … }
void ProfilePickerView::DisplayErrorMessage() { … }
#if BUILDFLAG(IS_CHROMEOS_LACROS)
void ProfilePickerView::NotifyAccountSelected(const std::string& gaia_id) {
params_.NotifyAccountSelected(gaia_id);
}
#endif
void ProfilePickerView::ShowScreen(
content::WebContents* contents,
const GURL& url,
base::OnceClosure navigation_finished_closure) { … }
void ProfilePickerView::ShowScreenInPickerContents(
const GURL& url,
base::OnceClosure navigation_finished_closure) { … }
void ProfilePickerView::Clear() { … }
bool ProfilePickerView::ShouldUseDarkColors() const { … }
content::WebContents* ProfilePickerView::GetPickerContents() const { … }
content::WebContentsDelegate* ProfilePickerView::GetWebContentsDelegate() { … }
web_modal::WebContentsModalDialogHost*
ProfilePickerView::GetWebContentsModalDialogHost() { … }
void ProfilePickerView::SwitchToSignedOutPostIdentityFlow(
std::optional<SkColor> profile_color,
base::TimeTicks profile_picked_time_on_startup,
base::OnceCallback<void(bool)> switch_finished_callback) { … }
void ProfilePickerView::OnLocalProfileInitialized(
std::optional<SkColor> profile_color,
base::TimeTicks profile_picked_time_on_startup,
base::OnceCallback<void(bool)> switch_finished_callback,
Profile* profile) { … }
void ProfilePickerView::ShowLocalProfileCustomization(
base::TimeTicks profile_picked_time_on_startup,
Browser* browser) { … }
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
void ProfilePickerView::SetNativeToolbarVisible(bool visible) { … }
bool ProfilePickerView::IsNativeToolbarVisibleForTesting() const { … }
SkColor ProfilePickerView::GetPreferredBackgroundColor() const { … }
#endif
bool ProfilePickerView::HandleKeyboardEvent(
content::WebContents* source,
const input::NativeWebKeyboardEvent& event) { … }
bool ProfilePickerView::HandleContextMenu(
content::RenderFrameHost& render_frame_host,
const content::ContextMenuParams& params) { … }
gfx::NativeView ProfilePickerView::GetHostView() const { … }
gfx::Point ProfilePickerView::GetDialogPosition(const gfx::Size& size) { … }
gfx::Size ProfilePickerView::GetMaximumDialogSize() { … }
void ProfilePickerView::AddObserver(
web_modal::ModalDialogHostObserver* observer) { … }
void ProfilePickerView::RemoveObserver(
web_modal::ModalDialogHostObserver* observer) { … }
ProfilePickerView::ProfilePickerView(ProfilePicker::Params&& params)
: … { … }
ProfilePickerView::~ProfilePickerView() { … }
bool ProfilePickerView::MaybeReopen(ProfilePicker::Params& params) { … }
void ProfilePickerView::Display() { … }
void ProfilePickerView::OnPickerProfileCreated(Profile* picker_profile) { … }
void ProfilePickerView::Init(Profile* picker_profile) { … }
void ProfilePickerView::FinishInit() { … }
std::unique_ptr<ProfileManagementFlowController>
ProfilePickerView::CreateFlowController(Profile* picker_profile,
ClearHostClosure clear_host_callback) { … }
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
void ProfilePickerView::SwitchToDiceSignIn(
ProfilePicker::ProfileInfo profile_info,
base::OnceCallback<void(bool)> switch_finished_callback) { … }
void ProfilePickerView::SwitchToForcedSignIn(
base::OnceCallback<void(bool)> switch_finished_callback) { … }
void ProfilePickerView::OnProfileForDiceForcedSigninCreated(
base::OnceCallback<void(bool)> switch_finished_callback,
Profile* profile) { … }
void ProfilePickerView::SwitchToReauth(
Profile* profile,
base::OnceCallback<void(ReauthUIError)> on_error_callback) { … }
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
void ProfilePickerView::SwitchToSignedInFlow(
Profile* signed_in_profile,
std::optional<SkColor> profile_color,
std::unique_ptr<content::WebContents> contents) {
DCHECK(!signin_util::IsForceSigninEnabled());
GetProfilePickerFlowController()->SwitchToPostSignIn(
signed_in_profile,
IdentityManagerFactory::GetForProfile(signed_in_profile)
->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin),
profile_color, std::move(contents));
}
#endif
void ProfilePickerView::WindowClosing() { … }
views::ClientView* ProfilePickerView::CreateClientView(views::Widget* widget) { … }
views::View* ProfilePickerView::GetContentsView() { … }
std::u16string ProfilePickerView::GetAccessibleWindowTitle() const { … }
gfx::Size ProfilePickerView::CalculatePreferredSize(
const views::SizeBounds& available_size) const { … }
gfx::Size ProfilePickerView::GetMinimumSize() const { … }
bool ProfilePickerView::AcceleratorPressed(const ui::Accelerator& accelerator) { … }
bool ProfilePickerView::GetAcceleratorForCommandId(
int command_id,
ui::Accelerator* accelerator) const { … }
void ProfilePickerView::BuildLayout() { … }
void ProfilePickerView::ShowScreenFinished(
content::WebContents* contents,
base::OnceClosure navigation_finished_closure) { … }
void ProfilePickerView::NavigateBack() { … }
void ProfilePickerView::ConfigureAccelerators() { … }
void ProfilePickerView::InitializeFeaturePromo(Profile* system_profile) { … }
void ProfilePickerView::ShowDialog(Profile* profile, const GURL& url) { … }
void ProfilePickerView::HideDialog() { … }
GURL ProfilePickerView::GetOnSelectProfileTargetUrl() const { … }
ProfilePickerFlowController* ProfilePickerView::GetProfilePickerFlowController()
const { … }
ClearHostClosure ProfilePickerView::GetClearClosure() { … }
#if BUILDFLAG(IS_CHROMEOS_LACROS)
void ProfilePicker::NotifyAccountSelected(const std::string& gaia_id) {
if (!g_profile_picker_view) {
return;
}
g_profile_picker_view->NotifyAccountSelected(gaia_id);
}
#endif
BEGIN_METADATA(…)