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 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_STORAGE_MONITOR_H_ 6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_STORAGE_MONITOR_H_ 7 8 #include <set> 9 10 #include "base/memory/ref_counted.h" 11 #include "base/memory/weak_ptr.h" 12 #include "base/scoped_observer.h" 13 #include "chrome/browser/extensions/extension_uninstall_dialog.h" 14 #include "components/keyed_service/core/keyed_service.h" 15 #include "content/public/browser/notification_observer.h" 16 #include "content/public/browser/notification_registrar.h" 17 #include "extensions/browser/extension_registry_observer.h" 18 19 namespace content { 20 class BrowserContext; 21 } 22 23 namespace gfx { 24 class Image; 25 } 26 27 namespace extensions { 28 29 class Extension; 30 class ExtensionPrefs; 31 class ExtensionRegistry; 32 class StorageEventObserver; 33 34 // ExtensionStorageMonitor monitors the storage usage of extensions and apps 35 // that are granted unlimited storage and displays notifications when high 36 // usage is detected. 37 class ExtensionStorageMonitor : public KeyedService, 38 public content::NotificationObserver, 39 public ExtensionRegistryObserver, 40 public ExtensionUninstallDialog::Delegate { 41 public: 42 static ExtensionStorageMonitor* Get(content::BrowserContext* context); 43 44 // Indices of buttons in the notification. Exposed for testing. 45 enum ButtonIndex { 46 BUTTON_DISABLE_NOTIFICATION = 0, 47 BUTTON_UNINSTALL 48 }; 49 50 explicit ExtensionStorageMonitor(content::BrowserContext* context); 51 virtual ~ExtensionStorageMonitor(); 52 53 private: 54 // content::NotificationObserver overrides: 55 virtual void Observe(int type, 56 const content::NotificationSource& source, 57 const content::NotificationDetails& details) OVERRIDE; 58 59 // ExtensionRegistryObserver overrides: 60 virtual void OnExtensionLoaded(content::BrowserContext* browser_context, 61 const Extension* extension) OVERRIDE; 62 virtual void OnExtensionUnloaded( 63 content::BrowserContext* browser_context, 64 const Extension* extension, 65 UnloadedExtensionInfo::Reason reason) OVERRIDE; 66 virtual void OnExtensionWillBeInstalled( 67 content::BrowserContext* browser_context, 68 const Extension* extension, 69 bool is_update, 70 bool from_ephemeral, 71 const std::string& old_name) OVERRIDE; 72 virtual void OnExtensionUninstalled(content::BrowserContext* browser_context, 73 const Extension* extension) OVERRIDE; 74 75 // Overridden from ExtensionUninstallDialog::Delegate: 76 virtual void ExtensionUninstallAccepted() OVERRIDE; 77 virtual void ExtensionUninstallCanceled() OVERRIDE; 78 79 std::string GetNotificationId(const std::string& extension_id); 80 81 void OnStorageThresholdExceeded(const std::string& extension_id, 82 int64 next_threshold, 83 int64 current_usage); 84 void OnImageLoaded(const std::string& extension_id, 85 int64 current_usage, 86 const gfx::Image& image); 87 void OnNotificationButtonClick(const std::string& extension_id, 88 int button_index); 89 90 void DisableStorageMonitoring(const std::string& extension_id); 91 void StartMonitoringStorage(const Extension* extension); 92 void StopMonitoringStorage(const std::string& extension_id); 93 void StopMonitoringAll(); 94 95 void RemoveNotificationForExtension(const std::string& extension_id); 96 void RemoveAllNotifications(); 97 98 // Displays the prompt for uninstalling the extension. 99 void ShowUninstallPrompt(const std::string& extension_id); 100 101 // Returns/sets the next threshold for displaying a notification if an 102 // extension or app consumes excessive disk space. 103 int64 GetNextStorageThreshold(const std::string& extension_id) const; 104 void SetNextStorageThreshold(const std::string& extension_id, 105 int64 next_threshold); 106 107 // Returns the raw next storage threshold value stored in prefs. Returns 0 if 108 // the initial threshold has not yet been reached. 109 int64 GetNextStorageThresholdFromPrefs(const std::string& extension_id) const; 110 111 // Returns/sets whether notifications should be shown if an extension or app 112 // consumes too much disk space. 113 bool IsStorageNotificationEnabled(const std::string& extension_id) const; 114 void SetStorageNotificationEnabled(const std::string& extension_id, 115 bool enable_notifications); 116 117 // Initially, monitoring will only be applied to ephemeral apps. This flag 118 // is set by tests to enable for all extensions and apps. 119 bool enable_for_all_extensions_; 120 121 // The first notification is shown after the initial threshold is exceeded. 122 // Ephemeral apps have a lower threshold than fully installed extensions. 123 // A lower threshold is set by tests. 124 int64 initial_extension_threshold_; 125 int64 initial_ephemeral_threshold_; 126 127 // The rate (in seconds) at which we would like to receive storage updates 128 // from QuotaManager. Overridden in tests. 129 int observer_rate_; 130 131 // IDs of extensions that notifications were shown for. 132 std::set<std::string> notified_extension_ids_; 133 134 content::BrowserContext* context_; 135 extensions::ExtensionPrefs* extension_prefs_; 136 137 content::NotificationRegistrar registrar_; 138 ScopedObserver<extensions::ExtensionRegistry, 139 extensions::ExtensionRegistryObserver> 140 extension_registry_observer_; 141 142 // StorageEventObserver monitors storage for extensions on the IO thread. 143 scoped_refptr<StorageEventObserver> storage_observer_; 144 145 // Modal dialog used to confirm removal of an extension. 146 scoped_ptr<ExtensionUninstallDialog> uninstall_dialog_; 147 148 // The ID of the extension that is the subject of the uninstall confirmation 149 // dialog. 150 std::string uninstall_extension_id_; 151 152 base::WeakPtrFactory<ExtensionStorageMonitor> weak_ptr_factory_; 153 154 friend class StorageEventObserver; 155 friend class ExtensionStorageMonitorTest; 156 157 DISALLOW_COPY_AND_ASSIGN(ExtensionStorageMonitor); 158 }; 159 160 } // namespace extensions 161 162 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_STORAGE_MONITOR_H_ 163