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

Side by Side Diff: chrome/browser/extensions/extension_storage_monitor.cc

Issue 2923663002: ExtensionStorageMonitor: use smaller, self-registering StorageObservers (Closed)
Patch Set: Fiddling. Created 3 years, 6 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/extensions/extension_storage_monitor.h" 5 #include "chrome/browser/extensions/extension_storage_monitor.h"
6 6
7 #include <map> 7 #include <map>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/metrics/histogram_macros.h" 10 #include "base/metrics/histogram_macros.h"
(...skipping 27 matching lines...) Expand all
38 #include "ui/message_center/notifier_settings.h" 38 #include "ui/message_center/notifier_settings.h"
39 #include "ui/message_center/views/constants.h" 39 #include "ui/message_center/views/constants.h"
40 40
41 using content::BrowserThread; 41 using content::BrowserThread;
42 42
43 namespace extensions { 43 namespace extensions {
44 44
45 namespace { 45 namespace {
46 46
47 // The rate at which we would like to observe storage events. 47 // The rate at which we would like to observe storage events.
48 const int kStorageEventRateSec = 30; 48 const base::TimeDelta kStorageEventRate = base::TimeDelta::FromSeconds(30);
Devlin 2017/06/12 20:15:05 is this allowed by our sizing/POD rules?
ncarter (slow) 2017/06/12 22:52:07 Good catch. TimeDelta has a constexpr ctor, but it
49 49
50 // Set the thresholds for the first notification. Once a threshold is exceeded, 50 // Set the thresholds for the first notification. Once a threshold is exceeded,
51 // it will be doubled to throttle notifications. 51 // it will be doubled to throttle notifications.
52 const int64_t kMBytes = 1024 * 1024; 52 const int64_t kMBytes = 1024 * 1024;
53 const int64_t kExtensionInitialThreshold = 1000 * kMBytes; 53 const int64_t kExtensionInitialThreshold = 1000 * kMBytes;
54 54
55 // Notifications have an ID so that we can update them. 55 // Notifications have an ID so that we can update them.
56 const char kNotificationIdFormat[] = "ExtensionStorageMonitor-$1-$2"; 56 const char kNotificationIdFormat[] = "ExtensionStorageMonitor-$1-$2";
57 const char kSystemNotifierId[] = "ExtensionStorageMonitor"; 57 const char kSystemNotifierId[] = "ExtensionStorageMonitor";
58 58
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 // Note we use COUNTS_100 (instead of PERCENT) because this can potentially 92 // Note we use COUNTS_100 (instead of PERCENT) because this can potentially
93 // exceed 100%. 93 // exceed 100%.
94 UMA_HISTOGRAM_COUNTS_100( 94 UMA_HISTOGRAM_COUNTS_100(
95 "Extensions.HostedAppUnlimitedStorageTemporaryStorageUsage", 95 "Extensions.HostedAppUnlimitedStorageTemporaryStorageUsage",
96 100.0 * usage / settings.per_host_quota); 96 100.0 * usage / settings.per_host_quota);
97 } 97 }
98 } 98 }
99 99
100 } // namespace 100 } // namespace
101 101
102 // StorageEventObserver monitors the storage usage of extensions and lives on 102 // SingleExtensionStorageObserver monitors the storage usage of one extension,
103 // the IO thread. When a threshold is exceeded, a message will be posted to the 103 // and lives on the IO thread. When a threshold is exceeded, a message will be
104 // UI thread, which displays the notification. 104 // posted to the ExtensionStorageMonitor on the UI thread, which displays the
105 class StorageEventObserver 105 // notification.
106 : public base::RefCountedThreadSafe<StorageEventObserver, 106 class SingleExtensionStorageObserver : public storage::StorageObserver {
107 BrowserThread::DeleteOnIOThread>,
108 public storage::StorageObserver {
109 public: 107 public:
110 explicit StorageEventObserver( 108 SingleExtensionStorageObserver(
111 base::WeakPtr<ExtensionStorageMonitor> storage_monitor) 109 ExtensionStorageMonitorIOHelper* io_helper,
112 : storage_monitor_(storage_monitor) { 110 const std::string& extension_id,
111 scoped_refptr<storage::QuotaManager> quota_manager,
112 const GURL& origin,
113 int64_t next_threshold,
114 base::TimeDelta rate,
115 bool should_uma)
116 : io_helper_(io_helper),
117 extension_id_(extension_id),
118 quota_manager_(std::move(quota_manager)),
119 next_threshold_(next_threshold),
120 should_uma_(should_uma) {
121 // We always observe persistent storage usage.
122 storage::StorageObserver::MonitorParams params(
123 storage::kStorageTypePersistent, origin, rate, false);
124 quota_manager_->AddStorageObserver(this, params);
125 if (should_uma) {
126 // And if this is for uma, we also observe temporary storage usage.
127 MonitorParams temporary_params(storage::kStorageTypeTemporary, origin,
128 rate, false);
129 quota_manager_->AddStorageObserver(this, temporary_params);
130 }
113 } 131 }
114 132
115 // Register as an observer for the extension's storage events. 133 ~SingleExtensionStorageObserver() override {
134 // This removes all our registrations.
135 quota_manager_->RemoveStorageObserver(this);
136 }
137
138 void set_next_threshold(int64_t next_threshold) {
139 next_threshold_ = next_threshold;
140 }
141
142 // storage::StorageObserver implementation.
143 void OnStorageEvent(const Event& event) override;
144
145 private:
146 // The IO thread helper that owns this instance.
147 ExtensionStorageMonitorIOHelper* const io_helper_;
Devlin 2017/06/12 20:15:05 This seems to only be used to get a weak ptr to th
ncarter (slow) 2017/06/12 22:52:07 We could, but we'd still have to retain the WeakPt
148
149 // The extension associated with the origin under observation.
150 const std::string extension_id_;
151
152 // The quota manager being observed, corresponding to the extension's storage
153 // partition.
154 scoped_refptr<storage::QuotaManager> quota_manager_;
155
156 // If |next_threshold| is -1, it signifies that we should not enforce (and
157 // only track) storage for this extension.
158 int64_t next_threshold_;
159
160 const bool should_uma_;
161
162 DISALLOW_COPY_AND_ASSIGN(SingleExtensionStorageObserver);
163 };
164
165 // The IO thread part of ExtensionStorageMonitor. This class manages a flock of
166 // SingleExtensionStorageObserver instances, one for each tracked extension.
167 // This class is owned by, and reports back to, ExtensionStorageMonitor.
168 class ExtensionStorageMonitorIOHelper
169 : public base::RefCountedThreadSafe<ExtensionStorageMonitorIOHelper,
170 BrowserThread::DeleteOnIOThread> {
171 public:
172 explicit ExtensionStorageMonitorIOHelper(
173 base::WeakPtr<ExtensionStorageMonitor> extension_storage_monitor)
174 : extension_storage_monitor_(std::move(extension_storage_monitor)) {}
175
176 // Register a StorageObserver for the extension's storage events.
116 void StartObservingForExtension( 177 void StartObservingForExtension(
117 scoped_refptr<storage::QuotaManager> quota_manager, 178 scoped_refptr<storage::QuotaManager> quota_manager,
118 const std::string& extension_id, 179 const std::string& extension_id,
119 const GURL& site_url, 180 const GURL& site_url,
120 int64_t next_threshold, 181 int64_t next_threshold,
121 const base::TimeDelta& rate, 182 const base::TimeDelta& rate,
122 bool should_uma) { 183 bool should_uma) {
123 DCHECK_CURRENTLY_ON(BrowserThread::IO); 184 DCHECK_CURRENTLY_ON(BrowserThread::IO);
124 DCHECK(quota_manager.get()); 185 DCHECK(quota_manager.get());
125 186
126 GURL origin = site_url.GetOrigin(); 187 DCHECK(!FindObserver(extension_id));
127 StorageState& state = origin_state_map_[origin];
128 state.quota_manager = quota_manager;
129 state.extension_id = extension_id;
130 state.next_threshold = next_threshold;
131 state.should_uma = should_uma;
132 188
133 // We always observe persistent storage usage. 189 storage_observers_[extension_id] =
134 storage::StorageObserver::MonitorParams params( 190 base::MakeUnique<SingleExtensionStorageObserver>(
135 storage::kStorageTypePersistent, origin, rate, false); 191 this, extension_id, std::move(quota_manager), site_url.GetOrigin(),
136 quota_manager->AddStorageObserver(this, params); 192 next_threshold, rate, should_uma);
137 if (should_uma) {
138 // And if this is for uma, we also observe temporary storage usage.
139 MonitorParams temporary_params(
140 storage::kStorageTypeTemporary, origin, rate, false);
141 quota_manager->AddStorageObserver(this, temporary_params);
142 }
143 } 193 }
144 194
145 // Updates the threshold for an extension already being monitored. 195 // Updates the threshold for an extension already being monitored.
146 void UpdateThresholdForExtension(const std::string& extension_id, 196 void UpdateThresholdForExtension(const std::string& extension_id,
147 int64_t next_threshold) { 197 int64_t next_threshold) {
148 DCHECK_CURRENTLY_ON(BrowserThread::IO); 198 DCHECK_CURRENTLY_ON(BrowserThread::IO);
149 199
150 for (OriginStorageStateMap::iterator it = origin_state_map_.begin(); 200 SingleExtensionStorageObserver* observer = FindObserver(extension_id);
151 it != origin_state_map_.end(); 201 if (observer)
152 ++it) { 202 observer->set_next_threshold(next_threshold);
153 if (it->second.extension_id == extension_id) {
154 it->second.next_threshold = next_threshold;
155 break;
156 }
157 }
158 } 203 }
159 204
160 // Deregister as an observer for the extension's storage events. 205 // Deregister as an observer for the extension's storage events.
161 void StopObservingForExtension(const std::string& extension_id) { 206 void StopObservingForExtension(const std::string& extension_id) {
162 DCHECK_CURRENTLY_ON(BrowserThread::IO); 207 DCHECK_CURRENTLY_ON(BrowserThread::IO);
163 208
164 for (OriginStorageStateMap::iterator it = origin_state_map_.begin(); 209 // Note that |extension_id| may not be in the map, since
165 it != origin_state_map_.end(); ) { 210 // some extensions may be exempt from monitoring.
Devlin 2017/06/12 20:15:05 Maybe worth duplicating this comment on line 200?
ncarter (slow) 2017/06/12 22:52:07 Done.
166 if (it->second.extension_id == extension_id) { 211 storage_observers_.erase(extension_id);
167 storage::StorageObserver::Filter filter(
168 storage::kStorageTypePersistent, it->first);
169 it->second.quota_manager->RemoveStorageObserverForFilter(this, filter);
170 // We also need to unregister temporary storage observation, if this was
171 // being tracked for uma.
172 if (it->second.should_uma) {
173 storage::StorageObserver::Filter temporary_filter(
174 storage::kStorageTypeTemporary, it->first);
175 it->second.quota_manager->RemoveStorageObserverForFilter(this,
176 filter);
ncarter (slow) 2017/06/12 18:31:29 |filter| here should be |temporary_filter|, and if
177 }
178 origin_state_map_.erase(it++);
179 } else {
180 ++it;
181 }
182 }
183 } 212 }
184 213
185 // Stop observing all storage events. Called during shutdown. 214 base::WeakPtr<ExtensionStorageMonitor> extension_storage_monitor() {
186 void StopObserving() { 215 return extension_storage_monitor_;
187 DCHECK_CURRENTLY_ON(BrowserThread::IO);
188
189 for (OriginStorageStateMap::iterator it = origin_state_map_.begin();
190 it != origin_state_map_.end(); ++it) {
191 it->second.quota_manager->RemoveStorageObserver(this);
192 }
193 origin_state_map_.clear();
194 } 216 }
195 217
196 private: 218 private:
197 friend class base::DeleteHelper<StorageEventObserver>; 219 friend class base::DeleteHelper<ExtensionStorageMonitorIOHelper>;
198 friend struct content::BrowserThread::DeleteOnThread< 220 friend struct content::BrowserThread::DeleteOnThread<
199 content::BrowserThread::IO>; 221 content::BrowserThread::IO>;
200 222
201 struct StorageState { 223 ~ExtensionStorageMonitorIOHelper() {}
202 scoped_refptr<storage::QuotaManager> quota_manager;
203 224
204 std::string extension_id; 225 SingleExtensionStorageObserver* FindObserver(
205 226 const std::string& extension_id) {
206 // If |next_threshold| is -1, it signifies that we should not enforce (and 227 auto it = storage_observers_.find(extension_id);
207 // only track) storage for this extension. 228 if (it != storage_observers_.end())
208 int64_t next_threshold; 229 return it->second.get();
209 230 return nullptr;
210 bool should_uma;
211
212 StorageState() : next_threshold(-1), should_uma(false) {}
213 };
214 typedef std::map<GURL, StorageState> OriginStorageStateMap;
215
216 ~StorageEventObserver() override {
217 DCHECK(origin_state_map_.empty());
218 StopObserving();
219 } 231 }
220 232
221 // storage::StorageObserver implementation. 233 // Keys are extension IDs. Values are self-registering StorageObservers.
222 void OnStorageEvent(const Event& event) override { 234 std::map<std::string, std::unique_ptr<SingleExtensionStorageObserver>>
223 OriginStorageStateMap::iterator iter = 235 storage_observers_;
224 origin_state_map_.find(event.filter.origin);
225 if (iter == origin_state_map_.end())
226 return;
227 StorageState& state = iter->second;
228 236
229 if (state.should_uma) { 237 // Keys are extension IDs.
238 base::WeakPtr<ExtensionStorageMonitor> extension_storage_monitor_;
239
240 DISALLOW_COPY_AND_ASSIGN(ExtensionStorageMonitorIOHelper);
241 };
242
243 void SingleExtensionStorageObserver::OnStorageEvent(const Event& event) {
244 {
Devlin 2017/06/12 20:15:05 this scope seems unnecessary?
ncarter (slow) 2017/06/12 22:52:07 Removed. I added this to get the diffs to line up
245 if (should_uma_) {
230 if (event.filter.storage_type == storage::kStorageTypePersistent) { 246 if (event.filter.storage_type == storage::kStorageTypePersistent) {
231 UMA_HISTOGRAM_MEMORY_KB( 247 UMA_HISTOGRAM_MEMORY_KB(
232 "Extensions.HostedAppUnlimitedStoragePersistentStorageUsage", 248 "Extensions.HostedAppUnlimitedStoragePersistentStorageUsage",
233 event.usage); 249 event.usage);
234 } else { 250 } else {
235 // We can't use the quota in the event because it assumes unlimited 251 // We can't use the quota in the event because it assumes unlimited
236 // storage. 252 // storage.
237 BrowserThread::PostTask( 253 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
238 BrowserThread::IO, FROM_HERE, 254 base::BindOnce(&LogTemporaryStorageUsage,
239 base::BindOnce(&LogTemporaryStorageUsage, state.quota_manager, 255 quota_manager_, event.usage));
240 event.usage));
241 } 256 }
242 } 257 }
243 258
244 if (state.next_threshold != -1 && 259 if (next_threshold_ != -1 && event.usage >= next_threshold_) {
245 event.usage >= state.next_threshold) { 260 while (event.usage >= next_threshold_)
246 while (event.usage >= state.next_threshold) 261 next_threshold_ *= 2;
247 state.next_threshold *= 2;
248 262
249 BrowserThread::PostTask( 263 BrowserThread::PostTask(
250 BrowserThread::UI, FROM_HERE, 264 BrowserThread::UI, FROM_HERE,
251 base::BindOnce(&ExtensionStorageMonitor::OnStorageThresholdExceeded, 265 base::BindOnce(&ExtensionStorageMonitor::OnStorageThresholdExceeded,
252 storage_monitor_, state.extension_id, 266 io_helper_->extension_storage_monitor(), extension_id_,
253 state.next_threshold, event.usage)); 267 next_threshold_, event.usage));
254 } 268 }
255 } 269 }
256 270 }
257 OriginStorageStateMap origin_state_map_;
258 base::WeakPtr<ExtensionStorageMonitor> storage_monitor_;
259 };
260 271
261 // ExtensionStorageMonitor 272 // ExtensionStorageMonitor
262 273
263 // static 274 // static
264 ExtensionStorageMonitor* ExtensionStorageMonitor::Get( 275 ExtensionStorageMonitor* ExtensionStorageMonitor::Get(
265 content::BrowserContext* context) { 276 content::BrowserContext* context) {
266 return ExtensionStorageMonitorFactory::GetForBrowserContext(context); 277 return ExtensionStorageMonitorFactory::GetForBrowserContext(context);
267 } 278 }
268 279
269 ExtensionStorageMonitor::ExtensionStorageMonitor( 280 ExtensionStorageMonitor::ExtensionStorageMonitor(
270 content::BrowserContext* context) 281 content::BrowserContext* context)
271 : enable_for_all_extensions_(false), 282 : enable_for_all_extensions_(false),
272 initial_extension_threshold_(kExtensionInitialThreshold), 283 initial_extension_threshold_(kExtensionInitialThreshold),
273 observer_rate_(base::TimeDelta::FromSeconds(kStorageEventRateSec)), 284 observer_rate_(kStorageEventRate),
274 context_(context), 285 context_(context),
275 extension_prefs_(ExtensionPrefs::Get(context)), 286 extension_prefs_(ExtensionPrefs::Get(context)),
276 extension_registry_observer_(this), 287 extension_registry_observer_(this),
277 weak_ptr_factory_(this) { 288 weak_ptr_factory_(this) {
278 DCHECK(extension_prefs_); 289 DCHECK(extension_prefs_);
279 290
280 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 291 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
281 content::Source<content::BrowserContext>(context_)); 292 content::Source<content::BrowserContext>(context_));
282 293
283 extension_registry_observer_.Add(ExtensionRegistry::Get(context_)); 294 extension_registry_observer_.Add(ExtensionRegistry::Get(context_));
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 return; 334 return;
324 } 335 }
325 336
326 int64_t next_threshold = GetNextStorageThresholdFromPrefs(extension->id()); 337 int64_t next_threshold = GetNextStorageThresholdFromPrefs(extension->id());
327 if (next_threshold <= initial_extension_threshold_) { 338 if (next_threshold <= initial_extension_threshold_) {
328 // Clear the next threshold in the prefs. This effectively raises it to 339 // Clear the next threshold in the prefs. This effectively raises it to
329 // |initial_extension_threshold_|. If the current threshold is already 340 // |initial_extension_threshold_|. If the current threshold is already
330 // higher than this, leave it as is. 341 // higher than this, leave it as is.
331 SetNextStorageThreshold(extension->id(), 0); 342 SetNextStorageThreshold(extension->id(), 0);
332 343
333 if (storage_observer_.get()) { 344 if (io_helper_.get()) {
Devlin 2017/06/12 20:15:05 nit: I don't think we need the .get() here, right?
ncarter (slow) 2017/06/12 22:52:07 Done.
334 BrowserThread::PostTask( 345 BrowserThread::PostTask(
335 BrowserThread::IO, FROM_HERE, 346 BrowserThread::IO, FROM_HERE,
336 base::BindOnce(&StorageEventObserver::UpdateThresholdForExtension, 347 base::BindOnce(
337 storage_observer_, extension->id(), 348 &ExtensionStorageMonitorIOHelper::UpdateThresholdForExtension,
338 initial_extension_threshold_)); 349 io_helper_, extension->id(), initial_extension_threshold_));
339 } 350 }
340 } 351 }
341 } 352 }
342 353
343 void ExtensionStorageMonitor::OnExtensionUninstalled( 354 void ExtensionStorageMonitor::OnExtensionUninstalled(
344 content::BrowserContext* browser_context, 355 content::BrowserContext* browser_context,
345 const Extension* extension, 356 const Extension* extension,
346 extensions::UninstallReason reason) { 357 extensions::UninstallReason reason) {
347 RemoveNotificationForExtension(extension->id()); 358 RemoveNotificationForExtension(extension->id());
348 } 359 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 489
479 bool should_enforce = (enable_for_all_extensions_) && 490 bool should_enforce = (enable_for_all_extensions_) &&
480 IsStorageNotificationEnabled(extension->id()); 491 IsStorageNotificationEnabled(extension->id());
481 492
482 bool for_metrics = ShouldGatherMetricsFor(extension); 493 bool for_metrics = ShouldGatherMetricsFor(extension);
483 494
484 if (!should_enforce && !for_metrics) 495 if (!should_enforce && !for_metrics)
485 return; // Don't track this extension. 496 return; // Don't track this extension.
486 497
487 // Lazily create the storage monitor proxy on the IO thread. 498 // Lazily create the storage monitor proxy on the IO thread.
488 if (!storage_observer_.get()) { 499 if (!io_helper_.get()) {
489 storage_observer_ = 500 io_helper_ =
490 new StorageEventObserver(weak_ptr_factory_.GetWeakPtr()); 501 new ExtensionStorageMonitorIOHelper(weak_ptr_factory_.GetWeakPtr());
491 } 502 }
492 503
493 GURL site_url = util::GetSiteForExtensionId(extension->id(), context_); 504 GURL site_url = util::GetSiteForExtensionId(extension->id(), context_);
494 content::StoragePartition* storage_partition = 505 content::StoragePartition* storage_partition =
495 content::BrowserContext::GetStoragePartitionForSite(context_, site_url); 506 content::BrowserContext::GetStoragePartitionForSite(context_, site_url);
496 DCHECK(storage_partition); 507 DCHECK(storage_partition);
497 scoped_refptr<storage::QuotaManager> quota_manager( 508 scoped_refptr<storage::QuotaManager> quota_manager(
498 storage_partition->GetQuotaManager()); 509 storage_partition->GetQuotaManager());
499 510
500 GURL storage_origin(site_url.GetOrigin()); 511 GURL storage_origin(site_url.GetOrigin());
501 if (extension->is_hosted_app()) 512 if (extension->is_hosted_app())
502 storage_origin = AppLaunchInfo::GetLaunchWebURL(extension).GetOrigin(); 513 storage_origin = AppLaunchInfo::GetLaunchWebURL(extension).GetOrigin();
503 514
504 // Don't give a threshold if we're not enforcing. 515 // Don't give a threshold if we're not enforcing.
505 int next_threshold = 516 int next_threshold =
506 should_enforce ? GetNextStorageThreshold(extension->id()) : -1; 517 should_enforce ? GetNextStorageThreshold(extension->id()) : -1;
507 518
508 BrowserThread::PostTask( 519 BrowserThread::PostTask(
509 BrowserThread::IO, FROM_HERE, 520 BrowserThread::IO, FROM_HERE,
510 base::BindOnce(&StorageEventObserver::StartObservingForExtension, 521 base::BindOnce(
511 storage_observer_, quota_manager, extension->id(), 522 &ExtensionStorageMonitorIOHelper::StartObservingForExtension,
512 storage_origin, next_threshold, observer_rate_, 523 io_helper_, quota_manager, extension->id(), storage_origin,
513 for_metrics)); 524 next_threshold, observer_rate_, for_metrics));
514 } 525 }
515 526
516 void ExtensionStorageMonitor::StopMonitoringStorage( 527 void ExtensionStorageMonitor::StopMonitoringStorage(
517 const std::string& extension_id) { 528 const std::string& extension_id) {
518 if (!storage_observer_.get()) 529 if (!io_helper_.get())
519 return; 530 return;
520 531
521 BrowserThread::PostTask( 532 BrowserThread::PostTask(
522 BrowserThread::IO, FROM_HERE, 533 BrowserThread::IO, FROM_HERE,
523 base::BindOnce(&StorageEventObserver::StopObservingForExtension, 534 base::BindOnce(
524 storage_observer_, extension_id)); 535 &ExtensionStorageMonitorIOHelper::StopObservingForExtension,
536 io_helper_, extension_id));
525 } 537 }
526 538
527 void ExtensionStorageMonitor::StopMonitoringAll() { 539 void ExtensionStorageMonitor::StopMonitoringAll() {
528 extension_registry_observer_.RemoveAll(); 540 extension_registry_observer_.RemoveAll();
529 541
530 RemoveAllNotifications(); 542 RemoveAllNotifications();
531 543
532 if (!storage_observer_.get()) 544 io_helper_ = nullptr;
533 return; 545 weak_ptr_factory_.InvalidateWeakPtrs();
534
535 BrowserThread::PostTask(
536 BrowserThread::IO, FROM_HERE,
537 base::BindOnce(&StorageEventObserver::StopObserving, storage_observer_));
538 storage_observer_ = NULL;
539 } 546 }
540 547
541 void ExtensionStorageMonitor::RemoveNotificationForExtension( 548 void ExtensionStorageMonitor::RemoveNotificationForExtension(
542 const std::string& extension_id) { 549 const std::string& extension_id) {
543 std::set<std::string>::iterator ext_id = 550 std::set<std::string>::iterator ext_id =
544 notified_extension_ids_.find(extension_id); 551 notified_extension_ids_.find(extension_id);
545 if (ext_id == notified_extension_ids_.end()) 552 if (ext_id == notified_extension_ids_.end())
546 return; 553 return;
547 554
548 notified_extension_ids_.erase(ext_id); 555 notified_extension_ids_.erase(ext_id);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 637
631 void ExtensionStorageMonitor::SetStorageNotificationEnabled( 638 void ExtensionStorageMonitor::SetStorageNotificationEnabled(
632 const std::string& extension_id, 639 const std::string& extension_id,
633 bool enable_notifications) { 640 bool enable_notifications) {
634 extension_prefs_->UpdateExtensionPref( 641 extension_prefs_->UpdateExtensionPref(
635 extension_id, kPrefDisableStorageNotifications, 642 extension_id, kPrefDisableStorageNotifications,
636 enable_notifications ? nullptr : base::MakeUnique<base::Value>(true)); 643 enable_notifications ? nullptr : base::MakeUnique<base::Value>(true));
637 } 644 }
638 645
639 } // namespace extensions 646 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698