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

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

Issue 310183005: Added uninstall option to notification of high disk usage by an extension (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@exstorage_refactor
Patch Set: Created 6 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 8
9 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/chrome_notification_types.h" 12 #include "chrome/browser/chrome_notification_types.h"
13 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/extensions/extension_storage_monitor_factory.h" 14 #include "chrome/browser/extensions/extension_storage_monitor_factory.h"
14 #include "chrome/browser/extensions/extension_util.h" 15 #include "chrome/browser/extensions/extension_util.h"
15 #include "chrome/browser/extensions/image_loader.h" 16 #include "chrome/browser/extensions/image_loader.h"
17 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" 18 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
17 #include "content/public/browser/browser_context.h" 19 #include "content/public/browser/browser_context.h"
18 #include "content/public/browser/browser_thread.h" 20 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/notification_details.h" 21 #include "content/public/browser/notification_details.h"
20 #include "content/public/browser/notification_source.h" 22 #include "content/public/browser/notification_source.h"
21 #include "content/public/browser/storage_partition.h" 23 #include "content/public/browser/storage_partition.h"
22 #include "extensions/browser/extension_prefs.h" 24 #include "extensions/browser/extension_prefs.h"
23 #include "extensions/browser/extension_registry.h" 25 #include "extensions/browser/extension_registry.h"
26 #include "extensions/browser/extension_system.h"
24 #include "extensions/common/extension.h" 27 #include "extensions/common/extension.h"
25 #include "extensions/common/manifest_handlers/icons_handler.h" 28 #include "extensions/common/manifest_handlers/icons_handler.h"
26 #include "grit/generated_resources.h" 29 #include "grit/generated_resources.h"
27 #include "ui/base/l10n/l10n_util.h" 30 #include "ui/base/l10n/l10n_util.h"
28 #include "ui/message_center/message_center.h" 31 #include "ui/message_center/message_center.h"
29 #include "ui/message_center/notifier_settings.h" 32 #include "ui/message_center/notifier_settings.h"
30 #include "ui/message_center/views/constants.h" 33 #include "ui/message_center/views/constants.h"
31 #include "webkit/browser/quota/quota_manager.h" 34 #include "webkit/browser/quota/quota_manager.h"
32 #include "webkit/browser/quota/storage_observer.h" 35 #include "webkit/browser/quota/storage_observer.h"
33 36
(...skipping 29 matching lines...) Expand all
63 // extension or app consumes excessive disk space. 66 // extension or app consumes excessive disk space.
64 const char kPrefDisableStorageNotifications[] = "disable_storage_notifications"; 67 const char kPrefDisableStorageNotifications[] = "disable_storage_notifications";
65 68
66 bool ShouldMonitorStorageFor(const Extension* extension) { 69 bool ShouldMonitorStorageFor(const Extension* extension) {
67 // Only monitor storage for extensions that are granted unlimited storage. 70 // Only monitor storage for extensions that are granted unlimited storage.
68 // Do not monitor storage for component extensions. 71 // Do not monitor storage for component extensions.
69 return extension->HasAPIPermission(APIPermission::kUnlimitedStorage) && 72 return extension->HasAPIPermission(APIPermission::kUnlimitedStorage) &&
70 extension->location() != Manifest::COMPONENT; 73 extension->location() != Manifest::COMPONENT;
71 } 74 }
72 75
76 const Extension* GetExtensionById(content::BrowserContext* context,
77 const std::string& extension_id) {
78 return ExtensionRegistry::Get(context)->GetExtensionById(
79 extension_id, ExtensionRegistry::EVERYTHING);
80 }
81
73 } // namespace 82 } // namespace
74 83
75 // StorageEventObserver monitors the storage usage of extensions and lives on 84 // StorageEventObserver monitors the storage usage of extensions and lives on
76 // the IO thread. When a threshold is exceeded, a message will be posted to the 85 // the IO thread. When a threshold is exceeded, a message will be posted to the
77 // UI thread, which displays the notification. 86 // UI thread, which displays the notification.
78 class StorageEventObserver 87 class StorageEventObserver
79 : public base::RefCountedThreadSafe< 88 : public base::RefCountedThreadSafe<
80 StorageEventObserver, 89 StorageEventObserver,
81 BrowserThread::DeleteOnIOThread>, 90 BrowserThread::DeleteOnIOThread>,
82 public quota::StorageObserver { 91 public quota::StorageObserver {
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 } 298 }
290 } 299 }
291 } 300 }
292 301
293 void ExtensionStorageMonitor::OnExtensionUninstalled( 302 void ExtensionStorageMonitor::OnExtensionUninstalled(
294 content::BrowserContext* browser_context, 303 content::BrowserContext* browser_context,
295 const Extension* extension) { 304 const Extension* extension) {
296 RemoveNotificationForExtension(extension->id()); 305 RemoveNotificationForExtension(extension->id());
297 } 306 }
298 307
308 void ExtensionStorageMonitor::ExtensionUninstallAccepted() {
309 DCHECK(!uninstall_extension_id_.empty());
310
311 const Extension* extension = GetExtensionById(context_,
312 uninstall_extension_id_);
313 uninstall_extension_id_.clear();
314 if (!extension)
315 return;
316
317 ExtensionService* service =
318 ExtensionSystem::Get(context_)->extension_service();
319 DCHECK(service);
320 service->UninstallExtension(extension->id(), false, NULL);
321 }
322
323 void ExtensionStorageMonitor::ExtensionUninstallCanceled() {
324 uninstall_extension_id_.clear();
325 }
326
299 std::string ExtensionStorageMonitor::GetNotificationId( 327 std::string ExtensionStorageMonitor::GetNotificationId(
300 const std::string& extension_id) { 328 const std::string& extension_id) {
301 std::vector<std::string> placeholders; 329 std::vector<std::string> placeholders;
302 placeholders.push_back(context_->GetPath().BaseName().MaybeAsASCII()); 330 placeholders.push_back(context_->GetPath().BaseName().MaybeAsASCII());
303 placeholders.push_back(extension_id); 331 placeholders.push_back(extension_id);
304 332
305 return ReplaceStringPlaceholders(kNotificationIdFormat, placeholders, NULL); 333 return ReplaceStringPlaceholders(kNotificationIdFormat, placeholders, NULL);
306 } 334 }
307 335
308 void ExtensionStorageMonitor::OnStorageThresholdExceeded( 336 void ExtensionStorageMonitor::OnStorageThresholdExceeded(
309 const std::string& extension_id, 337 const std::string& extension_id,
310 int64 next_threshold, 338 int64 next_threshold,
311 int64 current_usage) { 339 int64 current_usage) {
312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 340 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
313 341
314 const Extension* extension = ExtensionRegistry::Get(context_)-> 342 const Extension* extension = GetExtensionById(context_, extension_id);
315 GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING);
316 if (!extension) 343 if (!extension)
317 return; 344 return;
318 345
319 if (GetNextStorageThreshold(extension->id()) < next_threshold) 346 if (GetNextStorageThreshold(extension->id()) < next_threshold)
320 SetNextStorageThreshold(extension->id(), next_threshold); 347 SetNextStorageThreshold(extension->id(), next_threshold);
321 348
322 const int kIconSize = message_center::kNotificationIconSize; 349 const int kIconSize = message_center::kNotificationIconSize;
323 ExtensionResource resource = IconsInfo::GetIconResource( 350 ExtensionResource resource = IconsInfo::GetIconResource(
324 extension, kIconSize, ExtensionIconSet::MATCH_BIGGER); 351 extension, kIconSize, ExtensionIconSet::MATCH_BIGGER);
325 ImageLoader::Get(context_)->LoadImageAsync( 352 ImageLoader::Get(context_)->LoadImageAsync(
326 extension, resource, gfx::Size(kIconSize, kIconSize), 353 extension, resource, gfx::Size(kIconSize, kIconSize),
327 base::Bind(&ExtensionStorageMonitor::OnImageLoaded, 354 base::Bind(&ExtensionStorageMonitor::OnImageLoaded,
328 weak_ptr_factory_.GetWeakPtr(), 355 weak_ptr_factory_.GetWeakPtr(),
329 extension_id, 356 extension_id,
330 current_usage)); 357 current_usage));
331 } 358 }
332 359
333 void ExtensionStorageMonitor::OnImageLoaded( 360 void ExtensionStorageMonitor::OnImageLoaded(
334 const std::string& extension_id, 361 const std::string& extension_id,
335 int64 current_usage, 362 int64 current_usage,
336 const gfx::Image& image) { 363 const gfx::Image& image) {
337 const Extension* extension = ExtensionRegistry::Get(context_)-> 364 const Extension* extension = GetExtensionById(context_, extension_id);
338 GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING);
339 if (!extension) 365 if (!extension)
340 return; 366 return;
341 367
342 // Remove any existing notifications to force a new notification to pop up. 368 // Remove any existing notifications to force a new notification to pop up.
343 std::string notification_id(GetNotificationId(extension_id)); 369 std::string notification_id(GetNotificationId(extension_id));
344 message_center::MessageCenter::Get()->RemoveNotification( 370 message_center::MessageCenter::Get()->RemoveNotification(
345 notification_id, false); 371 notification_id, false);
346 372
347 message_center::RichNotificationData notification_data; 373 message_center::RichNotificationData notification_data;
348 notification_data.buttons.push_back(message_center::ButtonInfo( 374 notification_data.buttons.push_back(message_center::ButtonInfo(
349 l10n_util::GetStringUTF16(extension->is_app() ? 375 l10n_util::GetStringUTF16(extension->is_app() ?
350 IDS_EXTENSION_STORAGE_MONITOR_BUTTON_DISMISS_APP : 376 IDS_EXTENSION_STORAGE_MONITOR_BUTTON_DISMISS_APP :
351 IDS_EXTENSION_STORAGE_MONITOR_BUTTON_DISMISS_EXTENSION))); 377 IDS_EXTENSION_STORAGE_MONITOR_BUTTON_DISMISS_EXTENSION)));
378 notification_data.buttons.push_back(message_center::ButtonInfo(
379 l10n_util::GetStringUTF16(extension->is_app() ?
380 IDS_EXTENSION_STORAGE_MONITOR_BUTTON_UNINSTALL_APP :
381 IDS_EXTENSION_STORAGE_MONITOR_BUTTON_UNINSTALL_EXTENSION)));
352 382
353 gfx::Image notification_image(image); 383 gfx::Image notification_image(image);
354 if (notification_image.IsEmpty()) { 384 if (notification_image.IsEmpty()) {
355 notification_image = 385 notification_image =
356 extension->is_app() ? gfx::Image(util::GetDefaultAppIcon()) 386 extension->is_app() ? gfx::Image(util::GetDefaultAppIcon())
357 : gfx::Image(util::GetDefaultExtensionIcon()); 387 : gfx::Image(util::GetDefaultExtensionIcon());
358 } 388 }
359 389
360 scoped_ptr<message_center::Notification> notification; 390 scoped_ptr<message_center::Notification> notification;
361 notification.reset(new message_center::Notification( 391 notification.reset(new message_center::Notification(
(...skipping 19 matching lines...) Expand all
381 notified_extension_ids_.insert(extension_id); 411 notified_extension_ids_.insert(extension_id);
382 } 412 }
383 413
384 void ExtensionStorageMonitor::OnNotificationButtonClick( 414 void ExtensionStorageMonitor::OnNotificationButtonClick(
385 const std::string& extension_id, int button_index) { 415 const std::string& extension_id, int button_index) {
386 switch (button_index) { 416 switch (button_index) {
387 case BUTTON_DISABLE_NOTIFICATION: { 417 case BUTTON_DISABLE_NOTIFICATION: {
388 DisableStorageMonitoring(extension_id); 418 DisableStorageMonitoring(extension_id);
389 break; 419 break;
390 } 420 }
421 case BUTTON_UNINSTALL: {
422 ShowUninstallPrompt(extension_id);
423 break;
424 }
391 default: 425 default:
392 NOTREACHED(); 426 NOTREACHED();
393 } 427 }
394 } 428 }
395 429
396 void ExtensionStorageMonitor::DisableStorageMonitoring( 430 void ExtensionStorageMonitor::DisableStorageMonitoring(
397 const std::string& extension_id) { 431 const std::string& extension_id) {
398 StopMonitoringStorage(extension_id); 432 StopMonitoringStorage(extension_id);
399 433
400 SetStorageNotificationEnabled(extension_id, false); 434 SetStorageNotificationEnabled(extension_id, false);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 528
495 message_center::MessageCenter* center = message_center::MessageCenter::Get(); 529 message_center::MessageCenter* center = message_center::MessageCenter::Get();
496 DCHECK(center); 530 DCHECK(center);
497 for (std::set<std::string>::iterator it = notified_extension_ids_.begin(); 531 for (std::set<std::string>::iterator it = notified_extension_ids_.begin();
498 it != notified_extension_ids_.end(); ++it) { 532 it != notified_extension_ids_.end(); ++it) {
499 center->RemoveNotification(GetNotificationId(*it), false); 533 center->RemoveNotification(GetNotificationId(*it), false);
500 } 534 }
501 notified_extension_ids_.clear(); 535 notified_extension_ids_.clear();
502 } 536 }
503 537
538 void ExtensionStorageMonitor::ShowUninstallPrompt(
539 const std::string& extension_id) {
540 const Extension* extension = GetExtensionById(context_, extension_id);
541 if (!extension)
542 return;
543
544 if (!uninstall_dialog_.get()) {
545 uninstall_dialog_.reset(ExtensionUninstallDialog::Create(
546 Profile::FromBrowserContext(context_), NULL, this));
547 }
548
549 uninstall_extension_id_ = extension->id();
550 uninstall_dialog_->ConfirmUninstall(extension);
551 }
552
504 int64 ExtensionStorageMonitor::GetNextStorageThreshold( 553 int64 ExtensionStorageMonitor::GetNextStorageThreshold(
505 const std::string& extension_id) const { 554 const std::string& extension_id) const {
506 int next_threshold = GetNextStorageThresholdFromPrefs(extension_id); 555 int next_threshold = GetNextStorageThresholdFromPrefs(extension_id);
507 if (next_threshold == 0) { 556 if (next_threshold == 0) {
508 // The next threshold is written to the prefs after the initial threshold is 557 // The next threshold is written to the prefs after the initial threshold is
509 // exceeded. 558 // exceeded.
510 next_threshold = extension_prefs_->IsEphemeralApp(extension_id) 559 next_threshold = extension_prefs_->IsEphemeralApp(extension_id)
511 ? initial_ephemeral_threshold_ 560 ? initial_ephemeral_threshold_
512 : initial_extension_threshold_; 561 : initial_extension_threshold_;
513 } 562 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 void ExtensionStorageMonitor::SetStorageNotificationEnabled( 604 void ExtensionStorageMonitor::SetStorageNotificationEnabled(
556 const std::string& extension_id, 605 const std::string& extension_id,
557 bool enable_notifications) { 606 bool enable_notifications) {
558 extension_prefs_->UpdateExtensionPref( 607 extension_prefs_->UpdateExtensionPref(
559 extension_id, 608 extension_id,
560 kPrefDisableStorageNotifications, 609 kPrefDisableStorageNotifications,
561 enable_notifications ? NULL : new base::FundamentalValue(true)); 610 enable_notifications ? NULL : new base::FundamentalValue(true));
562 } 611 }
563 612
564 } // namespace extensions 613 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698