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
|
// 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.
#include "chrome/browser/ui/views/profiles/profile_picker_glic_flow_controller.h"
#include "base/functional/bind.h"
#include "base/notreached.h"
#include "chrome/browser/browser_process.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_manager.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/ui/views/profiles/profile_management_step_controller.h"
#include "chrome/browser/ui/views/profiles/profile_management_types.h"
#include "chrome/common/webui_url_constants.h"
#include "components/signin/public/identity_manager/identity_manager.h"
namespace {
GURL GetProfilePickerGlicURL() {
const GURL base_url = GURL(chrome::kChromeUIProfilePickerUrl);
GURL::Replacements replacements;
replacements.SetQueryStr(chrome::kChromeUIProfilePickerGlicQuery);
return base_url.ReplaceComponents(replacements);
}
} // namespace
ProfilePickerGlicFlowController::ProfilePickerGlicFlowController(
ProfilePickerWebContentsHost* host,
ClearHostClosure clear_host_callback,
base::OnceCallback<void(Profile*)> picked_profile_callback)
: ProfileManagementFlowController(host,
std::move(clear_host_callback),
/*flow_type_string=*/"GlicFlow"),
picked_profile_callback_(std::move(picked_profile_callback)) {
CHECK(picked_profile_callback_);
}
ProfilePickerGlicFlowController::~ProfilePickerGlicFlowController() {
if (picked_profile_callback_) {
Clear();
}
}
void ProfilePickerGlicFlowController::Init() {
RegisterStep(Step::kProfilePicker,
ProfileManagementStepController::CreateForProfilePickerApp(
host(), GetProfilePickerGlicURL()));
SwitchToStep(Step::kProfilePicker, /*reset_state=*/true);
}
void ProfilePickerGlicFlowController::PickProfile(
const base::FilePath& profile_path,
ProfilePicker::ProfilePickingArgs args,
base::OnceCallback<void(bool)> pick_profile_complete_callback) {
g_browser_process->profile_manager()->LoadProfileByPath(
profile_path, /*incognito=*/false,
base::BindOnce(&ProfilePickerGlicFlowController::OnPickedProfileLoaded,
base::Unretained(this),
std::move(pick_profile_complete_callback)));
}
void ProfilePickerGlicFlowController::OnPickedProfileLoaded(
base::OnceCallback<void(bool)> pick_profile_complete_callback,
Profile* profile) {
if (!profile) {
if (pick_profile_complete_callback) {
std::move(pick_profile_complete_callback).Run(false);
}
Clear();
return;
}
if (pick_profile_complete_callback) {
std::move(pick_profile_complete_callback).Run(true);
}
loaded_profile_ = profile;
signin::IdentityManager* identity_manager =
IdentityManagerFactory::GetForProfile(loaded_profile_);
if (identity_manager->AreRefreshTokensLoaded()) {
ExitFlowWithLoadedProfile();
return;
}
identity_manager_observation_.Observe(identity_manager);
}
void ProfilePickerGlicFlowController::Clear() {
std::move(picked_profile_callback_).Run(nullptr);
ExitFlow();
}
void ProfilePickerGlicFlowController::CancelPostSignInFlow() {
NOTREACHED() << "The glic flow controller is not expected to support this "
"part of the flow as it does not support signing in.";
}
void ProfilePickerGlicFlowController::ExitFlowWithLoadedProfile() {
CHECK(loaded_profile_);
signin::IdentityManager* identity_manager =
IdentityManagerFactory::GetForProfile(loaded_profile_);
CHECK(identity_manager->AreRefreshTokensLoaded());
// Effectively removes `ProfileKeepAliveOrigin::kWaitingForFirstBrowserWindow`
// and expects the call in `picked_profile_callback_` to set a new keep alive
// if the profile should not be destroyed.
ScopedProfileKeepAlive keep_alive(
loaded_profile_, ProfileKeepAliveOrigin::kWaitingForGlicView);
// Return the loaded profile to the caller.
std::move(picked_profile_callback_).Run(loaded_profile_);
loaded_profile_ = nullptr;
// Close the picker.
ExitFlow();
}
void ProfilePickerGlicFlowController::OnRefreshTokensLoaded() {
CHECK(loaded_profile_);
identity_manager_observation_.Reset();
ExitFlowWithLoadedProfile();
}
|