Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: chrome/browser/apps/ephemeral_app_service.cc

Issue 383703002: Clear the ephemeral app cache from Clear Browsing Data (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed review comments for tests Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/apps/ephemeral_app_service.h" 5 #include "chrome/browser/apps/ephemeral_app_service.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "chrome/browser/apps/ephemeral_app_service_factory.h" 8 #include "chrome/browser/apps/ephemeral_app_service_factory.h"
9 #include "chrome/browser/chrome_notification_types.h" 9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/extensions/extension_service.h" 10 #include "chrome/browser/extensions/extension_service.h"
11 #include "chrome/browser/extensions/extension_util.h" 11 #include "chrome/browser/extensions/extension_util.h"
12 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/common/chrome_switches.h" 13 #include "chrome/common/chrome_switches.h"
14 #include "content/public/browser/notification_service.h" 14 #include "content/public/browser/notification_service.h"
15 #include "content/public/browser/notification_source.h" 15 #include "content/public/browser/notification_source.h"
16 #include "content/public/browser/notification_types.h" 16 #include "content/public/browser/notification_types.h"
17 #include "extensions/browser/extension_prefs.h" 17 #include "extensions/browser/extension_prefs.h"
18 #include "extensions/browser/extension_registry.h" 18 #include "extensions/browser/extension_registry.h"
19 #include "extensions/browser/extension_system.h" 19 #include "extensions/browser/extension_system.h"
20 #include "extensions/browser/extension_util.h" 20 #include "extensions/browser/extension_util.h"
21 #include "extensions/common/extension.h" 21 #include "extensions/common/extension.h"
22 #include "extensions/common/extension_set.h" 22 #include "extensions/common/extension_set.h"
23 23
24 using extensions::Extension; 24 using extensions::Extension;
25 using extensions::ExtensionPrefs; 25 using extensions::ExtensionPrefs;
26 using extensions::ExtensionRegistry;
26 using extensions::ExtensionSet; 27 using extensions::ExtensionSet;
27 using extensions::ExtensionSystem; 28 using extensions::ExtensionSystem;
28 29
29 namespace { 30 namespace {
30 31
31 // The number of seconds after startup before performing garbage collection 32 // The number of seconds after startup before performing garbage collection
32 // of ephemeral apps. 33 // of ephemeral apps.
33 const int kGarbageCollectAppsStartupDelay = 60; 34 const int kGarbageCollectAppsStartupDelay = 60;
34 35
35 // The number of seconds after an ephemeral app has been installed before 36 // The number of seconds after an ephemeral app has been installed before
(...skipping 17 matching lines...) Expand all
53 } 54 }
54 55
55 EphemeralAppService::EphemeralAppService(Profile* profile) 56 EphemeralAppService::EphemeralAppService(Profile* profile)
56 : profile_(profile), 57 : profile_(profile),
57 extension_registry_observer_(this), 58 extension_registry_observer_(this),
58 ephemeral_app_count_(-1) { 59 ephemeral_app_count_(-1) {
59 if (!CommandLine::ForCurrentProcess()->HasSwitch( 60 if (!CommandLine::ForCurrentProcess()->HasSwitch(
60 switches::kEnableEphemeralApps)) 61 switches::kEnableEphemeralApps))
61 return; 62 return;
62 63
63 extension_registry_observer_.Add( 64 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
64 extensions::ExtensionRegistry::Get(profile_));
65 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, 65 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY,
66 content::Source<Profile>(profile_)); 66 content::Source<Profile>(profile_));
67 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 67 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
68 content::Source<Profile>(profile_)); 68 content::Source<Profile>(profile_));
69 } 69 }
70 70
71 EphemeralAppService::~EphemeralAppService() { 71 EphemeralAppService::~EphemeralAppService() {
72 } 72 }
73 73
74 void EphemeralAppService::ClearCachedApps() {
75 // Cancel any pending garbage collects.
76 garbage_collect_apps_timer_.Stop();
77
78 ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
79 DCHECK(registry);
80 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_);
81 DCHECK(prefs);
82 ExtensionService* service =
83 ExtensionSystem::Get(profile_)->extension_service();
84 DCHECK(service);
85
86 scoped_ptr<ExtensionSet> extensions =
87 registry->GenerateInstalledExtensionsSet();
88
89 for (ExtensionSet::const_iterator it = extensions->begin();
90 it != extensions->end();
91 ++it) {
92 std::string extension_id = (*it)->id();
93 if (!prefs->IsEphemeralApp(extension_id))
94 continue;
95
96 // Do not remove apps that are running.
97 if (!extensions::util::IsExtensionIdle(extension_id, profile_))
98 continue;
99
100 DCHECK(registry->GetExtensionById(extension_id,
101 ExtensionRegistry::EVERYTHING));
102 service->UninstallExtension(
103 extension_id,
104 ExtensionService::UNINSTALL_REASON_ORPHANED_EPHEMERAL_EXTENSION,
105 NULL);
106 }
107 }
108
74 void EphemeralAppService::Observe( 109 void EphemeralAppService::Observe(
75 int type, 110 int type,
76 const content::NotificationSource& source, 111 const content::NotificationSource& source,
77 const content::NotificationDetails& details) { 112 const content::NotificationDetails& details) {
78 switch (type) { 113 switch (type) {
79 case chrome::NOTIFICATION_EXTENSIONS_READY: { 114 case chrome::NOTIFICATION_EXTENSIONS_READY: {
80 Init(); 115 Init();
81 break; 116 break;
82 } 117 }
83 case chrome::NOTIFICATION_PROFILE_DESTROYED: { 118 case chrome::NOTIFICATION_PROFILE_DESTROYED: {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 } 155 }
121 156
122 void EphemeralAppService::Init() { 157 void EphemeralAppService::Init() {
123 InitEphemeralAppCount(); 158 InitEphemeralAppCount();
124 TriggerGarbageCollect( 159 TriggerGarbageCollect(
125 base::TimeDelta::FromSeconds(kGarbageCollectAppsStartupDelay)); 160 base::TimeDelta::FromSeconds(kGarbageCollectAppsStartupDelay));
126 } 161 }
127 162
128 void EphemeralAppService::InitEphemeralAppCount() { 163 void EphemeralAppService::InitEphemeralAppCount() {
129 scoped_ptr<ExtensionSet> extensions = 164 scoped_ptr<ExtensionSet> extensions =
130 extensions::ExtensionRegistry::Get(profile_) 165 ExtensionRegistry::Get(profile_)->GenerateInstalledExtensionsSet();
131 ->GenerateInstalledExtensionsSet();
132 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_); 166 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_);
133 DCHECK(prefs); 167 DCHECK(prefs);
134 168
135 ephemeral_app_count_ = 0; 169 ephemeral_app_count_ = 0;
136 for (ExtensionSet::const_iterator it = extensions->begin(); 170 for (ExtensionSet::const_iterator it = extensions->begin();
137 it != extensions->end(); ++it) { 171 it != extensions->end(); ++it) {
138 const Extension* extension = *it; 172 const Extension* extension = *it;
139 if (prefs->IsEphemeralApp(extension->id())) 173 if (prefs->IsEphemeralApp(extension->id()))
140 ++ephemeral_app_count_; 174 ++ephemeral_app_count_;
141 } 175 }
142 } 176 }
143 177
144 void EphemeralAppService::TriggerGarbageCollect(const base::TimeDelta& delay) { 178 void EphemeralAppService::TriggerGarbageCollect(const base::TimeDelta& delay) {
145 if (!garbage_collect_apps_timer_.IsRunning()) { 179 if (!garbage_collect_apps_timer_.IsRunning()) {
146 garbage_collect_apps_timer_.Start( 180 garbage_collect_apps_timer_.Start(
147 FROM_HERE, 181 FROM_HERE,
148 delay, 182 delay,
149 this, 183 this,
150 &EphemeralAppService::GarbageCollectApps); 184 &EphemeralAppService::GarbageCollectApps);
151 } 185 }
152 } 186 }
153 187
154 void EphemeralAppService::GarbageCollectApps() { 188 void EphemeralAppService::GarbageCollectApps() {
155 scoped_ptr<ExtensionSet> extensions = 189 ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
156 extensions::ExtensionRegistry::Get(profile_) 190 DCHECK(registry);
157 ->GenerateInstalledExtensionsSet();
158 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_); 191 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_);
159 DCHECK(prefs); 192 DCHECK(prefs);
160 193
194 scoped_ptr<ExtensionSet> extensions =
195 registry->GenerateInstalledExtensionsSet();
196
161 int app_count = 0; 197 int app_count = 0;
162 LaunchTimeAppMap app_launch_times; 198 LaunchTimeAppMap app_launch_times;
163 std::set<std::string> remove_app_ids; 199 std::set<std::string> remove_app_ids;
164 200
165 // Populate a list of ephemeral apps, ordered by their last launch time. 201 // Populate a list of ephemeral apps, ordered by their last launch time.
166 for (ExtensionSet::const_iterator it = extensions->begin(); 202 for (ExtensionSet::const_iterator it = extensions->begin();
167 it != extensions->end(); ++it) { 203 it != extensions->end(); ++it) {
168 const Extension* extension = *it; 204 const Extension* extension = *it;
169 if (!prefs->IsEphemeralApp(extension->id())) 205 if (!prefs->IsEphemeralApp(extension->id()))
170 continue; 206 continue;
(...skipping 11 matching lines...) Expand all
182 // the app will be removed. 218 // the app will be removed.
183 if (last_launch_time.is_null()) 219 if (last_launch_time.is_null())
184 last_launch_time = prefs->GetInstallTime(extension->id()); 220 last_launch_time = prefs->GetInstallTime(extension->id());
185 221
186 app_launch_times.insert(std::make_pair(last_launch_time, extension->id())); 222 app_launch_times.insert(std::make_pair(last_launch_time, extension->id()));
187 } 223 }
188 224
189 ExtensionService* service = 225 ExtensionService* service =
190 ExtensionSystem::Get(profile_)->extension_service(); 226 ExtensionSystem::Get(profile_)->extension_service();
191 DCHECK(service); 227 DCHECK(service);
192 // Execute the replacement policies and remove apps marked for deletion. 228 // Execute the eviction policies and remove apps marked for deletion.
193 if (!app_launch_times.empty()) { 229 if (!app_launch_times.empty()) {
194 GetAppsToRemove(app_count, app_launch_times, &remove_app_ids); 230 GetAppsToRemove(app_count, app_launch_times, &remove_app_ids);
231
195 for (std::set<std::string>::const_iterator id = remove_app_ids.begin(); 232 for (std::set<std::string>::const_iterator id = remove_app_ids.begin();
196 id != remove_app_ids.end(); ++id) { 233 id != remove_app_ids.end(); ++id) {
197 if (service->UninstallExtension( 234 // Protect against cascading uninstalls.
198 *id, 235 if (!registry->GetExtensionById(*id, ExtensionRegistry::EVERYTHING))
199 ExtensionService::UNINSTALL_REASON_ORPHANED_EPHEMERAL_EXTENSION, 236 continue;
200 NULL)) { 237
201 --app_count; 238 service->UninstallExtension(
202 } 239 *id,
240 ExtensionService::UNINSTALL_REASON_ORPHANED_EPHEMERAL_EXTENSION,
241 NULL);
203 } 242 }
204 } 243 }
205
206 ephemeral_app_count_ = app_count;
207 } 244 }
208 245
209 // static 246 // static
210 void EphemeralAppService::GetAppsToRemove( 247 void EphemeralAppService::GetAppsToRemove(
211 int app_count, 248 int app_count,
212 const LaunchTimeAppMap& app_launch_times, 249 const LaunchTimeAppMap& app_launch_times,
213 std::set<std::string>* remove_app_ids) { 250 std::set<std::string>* remove_app_ids) {
214 base::Time time_now = base::Time::Now(); 251 base::Time time_now = base::Time::Now();
215 const base::Time inactive_threshold = 252 const base::Time inactive_threshold =
216 time_now - base::TimeDelta::FromDays(kAppInactiveThreshold); 253 time_now - base::TimeDelta::FromDays(kAppInactiveThreshold);
(...skipping 11 matching lines...) Expand all
228 // Remove ephemeral apps that have been inactive for a while or if the cache 265 // Remove ephemeral apps that have been inactive for a while or if the cache
229 // is larger than the desired size. 266 // is larger than the desired size.
230 if (it->first < inactive_threshold || app_count > kMaxEphemeralAppsCount) { 267 if (it->first < inactive_threshold || app_count > kMaxEphemeralAppsCount) {
231 remove_app_ids->insert(it->second); 268 remove_app_ids->insert(it->second);
232 --app_count; 269 --app_count;
233 } else { 270 } else {
234 break; 271 break;
235 } 272 }
236 } 273 }
237 } 274 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698