Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / extensions / extension_storage_monitor_browsertest.cc
blob228c13ef4054fbb8415eb60bd9904d812bb1fbdb
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.
5 #include <set>
7 #include "base/run_loop.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "chrome/browser/extensions/extension_browsertest.h"
10 #include "chrome/browser/extensions/extension_service.h"
11 #include "chrome/browser/extensions/extension_storage_monitor.h"
12 #include "chrome/browser/ui/extensions/app_launch_params.h"
13 #include "chrome/browser/ui/extensions/application_launch.h"
14 #include "content/public/test/test_utils.h"
15 #include "extensions/browser/extension_prefs.h"
16 #include "extensions/browser/extension_registry.h"
17 #include "extensions/browser/extension_system.h"
18 #include "extensions/browser/test_extension_registry_observer.h"
19 #include "extensions/common/constants.h"
20 #include "extensions/test/extension_test_message_listener.h"
21 #include "ui/message_center/message_center.h"
22 #include "ui/message_center/message_center_observer.h"
24 namespace extensions {
26 namespace {
28 const int kInitialUsageThreshold = 500;
30 const char kWriteDataApp[] = "storage_monitor/write_data";
32 class NotificationObserver : public message_center::MessageCenterObserver {
33 public:
34 explicit NotificationObserver(const std::string& target_notification)
35 : message_center_(message_center::MessageCenter::Get()),
36 target_notification_id_(target_notification),
37 waiting_(false) {
38 message_center_->AddObserver(this);
41 ~NotificationObserver() override { message_center_->RemoveObserver(this); }
43 bool HasReceivedNotification() const {
44 return received_notifications_.find(target_notification_id_) !=
45 received_notifications_.end();
48 // Runs the message loop and returns true if a notification is received.
49 // Immediately returns true if a notification has already been received.
50 bool WaitForNotification() {
51 if (HasReceivedNotification())
52 return true;
54 waiting_ = true;
55 content::RunMessageLoop();
56 waiting_ = false;
57 return HasReceivedNotification();
60 private:
61 // MessageCenterObserver implementation:
62 void OnNotificationAdded(const std::string& notification_id) override {
63 received_notifications_.insert(notification_id);
65 if (waiting_ && HasReceivedNotification())
66 base::MessageLoopForUI::current()->Quit();
69 message_center::MessageCenter* message_center_;
70 std::set<std::string> received_notifications_;
71 std::string target_notification_id_;
72 bool waiting_;
75 } // namespace
77 class ExtensionStorageMonitorTest : public ExtensionBrowserTest {
78 public:
79 ExtensionStorageMonitorTest() : storage_monitor_(NULL) {}
81 protected:
82 // ExtensionBrowserTest overrides:
83 void SetUpOnMainThread() override {
84 ExtensionBrowserTest::SetUpOnMainThread();
86 InitStorageMonitor();
89 ExtensionStorageMonitor* monitor() {
90 CHECK(storage_monitor_);
91 return storage_monitor_;
94 int64 GetInitialExtensionThreshold() {
95 CHECK(storage_monitor_);
96 return storage_monitor_->initial_extension_threshold_;
99 int64 GetInitialEphemeralThreshold() {
100 CHECK(storage_monitor_);
101 return storage_monitor_->initial_ephemeral_threshold_;
104 void DisableForInstalledExtensions() {
105 CHECK(storage_monitor_);
106 storage_monitor_->enable_for_all_extensions_ = false;
109 const Extension* InitWriteDataApp() {
110 base::FilePath path = test_data_dir_.AppendASCII(kWriteDataApp);
111 const Extension* extension = InstallExtension(path, 1);
112 EXPECT_TRUE(extension);
113 return extension;
116 const Extension* InitWriteDataEphemeralApp() {
117 // The threshold for installed extensions should be higher than ephemeral
118 // apps.
119 storage_monitor_->initial_extension_threshold_ =
120 storage_monitor_->initial_ephemeral_threshold_ * 4;
122 base::FilePath path = test_data_dir_.AppendASCII(kWriteDataApp);
123 const Extension* extension = InstallEphemeralAppWithSourceAndFlags(
124 path, 1, Manifest::INTERNAL, Extension::NO_FLAGS);
125 EXPECT_TRUE(extension);
126 return extension;
129 std::string GetNotificationId(const std::string& extension_id) {
130 return monitor()->GetNotificationId(extension_id);
133 bool IsStorageNotificationEnabled(const std::string& extension_id) {
134 return monitor()->IsStorageNotificationEnabled(extension_id);
137 int64 GetNextStorageThreshold(const std::string& extension_id) {
138 return monitor()->GetNextStorageThreshold(extension_id);
141 void WriteBytesExpectingNotification(const Extension* extension,
142 int num_bytes) {
143 int64 previous_threshold = GetNextStorageThreshold(extension->id());
144 WriteBytes(extension, num_bytes, true);
145 EXPECT_GT(GetNextStorageThreshold(extension->id()), previous_threshold);
148 void WriteBytesNotExpectingNotification(const Extension* extension,
149 int num_bytes) {
150 WriteBytes(extension, num_bytes, false);
153 void SimulateUninstallDialogAccept() {
154 // Ensure the uninstall dialog was shown and fake an accept.
155 ASSERT_TRUE(monitor()->uninstall_dialog_.get());
156 monitor()->ExtensionUninstallAccepted();
159 private:
160 void InitStorageMonitor() {
161 storage_monitor_ = ExtensionStorageMonitor::Get(profile());
162 ASSERT_TRUE(storage_monitor_);
164 // Override thresholds so that we don't have to write a huge amount of data
165 // to trigger notifications in these tests.
166 storage_monitor_->enable_for_all_extensions_ = true;
167 storage_monitor_->initial_extension_threshold_ = kInitialUsageThreshold;
168 storage_monitor_->initial_ephemeral_threshold_ = kInitialUsageThreshold;
170 // To ensure storage events are dispatched from QuotaManager immediately.
171 storage_monitor_->observer_rate_ = base::TimeDelta();
174 // Write a number of bytes to persistent storage.
175 void WriteBytes(const Extension* extension,
176 int num_bytes,
177 bool expected_notification) {
178 ExtensionTestMessageListener launched_listener("launched", true);
179 ExtensionTestMessageListener write_complete_listener(
180 "write_complete", false);
181 NotificationObserver notification_observer(
182 GetNotificationId(extension->id()));
184 OpenApplication(AppLaunchParams(profile(), extension, LAUNCH_CONTAINER_NONE,
185 NEW_WINDOW, extensions::SOURCE_TEST));
186 ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
188 // Instruct the app to write |num_bytes| of data.
189 launched_listener.Reply(base::IntToString(num_bytes));
190 ASSERT_TRUE(write_complete_listener.WaitUntilSatisfied());
192 if (expected_notification) {
193 EXPECT_TRUE(notification_observer.WaitForNotification());
194 } else {
195 base::RunLoop().RunUntilIdle();
196 EXPECT_FALSE(notification_observer.HasReceivedNotification());
200 ExtensionStorageMonitor* storage_monitor_;
203 // Control - No notifications should be shown if usage remains under the
204 // threshold.
205 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, UnderThreshold) {
206 const Extension* extension = InitWriteDataApp();
207 ASSERT_TRUE(extension);
208 WriteBytesNotExpectingNotification(extension, 1);
211 // Ensure a notification is shown when usage reaches the first threshold.
212 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, ExceedInitialThreshold) {
213 const Extension* extension = InitWriteDataApp();
214 ASSERT_TRUE(extension);
215 WriteBytesExpectingNotification(extension, GetInitialExtensionThreshold());
218 // Ensure a notification is shown when usage immediately exceeds double the
219 // first threshold.
220 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, DoubleInitialThreshold) {
221 const Extension* extension = InitWriteDataApp();
222 ASSERT_TRUE(extension);
223 WriteBytesExpectingNotification(extension,
224 GetInitialExtensionThreshold() * 2);
227 // Ensure that notifications are not fired if the next threshold has not been
228 // reached.
229 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, ThrottleNotifications) {
230 const Extension* extension = InitWriteDataApp();
231 ASSERT_TRUE(extension);
233 // Exceed the first threshold.
234 WriteBytesExpectingNotification(extension, GetInitialExtensionThreshold());
236 // Stay within the next threshold.
237 WriteBytesNotExpectingNotification(extension, 1);
240 // Verify that notifications are disabled when the user clicks the action button
241 // in the notification.
242 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, UserDisabledNotifications) {
243 const Extension* extension = InitWriteDataApp();
244 ASSERT_TRUE(extension);
245 WriteBytesExpectingNotification(extension, GetInitialExtensionThreshold());
247 EXPECT_TRUE(IsStorageNotificationEnabled(extension->id()));
249 // Fake clicking the notification button to disable notifications.
250 message_center::MessageCenter::Get()->ClickOnNotificationButton(
251 GetNotificationId(extension->id()),
252 ExtensionStorageMonitor::BUTTON_DISABLE_NOTIFICATION);
254 EXPECT_FALSE(IsStorageNotificationEnabled(extension->id()));
256 // Expect to receive no further notifications when usage continues to
257 // increase.
258 int64 next_threshold = GetNextStorageThreshold(extension->id());
259 int64 next_data_size = next_threshold - GetInitialExtensionThreshold();
260 ASSERT_GT(next_data_size, 0);
262 WriteBytesNotExpectingNotification(extension, next_data_size);
265 // Verify that thresholds for ephemeral apps are reset when they are
266 // promoted to regular installed apps.
267 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, EphemeralAppLowUsage) {
268 const Extension* extension = InitWriteDataEphemeralApp();
269 ASSERT_TRUE(extension);
270 WriteBytesExpectingNotification(extension, GetInitialEphemeralThreshold());
272 // Store the number of bytes until the next threshold is reached.
273 int64 next_threshold = GetNextStorageThreshold(extension->id());
274 int64 next_data_size = next_threshold - GetInitialEphemeralThreshold();
275 ASSERT_GT(next_data_size, 0);
276 EXPECT_GE(GetInitialExtensionThreshold(), next_threshold);
278 // Promote the ephemeral app.
279 ExtensionService* service =
280 ExtensionSystem::Get(profile())->extension_service();
281 service->PromoteEphemeralApp(extension, false);
283 // The next threshold should now be equal to the initial threshold for
284 // extensions (which is higher than the initial threshold for ephemeral apps).
285 EXPECT_EQ(GetInitialExtensionThreshold(),
286 GetNextStorageThreshold(extension->id()));
288 // Since the threshold was increased, a notification should not be
289 // triggered.
290 WriteBytesNotExpectingNotification(extension, next_data_size);
293 // Verify that thresholds for ephemeral apps are not reset when they are
294 // promoted to regular installed apps if their usage is higher than the initial
295 // threshold for installed extensions.
296 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, EphemeralAppWithHighUsage) {
297 const Extension* extension = InitWriteDataEphemeralApp();
298 ASSERT_TRUE(extension);
299 WriteBytesExpectingNotification(extension, GetInitialExtensionThreshold());
300 int64 saved_next_threshold = GetNextStorageThreshold(extension->id());
302 // Promote the ephemeral app.
303 ExtensionService* service =
304 ExtensionSystem::Get(profile())->extension_service();
305 service->PromoteEphemeralApp(extension, false);
307 // The next threshold should not have changed.
308 EXPECT_EQ(saved_next_threshold, GetNextStorageThreshold(extension->id()));
311 // Ensure that monitoring is disabled for installed extensions if
312 // |enable_for_all_extensions_| is false. This test can be removed if monitoring
313 // is eventually enabled for all extensions.
314 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest,
315 DisableForInstalledExtensions) {
316 DisableForInstalledExtensions();
318 const Extension* extension = InitWriteDataApp();
319 ASSERT_TRUE(extension);
320 WriteBytesNotExpectingNotification(extension, GetInitialExtensionThreshold());
323 // Verify that notifications are disabled when the user clicks the action button
324 // in the notification.
325 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, UninstallExtension) {
326 const Extension* extension = InitWriteDataApp();
327 ASSERT_TRUE(extension);
328 WriteBytesExpectingNotification(extension, GetInitialExtensionThreshold());
330 // Fake clicking the notification button to uninstall.
331 message_center::MessageCenter::Get()->ClickOnNotificationButton(
332 GetNotificationId(extension->id()),
333 ExtensionStorageMonitor::BUTTON_UNINSTALL);
335 // Also fake accepting the uninstall.
336 TestExtensionRegistryObserver observer(ExtensionRegistry::Get(profile()),
337 extension->id());
338 SimulateUninstallDialogAccept();
339 observer.WaitForExtensionUninstalled();
342 } // namespace extensions