Index: chrome/browser/chrome_browser_main.cc |
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc |
index c496ffe34032dc98f91d26d70326ab24f6248eb8..b2596e4ce71b25927ba04444ad9c17f76dd10482 100644 |
--- a/chrome/browser/chrome_browser_main.cc |
+++ b/chrome/browser/chrome_browser_main.cc |
@@ -90,6 +90,7 @@ |
#include "chrome/browser/ui/app_modal/chrome_javascript_native_dialog_factory.h" |
#include "chrome/browser/ui/browser.h" |
#include "chrome/browser/ui/browser_finder.h" |
+#include "chrome/browser/ui/simple_message_box.h" |
#include "chrome/browser/ui/startup/bad_flags_prompt.h" |
#include "chrome/browser/ui/startup/default_browser_prompt.h" |
#include "chrome/browser/ui/startup/startup_browser_creator.h" |
@@ -389,7 +390,7 @@ Profile* CreatePrimaryProfile(const content::MainFunctionParams& parameters, |
profile_list->Clear(); |
} |
- Profile* profile = NULL; |
+ Profile* profile = nullptr; |
#if defined(OS_CHROMEOS) || defined(OS_ANDROID) |
// On ChromeOS and Android the ProfileManager will use the same path as the |
// one we got passed. GetActiveUserProfile will therefore use the correct path |
@@ -401,25 +402,91 @@ Profile* CreatePrimaryProfile(const content::MainFunctionParams& parameters, |
base::FilePath profile_path = |
GetStartupProfilePath(user_data_dir, parsed_command_line); |
- profile = g_browser_process->profile_manager()->GetProfile( |
- profile_path); |
+ ProfileManager* profile_manager = g_browser_process->profile_manager(); |
+ profile = profile_manager->GetProfile(profile_path); |
- // If we're using the --new-profile-management flag and this profile is |
- // signed out, then we should show the user manager instead. By switching |
- // the active profile to the guest profile we ensure that no |
- // browser windows will be opened for the guest profile. |
+ // If we're using the --new-profile-management flag and this profile is signed |
+ // out, then we should show the user manager instead. By switching the active |
+ // profile to the guest profile we ensure that no browser windows will be |
+ // opened for the guest profile. The initialization of guest profile is |
+ // possible to fail. |
if (switches::IsNewProfileManagement() && |
profile && |
!profile->IsGuestSession()) { |
ProfileAttributesEntry* entry; |
- bool has_entry = g_browser_process->profile_manager()-> |
- GetProfileAttributesStorage(). |
- GetProfileAttributesWithPath(profile_path, &entry); |
+ bool has_entry = g_browser_process->profile_manager() |
+ ->GetProfileAttributesStorage() |
+ .GetProfileAttributesWithPath(profile_path, &entry); |
if (has_entry && entry->IsSigninRequired()) { |
- profile = g_browser_process->profile_manager()->GetProfile( |
- ProfileManager::GetGuestProfilePath()); |
+ profile = profile_manager->GetProfile( |
+ ProfileManager::GetGuestProfilePath()); |
} |
} |
+ |
+ // If the user specified a profile and it fails to initialize, do not start |
+ // chromium. |
+ if (profiles::IsMultipleProfilesEnabled() && |
+ parsed_command_line.HasSwitch(switches::kProfileDirectory) && |
+ !profile) { |
+ chrome::ShowWarningMessageBox(NULL, |
+ base::UTF8ToUTF16("Unable to start chrome"), |
+ base::UTF8ToUTF16("Cannot open or create the specified profile.")); |
+ return nullptr; |
WC Leung
2016/06/06 20:01:36
We need to get help from the UI team to determine
|
+ } |
+ |
+ // If the last used profile is unable to initialize, see if any of other last |
+ // opened profiles can initialize successfully. At this stage we assume |
+ // creation of all new profile (including guest profile) to fail. |
+ if (!profile) { |
+ std::vector<Profile*> last_opened_profiles = |
+ ProfileManager::GetLastOpenedProfiles(); |
+ // Get the first profile that is not signed out.. |
+ if (last_opened_profiles.size()) { |
+ for (Profile* last_opened_profile : last_opened_profiles) { |
+ ProfileAttributesEntry* entry; |
+ bool has_entry = |
+ g_browser_process->profile_manager() |
+ ->GetProfileAttributesStorage() |
+ .GetProfileAttributesWithPath(profile->GetPath(), |
+ &entry); |
+ if (!has_entry || !entry->IsSigninRequired()) { |
+ profile = last_opened_profile; |
+ break; |
+ } |
+ } |
+ } |
+ } |
+ |
+ // If it still fails, try to create a guest profile. Show the user manager |
+ // if this is successful. |
+ if (!profile) { |
+ profile = profile_manager->GetProfile( |
+ ProfileManager::GetGuestProfilePath()); |
+ } |
+ |
+ // If still fails, try to open any non-signin profile. |
+ if (!profile) { |
+ std::vector<ProfileAttributesEntry*> entries = |
+ profile_manager->GetProfileAttributesStorage() |
+ .GetAllProfilesAttributes(); |
+ for (ProfileAttributesEntry* entry : entries) { |
+ if (!entry->IsSigninRequired()) { |
+ profile = profile_manager->GetProfile(entry->GetPath()); |
+ if (profile) |
+ break; |
+ } |
+ } |
+ } |
+ |
+ // If it continues to fail, we have to show an error message and give up. |
+ if (!profile) { |
+ chrome::ShowWarningMessageBox(NULL, |
+ base::UTF8ToUTF16("Unable to start chrome"), |
+ base::UTF8ToUTF16( |
+ "Cannot load or create any profile in the user data directory.\n" |
+ "The user data directory is possibly corrupted.")); |
WC Leung
2016/06/06 20:01:36
Same for here. Anyway, should we also add some UMA
|
+ return nullptr; |
+ } |
#endif // defined(OS_CHROMEOS) || defined(OS_ANDROID) |
if (profile) { |
UMA_HISTOGRAM_LONG_TIMES( |
@@ -427,14 +494,12 @@ Profile* CreatePrimaryProfile(const content::MainFunctionParams& parameters, |
return profile; |
} |
-#if !defined(OS_WIN) |
// TODO(port): fix this. See comments near the definition of |
// user_data_dir. It is better to CHECK-fail here than it is to |
// silently exit because of missing code in the above test. |
CHECK(profile) << "Cannot get default profile."; |
-#endif // !defined(OS_WIN) |
- return NULL; |
+ return nullptr; |
} |
#if defined(OS_MACOSX) |