blob: d73ec70009680d15b11490a15651ee6ae5bcbf5d [file] [log] [blame]
// Copyright 2020 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/profiles/profile_picker.h"
#include <string>
#include "base/command_line.h"
#include "base/containers/flat_set.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profiles_state.h"
#include "chrome/browser/ui/startup/startup_browser_creator.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/signin/public/base/signin_switches.h"
namespace {
bool g_open_command_line_urls_in_next_profile_opened = false;
ProfilePicker::AvailabilityOnStartup GetAvailabilityOnStartup() {
int availability_on_startup = g_browser_process->local_state()->GetInteger(
prefs::kBrowserProfilePickerAvailabilityOnStartup);
switch (availability_on_startup) {
case 0:
return ProfilePicker::AvailabilityOnStartup::kEnabled;
case 1:
return ProfilePicker::AvailabilityOnStartup::kDisabled;
case 2:
return ProfilePicker::AvailabilityOnStartup::kForced;
default:
NOTREACHED();
}
}
} // namespace
const char ProfilePicker::kTaskManagerUrl[] =
"chrome://profile-picker/task-manager";
ProfilePicker::Params::~Params() = default;
ProfilePicker::Params::Params(ProfilePicker::Params&&) = default;
ProfilePicker::Params& ProfilePicker::Params::operator=(
ProfilePicker::Params&&) = default;
// static
ProfilePicker::Params ProfilePicker::Params::FromEntryPoint(
EntryPoint entry_point) {
// Use specialized constructors when available.
CHECK_NE(entry_point, EntryPoint::kBackgroundModeManager);
CHECK_NE(entry_point, EntryPoint::kGlicManager);
return ProfilePicker::Params(entry_point, GetPickerProfilePath());
}
ProfilePicker::Params ProfilePicker::Params::FromStartupWithEmail(
const std::string& email) {
Params params = ProfilePicker::Params::FromEntryPoint(
EntryPoint::kOnStartupCreateProfileWithEmail);
params.initial_email_ = email;
return params;
}
// static
ProfilePicker::Params ProfilePicker::Params::ForBackgroundManager(
const GURL& on_select_profile_target_url) {
Params params(EntryPoint::kBackgroundModeManager, GetPickerProfilePath());
params.on_select_profile_target_url_ = on_select_profile_target_url;
return params;
}
// static
ProfilePicker::Params ProfilePicker::Params::ForFirstRun(
const base::FilePath& profile_path,
FirstRunExitedCallback first_run_exited_callback) {
Params params(EntryPoint::kFirstRun, profile_path);
params.first_run_exited_callback_ = std::move(first_run_exited_callback);
return params;
}
// static
ProfilePicker::Params ProfilePicker::Params::ForGlicManager(
base::OnceCallback<void(Profile*)> picked_profile_callback) {
Params params(EntryPoint::kGlicManager, GetPickerProfilePath());
params.picked_profile_callback_ = std::move(picked_profile_callback);
return params;
}
void ProfilePicker::Params::NotifyFirstRunExited(
FirstRunExitStatus exit_status) {
if (!first_run_exited_callback_) {
return;
}
std::move(first_run_exited_callback_).Run(exit_status);
}
void ProfilePicker::Params::NotifyProfilePicked(Profile* profile) {
CHECK(picked_profile_callback_);
CHECK_EQ(entry_point_, EntryPoint::kGlicManager);
std::move(picked_profile_callback_).Run(profile);
}
bool ProfilePicker::Params::CanReusePickerWindow(const Params& other) const {
LOG(WARNING) << "Checking window reusability from entry point "
<< static_cast<int>(entry_point_) << " to "
<< static_cast<int>(other.entry_point());
// Some entry points have specific UIs that cannot be reused for other entry
// points.
base::flat_set<EntryPoint> exclusive_entry_points = {
EntryPoint::kFirstRun,
EntryPoint::kGlicManager,
};
if (entry_point_ != other.entry_point_ &&
(exclusive_entry_points.contains(entry_point_) ||
exclusive_entry_points.contains(other.entry_point_))) {
return false;
}
return profile_path_ == other.profile_path_;
}
ProfilePicker::Params::Params(EntryPoint entry_point,
const base::FilePath& profile_path)
: entry_point_(entry_point), profile_path_(profile_path) {}
// static
bool ProfilePicker::Shown() {
PrefService* prefs = g_browser_process->local_state();
DCHECK(prefs);
return prefs->GetBoolean(prefs::kBrowserProfilePickerShown);
}
// static
StartupProfileMode ProfilePicker::GetStartupMode() {
AvailabilityOnStartup availability_on_startup = GetAvailabilityOnStartup();
if (availability_on_startup == AvailabilityOnStartup::kDisabled) {
return StartupProfileMode::kBrowserWindow;
}
// TODO (crbug/1155158): Move this over the urls check (in
// startup_browser_creator.cc) once the profile picker can forward urls
// specified in command line.
if (availability_on_startup == AvailabilityOnStartup::kForced) {
return StartupProfileMode::kProfilePicker;
}
ProfileManager* profile_manager = g_browser_process->profile_manager();
// Only launch the profile creation flow at startup if the user has specified
// both a profile email address and the switch to create a new profile. Only
// launch the profile creation flow if and a profile with this email does not
// already exist.
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kProfileEmail)) {
std::string switch_email =
command_line->GetSwitchValueASCII(switches::kProfileEmail);
if (!switch_email.empty()) {
if (!profile_manager->GetProfileDirForEmail(switch_email).empty()) {
return StartupProfileMode::kBrowserWindow;
} else if (command_line->HasSwitch(
switches::kCreateProfileEmailIfNotExists) &&
base::FeatureList::IsEnabled(
features::kCreateProfileIfNoneExists)) {
return StartupProfileMode::kProfilePicker;
}
}
}
size_t number_of_profiles = profile_manager->GetNumberOfProfiles();
// Need to consider 0 profiles as this is what happens in some browser-tests.
if (number_of_profiles == 0) {
return StartupProfileMode::kBrowserWindow;
}
if (number_of_profiles == 1 &&
!base::FeatureList::IsEnabled(
switches::kShowProfilePickerToAllUsersExperiment)) {
return StartupProfileMode::kBrowserWindow;
}
bool pref_enabled = g_browser_process->local_state()->GetBoolean(
prefs::kBrowserShowProfilePickerOnStartup);
base::UmaHistogramBoolean("ProfilePicker.AskOnStartup", pref_enabled);
if (pref_enabled) {
return StartupProfileMode::kProfilePicker;
}
return StartupProfileMode::kBrowserWindow;
}
// static
void ProfilePicker::SetOpenCommandLineUrlsInNextProfileOpened(bool value) {
g_open_command_line_urls_in_next_profile_opened = value;
}
// static
bool ProfilePicker::GetOpenCommandLineUrlsInNextProfileOpened() {
return g_open_command_line_urls_in_next_profile_opened;
}