• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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