Home | History | Annotate | Download | only in extensions
      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(
     73       content::BrowserContext* browser_context,
     74       const Extension* extension,
     75       extensions::UninstallReason reason) OVERRIDE;
     76 
     77   // Overridden from ExtensionUninstallDialog::Delegate:
     78   virtual void ExtensionUninstallAccepted() OVERRIDE;
     79   virtual void ExtensionUninstallCanceled() OVERRIDE;
     80 
     81   std::string GetNotificationId(const std::string& extension_id);
     82 
     83   void OnStorageThresholdExceeded(const std::string& extension_id,
     84                                   int64 next_threshold,
     85                                   int64 current_usage);
     86   void OnImageLoaded(const std::string& extension_id,
     87                      int64 current_usage,
     88                      const gfx::Image& image);
     89   void OnNotificationButtonClick(const std::string& extension_id,
     90                                  int button_index);
     91 
     92   void DisableStorageMonitoring(const std::string& extension_id);
     93   void StartMonitoringStorage(const Extension* extension);
     94   void StopMonitoringStorage(const std::string& extension_id);
     95   void StopMonitoringAll();
     96 
     97   void RemoveNotificationForExtension(const std::string& extension_id);
     98   void RemoveAllNotifications();
     99 
    100   // Displays the prompt for uninstalling the extension.
    101   void ShowUninstallPrompt(const std::string& extension_id);
    102 
    103   // Returns/sets the next threshold for displaying a notification if an
    104   // extension or app consumes excessive disk space.
    105   int64 GetNextStorageThreshold(const std::string& extension_id) const;
    106   void SetNextStorageThreshold(const std::string& extension_id,
    107                                int64 next_threshold);
    108 
    109   // Returns the raw next storage threshold value stored in prefs. Returns 0 if
    110   // the initial threshold has not yet been reached.
    111   int64 GetNextStorageThresholdFromPrefs(const std::string& extension_id) const;
    112 
    113   // Returns/sets whether notifications should be shown if an extension or app
    114   // consumes too much disk space.
    115   bool IsStorageNotificationEnabled(const std::string& extension_id) const;
    116   void SetStorageNotificationEnabled(const std::string& extension_id,
    117                                      bool enable_notifications);
    118 
    119   // Initially, monitoring will only be applied to ephemeral apps. This flag
    120   // is set by tests to enable for all extensions and apps.
    121   bool enable_for_all_extensions_;
    122 
    123   // The first notification is shown after the initial threshold is exceeded.
    124   // Ephemeral apps have a lower threshold than fully installed extensions.
    125   // A lower threshold is set by tests.
    126   int64 initial_extension_threshold_;
    127   int64 initial_ephemeral_threshold_;
    128 
    129   // The rate (in seconds) at which we would like to receive storage updates
    130   // from QuotaManager. Overridden in tests.
    131   int observer_rate_;
    132 
    133   // IDs of extensions that notifications were shown for.
    134   std::set<std::string> notified_extension_ids_;
    135 
    136   content::BrowserContext* context_;
    137   extensions::ExtensionPrefs* extension_prefs_;
    138 
    139   content::NotificationRegistrar registrar_;
    140   ScopedObserver<extensions::ExtensionRegistry,
    141                  extensions::ExtensionRegistryObserver>
    142       extension_registry_observer_;
    143 
    144   // StorageEventObserver monitors storage for extensions on the IO thread.
    145   scoped_refptr<StorageEventObserver> storage_observer_;
    146 
    147   // Modal dialog used to confirm removal of an extension.
    148   scoped_ptr<ExtensionUninstallDialog> uninstall_dialog_;
    149 
    150   // The ID of the extension that is the subject of the uninstall confirmation
    151   // dialog.
    152   std::string uninstall_extension_id_;
    153 
    154   base::WeakPtrFactory<ExtensionStorageMonitor> weak_ptr_factory_;
    155 
    156   friend class StorageEventObserver;
    157   friend class ExtensionStorageMonitorTest;
    158 
    159   DISALLOW_COPY_AND_ASSIGN(ExtensionStorageMonitor);
    160 };
    161 
    162 }  // namespace extensions
    163 
    164 #endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_STORAGE_MONITOR_H_
    165