Commit fa8de986 authored by Jan Krcal's avatar Jan Krcal Committed by Commit Bot

[Profile picker] Use system profile on startup when showing the picker

This CL changes the logic to load the startup profile whenever the
profile picker should be loaded. It instead loads the guest profile
to indicate the picker should be open. This speeds up showing the picker
when the last profile used is heavy to load. The CL also unifies the
logic to decide whether to show the new picker (or the old user manager)
into one function, GetStartupProfile().

There is one behavioral difference: the new code directly opens browser
windows if the user had multiple profiles open last time. This is desired
because having multiple profiles open simultaneously the last time is a
strong signal the user wants to continue this way. Note that having
multiple profiles open the last time happens only in limited situations,
e.g. via chrome://restart or via session restore (when logging out /
switching off the machine with multiple profiles' windows open).

Bug: 1150330
Change-Id: Iae9744f44bc242e9aaaf8f287cc29e1089326786
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2532460
Commit-Queue: Jan Krcal <jkrcal@chromium.org>
Reviewed-by: default avatarDavid Roger <droger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#828665}
parent 2e87369b
...@@ -1265,12 +1265,7 @@ static base::mac::ScopedObjCClassSwizzler* g_swizzle_imk_input_session; ...@@ -1265,12 +1265,7 @@ static base::mac::ScopedObjCClassSwizzler* g_swizzle_imk_input_session;
// manager is still shown). // manager is still shown).
UserManager::Show(base::FilePath(), UserManager::Show(base::FilePath(),
profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION); profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION);
} else if (ProfilePicker::ShouldShowAtLaunch( } else if (ProfilePicker::ShouldShowAtLaunch()) {
// Pass an empty command line, because this is not application
// startup. The original arguments (e.g. --incognito) are no
// longer relevant.
base::CommandLine(base::CommandLine::NO_PROGRAM),
/*urls_to_launch=*/std::vector<GURL>())) {
ProfilePicker::Show( ProfilePicker::Show(
ProfilePicker::EntryPoint::kNewSessionOnExistingProcess); ProfilePicker::EntryPoint::kNewSessionOnExistingProcess);
} else { } else {
......
...@@ -340,6 +340,7 @@ void AddFirstRunNewTabs(StartupBrowserCreator* browser_creator, ...@@ -340,6 +340,7 @@ void AddFirstRunNewTabs(StartupBrowserCreator* browser_creator,
// should not continue. // should not continue.
Profile* CreatePrimaryProfile(const content::MainFunctionParams& parameters, Profile* CreatePrimaryProfile(const content::MainFunctionParams& parameters,
const base::FilePath& user_data_dir, const base::FilePath& user_data_dir,
const base::FilePath& cur_dir,
const base::CommandLine& parsed_command_line) { const base::CommandLine& parsed_command_line) {
TRACE_EVENT0("startup", "ChromeBrowserMainParts::CreateProfile") TRACE_EVENT0("startup", "ChromeBrowserMainParts::CreateProfile")
...@@ -392,7 +393,7 @@ Profile* CreatePrimaryProfile(const content::MainFunctionParams& parameters, ...@@ -392,7 +393,7 @@ Profile* CreatePrimaryProfile(const content::MainFunctionParams& parameters,
CHECK(profile) << "Cannot get default profile."; CHECK(profile) << "Cannot get default profile.";
#else #else
profile = GetStartupProfile(user_data_dir, parsed_command_line); profile = GetStartupProfile(user_data_dir, cur_dir, parsed_command_line);
if (!profile && !set_last_used_profile) if (!profile && !set_last_used_profile)
profile = GetFallbackStartupProfile(); profile = GetFallbackStartupProfile();
...@@ -1360,9 +1361,8 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() { ...@@ -1360,9 +1361,8 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
// This step is costly and is already measured in Startup.CreateFirstProfile // This step is costly and is already measured in Startup.CreateFirstProfile
// and more directly Profile.CreateAndInitializeProfile. // and more directly Profile.CreateAndInitializeProfile.
profile_ = CreatePrimaryProfile(parameters(), profile_ = CreatePrimaryProfile(parameters(), user_data_dir_,
user_data_dir_, base::FilePath(), parsed_command_line());
parsed_command_line());
if (!profile_) if (!profile_)
return content::RESULT_CODE_NORMAL_EXIT; return content::RESULT_CODE_NORMAL_EXIT;
......
...@@ -6,68 +6,24 @@ ...@@ -6,68 +6,24 @@
#include <string> #include <string>
#include "base/command_line.h"
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_functions.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile_attributes_storage.h" #include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profiles_state.h" #include "chrome/browser/profiles/profiles_state.h"
#include "chrome/browser/signin/signin_util.h" #include "chrome/browser/signin/signin_util.h"
#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/ui_features.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#if defined(OS_WIN)
#include "chrome/browser/notifications/win/notification_launch_id.h"
#endif
// static // static
bool ProfilePicker::ShouldShowAtLaunch( bool ProfilePicker::ShouldShowAtLaunch() {
const base::CommandLine& command_line,
const std::vector<GURL>& urls_to_launch) {
// Don't show the picker if a certain profile (or an incognito window in the
// default profile) is explicitly requested.
if (profiles::IsGuestModeRequested(command_line,
g_browser_process->local_state(),
/*show_warning=*/false) ||
command_line.HasSwitch(switches::kIncognito) ||
command_line.HasSwitch(switches::kProfileDirectory)) {
return false;
}
// Don't show the picker if an app is explicitly requested to open. This URL
// param should be ideally paired with switches::kProfileDirectory but it's
// better to err on the side of opening the last profile than to err on the
// side of not opening the app directly.
if (command_line.HasSwitch(switches::kApp) ||
command_line.HasSwitch(switches::kAppId)) {
return false;
}
// If the browser is launched due to activation on Windows native notification,
// the profile id encoded in the notification launch id should be chosen over
// the profile picker.
#if defined(OS_WIN)
std::string profile_id =
NotificationLaunchId::GetNotificationLaunchProfileId(command_line);
if (!profile_id.empty()) {
return false;
}
#endif // defined(OS_WIN)
// Don't show the picker if a any URL is requested to launch via the
// command-line.
if (!urls_to_launch.empty()) {
return false;
}
size_t number_of_profiles = g_browser_process->profile_manager() size_t number_of_profiles = g_browser_process->profile_manager()
->GetProfileAttributesStorage() ->GetProfileAttributesStorage()
.GetNumberOfProfiles(); .GetNumberOfProfiles();
if (signin_util::IsForceSigninEnabled() || number_of_profiles == 1) // Need to consider 0 profiles as this is what happens in some browser-tests.
if (signin_util::IsForceSigninEnabled() || number_of_profiles <= 1)
return false; return false;
bool pref_enabled = g_browser_process->local_state()->GetBoolean( bool pref_enabled = g_browser_process->local_state()->GetBoolean(
......
...@@ -68,14 +68,11 @@ class ProfilePicker { ...@@ -68,14 +68,11 @@ class ProfilePicker {
// Overrides the timeout delay for waiting for extended account info. // Overrides the timeout delay for waiting for extended account info.
static void SetExtendedAccountInfoTimeoutForTesting(base::TimeDelta timeout); static void SetExtendedAccountInfoTimeoutForTesting(base::TimeDelta timeout);
// Returns whether the profile picker at launch. This can be called on // Returns whether to show profile picker at launch. This can be called on
// startup or when Chrome is re-opened, e.g. when clicking on the dock icon on // startup or when Chrome is re-opened, e.g. when clicking on the dock icon on
// MacOS when there are no windows, or from Windows tray icon. // MacOS when there are no windows, or from Windows tray icon.
// This returns true if this is a new session. Returns false if a specific // This returns true if the user has multiple profiles and has not opted-out.
// profile is passed in the command line, or if some parameters (such as the static bool ShouldShowAtLaunch();
// URLs to launch) cannot be handled by the picker.
static bool ShouldShowAtLaunch(const base::CommandLine& command_line,
const std::vector<GURL>& urls_to_launch);
private: private:
DISALLOW_COPY_AND_ASSIGN(ProfilePicker); DISALLOW_COPY_AND_ASSIGN(ProfilePicker);
......
...@@ -161,12 +161,6 @@ class StartupBrowserCreator { ...@@ -161,12 +161,6 @@ class StartupBrowserCreator {
Profile* last_used_profile, Profile* last_used_profile,
const Profiles& last_opened_profiles); const Profiles& last_opened_profiles);
// Returns the list of URLs to open from the command line.
static std::vector<GURL> GetURLsFromCommandLine(
const base::CommandLine& command_line,
const base::FilePath& cur_dir,
Profile* profile);
// This function performs command-line handling and is invoked only after // This function performs command-line handling and is invoked only after
// start up (for example when we get a start request for another process). // start up (for example when we get a start request for another process).
// |command_line| holds the command line being processed. // |command_line| holds the command line being processed.
...@@ -202,6 +196,11 @@ class StartupBrowserCreator { ...@@ -202,6 +196,11 @@ class StartupBrowserCreator {
static bool in_synchronous_profile_launch_; static bool in_synchronous_profile_launch_;
}; };
// Returns the list of URLs to open from the command line.
std::vector<GURL> GetURLsFromCommandLine(const base::CommandLine& command_line,
const base::FilePath& cur_dir,
Profile* profile);
// Returns true if |profile| has exited uncleanly and has not been launched // Returns true if |profile| has exited uncleanly and has not been launched
// after the unclean exit. // after the unclean exit.
bool HasPendingUncleanExit(Profile* profile); bool HasPendingUncleanExit(Profile* profile);
...@@ -219,6 +218,7 @@ base::FilePath GetStartupProfilePath(const base::FilePath& user_data_dir, ...@@ -219,6 +218,7 @@ base::FilePath GetStartupProfilePath(const base::FilePath& user_data_dir,
// opening the user manager, returns null if either the guest profile or the // opening the user manager, returns null if either the guest profile or the
// system profile cannot be opened. // system profile cannot be opened.
Profile* GetStartupProfile(const base::FilePath& user_data_dir, Profile* GetStartupProfile(const base::FilePath& user_data_dir,
const base::FilePath& cur_dir,
const base::CommandLine& command_line); const base::CommandLine& command_line);
// Returns the profile that should be loaded on process startup when // Returns the profile that should be loaded on process startup when
......
...@@ -1871,7 +1871,8 @@ class StartupBrowserCreatorPickerTest : public InProcessBrowserTest { ...@@ -1871,7 +1871,8 @@ class StartupBrowserCreatorPickerTest : public InProcessBrowserTest {
~StartupBrowserCreatorPickerTest() override = default; ~StartupBrowserCreatorPickerTest() override = default;
protected: protected:
void StartWithTwoProfiles(const base::CommandLine& command_line) { void StartWithTwoProfiles(const base::CommandLine& command_line,
bool set_last_opened_profiles = false) {
Profile* profile = browser()->profile(); Profile* profile = browser()->profile();
ProfileManager* profile_manager = g_browser_process->profile_manager(); ProfileManager* profile_manager = g_browser_process->profile_manager();
// Create another profile. // Create another profile.
...@@ -1886,8 +1887,13 @@ class StartupBrowserCreatorPickerTest : public InProcessBrowserTest { ...@@ -1886,8 +1887,13 @@ class StartupBrowserCreatorPickerTest : public InProcessBrowserTest {
ASSERT_TRUE(other_profile); ASSERT_TRUE(other_profile);
StartupBrowserCreator launch; StartupBrowserCreator launch;
std::vector<Profile*> last_opened_profiles;
if (set_last_opened_profiles) {
last_opened_profiles.push_back(profile);
last_opened_profiles.push_back(other_profile);
}
ASSERT_TRUE(launch.Start(command_line, profile_manager->user_data_dir(), ASSERT_TRUE(launch.Start(command_line, profile_manager->user_data_dir(),
profile, {})); profile, last_opened_profiles));
} }
private: private:
...@@ -1972,6 +1978,16 @@ IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorPickerTest, SkipsPickerWithAppId) { ...@@ -1972,6 +1978,16 @@ IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorPickerTest, SkipsPickerWithAppId) {
EXPECT_TRUE(new_browser); EXPECT_TRUE(new_browser);
} }
IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorPickerTest,
SkipsPickerWithLastOpenedProfiles) {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
StartWithTwoProfiles(command_line, /*set_last_opened_profiles=*/true);
// Skips the picker and creates a new browser window.
Browser* new_browser = FindOneOtherBrowser(browser());
EXPECT_TRUE(new_browser);
}
class GuestStartupBrowserCreatorPickerTest class GuestStartupBrowserCreatorPickerTest
: public StartupBrowserCreatorPickerTest, : public StartupBrowserCreatorPickerTest,
public ::testing::WithParamInterface<bool> { public ::testing::WithParamInterface<bool> {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment