Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/profiles/profile_manager.h" | 5 #include "chrome/browser/profiles/profile_manager.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <map> | |
| 9 #include <set> | 10 #include <set> |
| 10 #include <string> | 11 #include <string> |
| 11 | 12 |
| 12 #include "base/bind.h" | 13 #include "base/bind.h" |
| 13 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 14 #include "base/deferred_sequenced_task_runner.h" | 15 #include "base/deferred_sequenced_task_runner.h" |
| 15 #include "base/feature_list.h" | 16 #include "base/feature_list.h" |
| 16 #include "base/files/file_enumerator.h" | 17 #include "base/files/file_enumerator.h" |
| 17 #include "base/files/file_path.h" | 18 #include "base/files/file_path.h" |
| 18 #include "base/files/file_util.h" | 19 #include "base/files/file_util.h" |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 124 #include "chrome/browser/profiles/profile_statistics.h" | 125 #include "chrome/browser/profiles/profile_statistics.h" |
| 125 #include "chrome/browser/profiles/profile_statistics_factory.h" | 126 #include "chrome/browser/profiles/profile_statistics_factory.h" |
| 126 #endif | 127 #endif |
| 127 | 128 |
| 128 using base::UserMetricsAction; | 129 using base::UserMetricsAction; |
| 129 using content::BrowserThread; | 130 using content::BrowserThread; |
| 130 | 131 |
| 131 namespace { | 132 namespace { |
| 132 | 133 |
| 133 // Profiles that should be deleted on shutdown. | 134 // Profiles that should be deleted on shutdown. |
| 134 std::vector<base::FilePath>& ProfilesToDelete() { | 135 enum class ProfileDeletionStage { SCHEDULED, ABANDONED }; |
| 135 CR_DEFINE_STATIC_LOCAL(std::vector<base::FilePath>, profiles_to_delete, ()); | 136 using ProfileDeletionMap = std::map<base::FilePath, ProfileDeletionStage>; |
| 137 // Profile deletion can pass thru two stages: scheduled for deletion when where | |
|
Bernhard Bauer
2016/08/04 12:24:34
Nit: "through". Also, would it make sense to move
| |
| 138 // performing necessary activity prior to deletion, and abandoned stage when it | |
|
Bernhard Bauer
2016/08/04 12:24:34
I think we can also go into detail about what the
| |
| 139 // can be safely removed from disk. | |
| 140 ProfileDeletionMap& ProfilesToDelete() { | |
| 141 CR_DEFINE_STATIC_LOCAL(ProfileDeletionMap, profiles_to_delete, ()); | |
| 136 return profiles_to_delete; | 142 return profiles_to_delete; |
| 137 } | 143 } |
| 138 | 144 |
| 139 int64_t ComputeFilesSize(const base::FilePath& directory, | 145 int64_t ComputeFilesSize(const base::FilePath& directory, |
| 140 const base::FilePath::StringType& pattern) { | 146 const base::FilePath::StringType& pattern) { |
| 141 int64_t running_size = 0; | 147 int64_t running_size = 0; |
| 142 base::FileEnumerator iter(directory, false, base::FileEnumerator::FILES, | 148 base::FileEnumerator iter(directory, false, base::FileEnumerator::FILES, |
| 143 pattern); | 149 pattern); |
| 144 while (!iter.Next().empty()) | 150 while (!iter.Next().empty()) |
| 145 running_size += iter.GetInfo().GetSize(); | 151 running_size += iter.GetInfo().GetSize(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 194 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Policy")); | 200 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Policy")); |
| 195 size_MB = static_cast<int>(size / kBytesInOneMB); | 201 size_MB = static_cast<int>(size / kBytesInOneMB); |
| 196 UMA_HISTOGRAM_COUNTS_10000("Profile.PolicySize", size_MB); | 202 UMA_HISTOGRAM_COUNTS_10000("Profile.PolicySize", size_MB); |
| 197 | 203 |
| 198 // Count number of enabled apps in this profile, if we know. | 204 // Count number of enabled apps in this profile, if we know. |
| 199 if (enabled_app_count != -1) | 205 if (enabled_app_count != -1) |
| 200 UMA_HISTOGRAM_COUNTS_10000("Profile.AppCount", enabled_app_count); | 206 UMA_HISTOGRAM_COUNTS_10000("Profile.AppCount", enabled_app_count); |
| 201 } | 207 } |
| 202 | 208 |
| 203 #if !defined(OS_ANDROID) | 209 #if !defined(OS_ANDROID) |
| 210 // Return true if profile can be scheduled for deletion. | |
|
Bernhard Bauer
2016/08/04 12:24:34
I think we should explain in the comment under whi
| |
| 211 bool ScheduleProfileDirectoryForDeletion(const base::FilePath& path) { | |
| 212 if (ContainsKey(ProfilesToDelete(), path)) | |
| 213 return false; | |
| 214 ProfilesToDelete()[path] = ProfileDeletionStage::SCHEDULED; | |
| 215 return true; | |
| 216 } | |
| 217 | |
| 204 void QueueProfileDirectoryForDeletion(const base::FilePath& path) { | 218 void QueueProfileDirectoryForDeletion(const base::FilePath& path) { |
|
Bernhard Bauer
2016/08/04 12:24:34
Should we maybe use the term "marked" for the seco
| |
| 205 ProfilesToDelete().push_back(path); | 219 DCHECK(!ContainsKey(ProfilesToDelete(), path) || |
| 220 ProfilesToDelete()[path] == ProfileDeletionStage::SCHEDULED); | |
| 221 ProfilesToDelete()[path] = ProfileDeletionStage::ABANDONED; | |
| 206 } | 222 } |
| 207 #endif | 223 #endif |
| 208 | 224 |
| 209 bool IsProfileMarkedForDeletion(const base::FilePath& profile_path) { | 225 bool IsProfileMarkedForDeletion(const base::FilePath& profile_path) { |
|
Bernhard Bauer
2016/08/04 12:24:34
For consistency, this method should then probably
| |
| 210 return std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(), | 226 auto it = ProfilesToDelete().find(profile_path); |
| 211 profile_path) != ProfilesToDelete().end(); | 227 return it != ProfilesToDelete().end() && |
| 228 it->second == ProfileDeletionStage::ABANDONED; | |
| 212 } | 229 } |
| 213 | 230 |
| 214 // Physically remove deleted profile directories from disk. | 231 // Physically remove deleted profile directories from disk. |
| 215 void NukeProfileFromDisk(const base::FilePath& profile_path) { | 232 void NukeProfileFromDisk(const base::FilePath& profile_path) { |
| 216 // Delete both the profile directory and its corresponding cache. | 233 // Delete both the profile directory and its corresponding cache. |
| 217 base::FilePath cache_path; | 234 base::FilePath cache_path; |
| 218 chrome::GetUserCacheDirectory(profile_path, &cache_path); | 235 chrome::GetUserCacheDirectory(profile_path, &cache_path); |
| 219 base::DeleteFile(profile_path, true); | 236 base::DeleteFile(profile_path, true); |
| 220 base::DeleteFile(cache_path, true); | 237 base::DeleteFile(cache_path, true); |
| 221 } | 238 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 326 if (!pm) // Is NULL when running unit tests. | 343 if (!pm) // Is NULL when running unit tests. |
| 327 return; | 344 return; |
| 328 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); | 345 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); |
| 329 for (size_t i = 0; i < profiles.size(); ++i) | 346 for (size_t i = 0; i < profiles.size(); ++i) |
| 330 SessionServiceFactory::ShutdownForProfile(profiles[i]); | 347 SessionServiceFactory::ShutdownForProfile(profiles[i]); |
| 331 } | 348 } |
| 332 #endif | 349 #endif |
| 333 | 350 |
| 334 // static | 351 // static |
| 335 void ProfileManager::NukeDeletedProfilesFromDisk() { | 352 void ProfileManager::NukeDeletedProfilesFromDisk() { |
| 336 for (std::vector<base::FilePath>::iterator it = | 353 for (const auto& item : ProfilesToDelete()) { |
| 337 ProfilesToDelete().begin(); | 354 if (item.second == ProfileDeletionStage::ABANDONED) |
| 338 it != ProfilesToDelete().end(); | 355 NukeProfileFromDisk(item.first); |
| 339 ++it) { | |
| 340 NukeProfileFromDisk(*it); | |
| 341 } | 356 } |
| 342 ProfilesToDelete().clear(); | 357 ProfilesToDelete().clear(); |
| 343 } | 358 } |
| 344 | 359 |
| 345 // static | 360 // static |
| 346 Profile* ProfileManager::GetLastUsedProfile() { | 361 Profile* ProfileManager::GetLastUsedProfile() { |
| 347 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 362 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 348 return profile_manager->GetLastUsedProfile(profile_manager->user_data_dir_); | 363 return profile_manager->GetLastUsedProfile(profile_manager->user_data_dir_); |
| 349 } | 364 } |
| 350 | 365 |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 728 | 743 |
| 729 ProfileShortcutManager* ProfileManager::profile_shortcut_manager() { | 744 ProfileShortcutManager* ProfileManager::profile_shortcut_manager() { |
| 730 return profile_shortcut_manager_.get(); | 745 return profile_shortcut_manager_.get(); |
| 731 } | 746 } |
| 732 | 747 |
| 733 #if !defined(OS_ANDROID) | 748 #if !defined(OS_ANDROID) |
| 734 bool ProfileManager::MaybeScheduleProfileForDeletion( | 749 bool ProfileManager::MaybeScheduleProfileForDeletion( |
| 735 const base::FilePath& profile_dir, | 750 const base::FilePath& profile_dir, |
| 736 const CreateCallback& callback, | 751 const CreateCallback& callback, |
| 737 ProfileMetrics::ProfileDelete deletion_source) { | 752 ProfileMetrics::ProfileDelete deletion_source) { |
| 738 if (IsProfileMarkedForDeletion(profile_dir)) | 753 if (!ScheduleProfileDirectoryForDeletion(profile_dir)) |
| 739 return false; | 754 return false; |
| 740 ScheduleProfileForDeletion(profile_dir, callback); | 755 ScheduleProfileForDeletion(profile_dir, callback); |
| 741 ProfileMetrics::LogProfileDeleteUser(deletion_source); | 756 ProfileMetrics::LogProfileDeleteUser(deletion_source); |
| 742 return true; | 757 return true; |
| 743 } | 758 } |
| 744 | 759 |
| 745 void ProfileManager::ScheduleProfileForDeletion( | 760 void ProfileManager::ScheduleProfileForDeletion( |
| 746 const base::FilePath& profile_dir, | 761 const base::FilePath& profile_dir, |
| 747 const CreateCallback& callback) { | 762 const CreateCallback& callback) { |
| 748 DCHECK(profiles::IsMultipleProfilesEnabled()); | 763 DCHECK(profiles::IsMultipleProfilesEnabled()); |
| (...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1627 | 1642 |
| 1628 FinishDeletingProfile(profile_to_delete_path, new_active_profile_path); | 1643 FinishDeletingProfile(profile_to_delete_path, new_active_profile_path); |
| 1629 if (!original_callback.is_null()) | 1644 if (!original_callback.is_null()) |
| 1630 original_callback.Run(loaded_profile, status); | 1645 original_callback.Run(loaded_profile, status); |
| 1631 } | 1646 } |
| 1632 #endif // !defined(OS_ANDROID) | 1647 #endif // !defined(OS_ANDROID) |
| 1633 | 1648 |
| 1634 ProfileManagerWithoutInit::ProfileManagerWithoutInit( | 1649 ProfileManagerWithoutInit::ProfileManagerWithoutInit( |
| 1635 const base::FilePath& user_data_dir) : ProfileManager(user_data_dir) { | 1650 const base::FilePath& user_data_dir) : ProfileManager(user_data_dir) { |
| 1636 } | 1651 } |
| OLD | NEW |