OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |