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
|
// Copyright 2022 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_management_flow_controller_impl.h"
#include <memory>
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/signin_util.h"
#include "chrome/browser/ui/autofill/popup_controller_common.h"
#include "chrome/browser/ui/views/profiles/profile_management_flow_controller.h"
#include "chrome/browser/ui/views/profiles/profile_management_step_controller.h"
#include "chrome/browser/ui/views/profiles/profile_management_types.h"
#include "chrome/browser/ui/views/profiles/profile_picker_signed_in_flow_controller.h"
#include "content/public/browser/web_contents.h"
#include "google_apis/gaia/core_account_id.h"
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
#include "chrome/browser/ui/views/profiles/profile_picker_dice_sign_in_provider.h"
#endif
ProfileManagementFlowControllerImpl::ProfileManagementFlowControllerImpl(
ProfilePickerWebContentsHost* host,
ClearHostClosure clear_host_callback,
std::string_view flow_type_string)
: ProfileManagementFlowController(host,
std::move(clear_host_callback),
flow_type_string) {}
ProfileManagementFlowControllerImpl::~ProfileManagementFlowControllerImpl() =
default;
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
void ProfileManagementFlowControllerImpl::
SwitchToIdentityStepsFromAccountSelection(
StepSwitchFinishedCallback step_switch_finished_callback,
signin_metrics::AccessPoint access_point,
base::FilePath profile_path) {
DCHECK_NE(Step::kAccountSelection, current_step());
DCHECK_NE(Step::kPostSignInFlow, current_step());
bool step_needs_registration = !IsStepInitialized(Step::kAccountSelection);
if (step_needs_registration) {
RegisterStep(
Step::kAccountSelection,
ProfileManagementStepController::CreateForDiceSignIn(
host(),
std::make_unique<ProfilePickerDiceSignInProvider>(
host(), access_point, std::move(profile_path)),
base::BindOnce(
&ProfileManagementFlowControllerImpl::HandleSignInCompleted,
// Binding as Unretained as `this`
// outlives the step controllers.
base::Unretained(this))));
}
SwitchToStep(Step::kAccountSelection,
/*reset_state=*/step_needs_registration,
std::move(step_switch_finished_callback),
CreateSwitchToStepPopCallback(current_step()));
}
#endif
std::unique_ptr<ProfileManagementStepController>
ProfileManagementFlowControllerImpl::CreatePostSignInStep(
Profile* signed_in_profile,
const CoreAccountInfo& account_info,
std::unique_ptr<content::WebContents> contents) {
return ProfileManagementStepController::CreateForPostSignInFlow(
host(), CreateSignedInFlowController(signed_in_profile, account_info,
std::move(contents)));
}
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
std::unique_ptr<ProfileManagementStepController>
ProfileManagementFlowControllerImpl::CreateSamlStep(
Profile* signed_in_profile,
std::unique_ptr<content::WebContents> contents) {
return ProfileManagementStepController::CreateForFinishSamlSignIn(
host(), signed_in_profile, std::move(contents),
base::BindOnce(
&ProfileManagementFlowControllerImpl::FinishFlowAndRunInBrowser,
// Unretained ok: the callback is passed to a step that
// the `flow_controller_` will own and outlive.
base::Unretained(this),
// Unretained ok: the steps register a profile alive and
// will be alive until this callback runs.
base::Unretained(signed_in_profile)));
}
void ProfileManagementFlowControllerImpl::HandleSignInCompleted(
Profile* signed_in_profile,
const CoreAccountInfo& account_info,
std::unique_ptr<content::WebContents> contents,
StepSwitchFinishedCallback step_switch_finished_callback) {
DCHECK(signed_in_profile);
DCHECK_EQ(Step::kAccountSelection, current_step());
Step step;
// SAML with ForceSignin flow is migrated to the regular Profile Picker flow.
if (account_info.IsEmpty() && !signin_util::IsForceSigninEnabled()) {
step = Step::kFinishSamlSignin;
DCHECK(!IsStepInitialized(step));
// The SAML step controller handles finishing the profile setup by itself
// when we switch to it.
RegisterStep(step, CreateSamlStep(signed_in_profile, std::move(contents)));
} else {
step = Step::kPostSignInFlow;
DCHECK(!IsStepInitialized(step));
RegisterStep(step, CreatePostSignInStep(signed_in_profile, account_info,
std::move(contents)));
}
SwitchToStep(step, /*reset_state=*/true,
std::move(step_switch_finished_callback));
// If we need to go back, we should go all the way to the beginning of the
// flow and after that, recreate the account selection step to ensure no data
// leaks if we select a different account.
// We also erase the step after the switch here because it holds a
// `ScopedProfileKeepAlive` and we need the next step to register its own
// before this the account selection's is released.
UnregisterStep(Step::kAccountSelection);
}
#endif
void ProfileManagementFlowControllerImpl::SwitchToPostIdentitySteps(
PostHostClearedCallback post_host_cleared_callback) {
post_identity_steps_ =
RegisterPostIdentitySteps(std::move(post_host_cleared_callback));
AdvanceToNextPostIdentityStep();
}
void ProfileManagementFlowControllerImpl::AdvanceToNextPostIdentityStep() {
if (post_identity_steps_.empty()) {
return;
}
Step next_step = post_identity_steps_.front();
post_identity_steps_.pop();
SwitchToStep(next_step, /*reset_state=*/true);
}
void ProfileManagementFlowControllerImpl::HandleIdentityStepsCompleted(
Profile* profile,
PostHostClearedCallback post_host_cleared_callback,
bool is_continue_callback) {
CHECK(profile);
if (is_continue_callback) {
RegisterStep(
Step::kFinishFlow,
ProfileManagementStepController::CreateForFinishFlowAndRunInBrowser(
host(),
base::BindOnce(
&ProfileManagementFlowControllerImpl::FinishFlowAndRunInBrowser,
base::Unretained(this), profile,
std::move(post_host_cleared_callback))));
SwitchToStep(Step::kFinishFlow, /*reset_state=*/true);
return;
}
SwitchToPostIdentitySteps(std::move(post_host_cleared_callback));
}
|