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 <set> | 5 #include <set> |
6 | 6 |
7 #include "base/run_loop.h" | 7 #include "base/run_loop.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "chrome/browser/extensions/extension_browsertest.h" | 9 #include "chrome/browser/extensions/extension_browsertest.h" |
| 10 #include "chrome/browser/extensions/extension_service.h" |
10 #include "chrome/browser/extensions/extension_storage_monitor.h" | 11 #include "chrome/browser/extensions/extension_storage_monitor.h" |
11 #include "chrome/browser/extensions/extension_test_message_listener.h" | 12 #include "chrome/browser/extensions/extension_test_message_listener.h" |
12 #include "chrome/browser/ui/extensions/application_launch.h" | 13 #include "chrome/browser/ui/extensions/application_launch.h" |
13 #include "content/public/test/test_utils.h" | 14 #include "content/public/test/test_utils.h" |
14 #include "extensions/browser/extension_prefs.h" | 15 #include "extensions/browser/extension_prefs.h" |
| 16 #include "extensions/browser/extension_system.h" |
15 #include "ui/message_center/message_center.h" | 17 #include "ui/message_center/message_center.h" |
16 #include "ui/message_center/message_center_observer.h" | 18 #include "ui/message_center/message_center_observer.h" |
17 | 19 |
18 namespace extensions { | 20 namespace extensions { |
19 | 21 |
20 namespace { | 22 namespace { |
21 | 23 |
22 const int kInitialUsageThreshold = 500; | 24 const int kInitialUsageThreshold = 500; |
23 | 25 |
24 const char kWriteDataApp[] = "storage_monitor/write_data"; | 26 const char kWriteDataApp[] = "storage_monitor/write_data"; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 | 67 |
66 message_center::MessageCenter* message_center_; | 68 message_center::MessageCenter* message_center_; |
67 std::set<std::string> received_notifications_; | 69 std::set<std::string> received_notifications_; |
68 std::string target_notification_id_; | 70 std::string target_notification_id_; |
69 bool waiting_; | 71 bool waiting_; |
70 }; | 72 }; |
71 | 73 |
72 } // namespace | 74 } // namespace |
73 | 75 |
74 class ExtensionStorageMonitorTest : public ExtensionBrowserTest { | 76 class ExtensionStorageMonitorTest : public ExtensionBrowserTest { |
| 77 public: |
| 78 ExtensionStorageMonitorTest() : storage_monitor_(NULL) {} |
| 79 |
75 protected: | 80 protected: |
76 void InitStorageMonitor() { | 81 // ExtensionBrowserTest overrides: |
77 ExtensionStorageMonitor* monitor = ExtensionStorageMonitor::Get(profile()); | 82 virtual void SetUpOnMainThread() OVERRIDE { |
78 ASSERT_TRUE(monitor); | 83 ExtensionBrowserTest::SetUpOnMainThread(); |
79 | 84 |
80 // Override thresholds so that we don't have to write a huge amount of data | 85 InitStorageMonitor(); |
81 // to trigger notifications in these tests. | 86 } |
82 monitor->enable_for_all_extensions_ = true; | |
83 monitor->initial_extension_threshold_ = kInitialUsageThreshold; | |
84 | 87 |
85 // To ensure storage events are dispatched from QuotaManager immediately. | 88 ExtensionStorageMonitor* monitor() { |
86 monitor->observer_rate_ = 0; | 89 CHECK(storage_monitor_); |
| 90 return storage_monitor_; |
| 91 } |
| 92 |
| 93 int64 GetInitialExtensionThreshold() { |
| 94 CHECK(storage_monitor_); |
| 95 return storage_monitor_->initial_extension_threshold_; |
| 96 } |
| 97 |
| 98 int64 GetInitialEphemeralThreshold() { |
| 99 CHECK(storage_monitor_); |
| 100 return storage_monitor_->initial_ephemeral_threshold_; |
| 101 } |
| 102 |
| 103 void DisableForInstalledExtensions() { |
| 104 CHECK(storage_monitor_); |
| 105 storage_monitor_->enable_for_all_extensions_ = false; |
87 } | 106 } |
88 | 107 |
89 const Extension* InitWriteDataApp() { | 108 const Extension* InitWriteDataApp() { |
90 InitStorageMonitor(); | |
91 | |
92 base::FilePath path = test_data_dir_.AppendASCII(kWriteDataApp); | 109 base::FilePath path = test_data_dir_.AppendASCII(kWriteDataApp); |
93 const Extension* extension = InstallExtension(path, 1); | 110 const Extension* extension = InstallExtension(path, 1); |
94 EXPECT_TRUE(extension); | 111 EXPECT_TRUE(extension); |
95 return extension; | 112 return extension; |
96 } | 113 } |
97 | 114 |
| 115 const Extension* InitWriteDataEphemeralApp() { |
| 116 // The threshold for installed extensions should be higher than ephemeral |
| 117 // apps. |
| 118 storage_monitor_->initial_extension_threshold_ = |
| 119 storage_monitor_->initial_ephemeral_threshold_ * 4; |
| 120 |
| 121 base::FilePath path = test_data_dir_.AppendASCII(kWriteDataApp); |
| 122 const Extension* extension = InstallEphemeralAppWithSourceAndFlags( |
| 123 path, 1, Manifest::INTERNAL, Extension::NO_FLAGS); |
| 124 EXPECT_TRUE(extension); |
| 125 return extension; |
| 126 } |
| 127 |
98 std::string GetNotificationId(const std::string& extension_id) { | 128 std::string GetNotificationId(const std::string& extension_id) { |
99 return ExtensionStorageMonitor::Get(profile())-> | 129 return monitor()->GetNotificationId(extension_id); |
100 GetNotificationId(extension_id); | 130 } |
| 131 |
| 132 bool IsStorageNotificationEnabled(const std::string& extension_id) { |
| 133 return monitor()->IsStorageNotificationEnabled(extension_id); |
| 134 } |
| 135 |
| 136 int64 GetNextStorageThreshold(const std::string& extension_id) { |
| 137 return monitor()->GetNextStorageThreshold(extension_id); |
101 } | 138 } |
102 | 139 |
103 void WriteBytesExpectingNotification(const Extension* extension, | 140 void WriteBytesExpectingNotification(const Extension* extension, |
104 int num_bytes) { | 141 int num_bytes) { |
| 142 int64 previous_threshold = GetNextStorageThreshold(extension->id()); |
105 WriteBytes(extension, num_bytes, true); | 143 WriteBytes(extension, num_bytes, true); |
| 144 EXPECT_GT(GetNextStorageThreshold(extension->id()), previous_threshold); |
106 } | 145 } |
107 | 146 |
108 void WriteBytesNotExpectingNotification(const Extension* extension, | 147 void WriteBytesNotExpectingNotification(const Extension* extension, |
109 int num_bytes) { | 148 int num_bytes) { |
110 WriteBytes(extension, num_bytes, false); | 149 WriteBytes(extension, num_bytes, false); |
111 } | 150 } |
112 | 151 |
113 private: | 152 private: |
| 153 void InitStorageMonitor() { |
| 154 storage_monitor_ = ExtensionStorageMonitor::Get(profile()); |
| 155 ASSERT_TRUE(storage_monitor_); |
| 156 |
| 157 // Override thresholds so that we don't have to write a huge amount of data |
| 158 // to trigger notifications in these tests. |
| 159 storage_monitor_->enable_for_all_extensions_ = true; |
| 160 storage_monitor_->initial_extension_threshold_ = kInitialUsageThreshold; |
| 161 storage_monitor_->initial_ephemeral_threshold_ = kInitialUsageThreshold; |
| 162 |
| 163 // To ensure storage events are dispatched from QuotaManager immediately. |
| 164 storage_monitor_->observer_rate_ = 0; |
| 165 } |
| 166 |
114 // Write a number of bytes to persistent storage. | 167 // Write a number of bytes to persistent storage. |
115 void WriteBytes(const Extension* extension, | 168 void WriteBytes(const Extension* extension, |
116 int num_bytes, | 169 int num_bytes, |
117 bool expected_notification) { | 170 bool expected_notification) { |
118 ExtensionTestMessageListener launched_listener("launched", true); | 171 ExtensionTestMessageListener launched_listener("launched", true); |
119 ExtensionTestMessageListener write_complete_listener( | 172 ExtensionTestMessageListener write_complete_listener( |
120 "write_complete", false); | 173 "write_complete", false); |
121 NotificationObserver notification_observer( | 174 NotificationObserver notification_observer( |
122 GetNotificationId(extension->id())); | 175 GetNotificationId(extension->id())); |
123 | 176 |
124 OpenApplication(AppLaunchParams( | 177 OpenApplication(AppLaunchParams( |
125 profile(), extension, LAUNCH_CONTAINER_NONE, NEW_WINDOW)); | 178 profile(), extension, LAUNCH_CONTAINER_NONE, NEW_WINDOW)); |
126 ASSERT_TRUE(launched_listener.WaitUntilSatisfied()); | 179 ASSERT_TRUE(launched_listener.WaitUntilSatisfied()); |
127 | 180 |
128 // Instruct the app to write |num_bytes| of data. | 181 // Instruct the app to write |num_bytes| of data. |
129 launched_listener.Reply(base::IntToString(num_bytes)); | 182 launched_listener.Reply(base::IntToString(num_bytes)); |
130 ASSERT_TRUE(write_complete_listener.WaitUntilSatisfied()); | 183 ASSERT_TRUE(write_complete_listener.WaitUntilSatisfied()); |
131 | 184 |
132 if (expected_notification) { | 185 if (expected_notification) { |
133 EXPECT_TRUE(notification_observer.WaitForNotification()); | 186 EXPECT_TRUE(notification_observer.WaitForNotification()); |
134 } else { | 187 } else { |
135 base::RunLoop().RunUntilIdle(); | 188 base::RunLoop().RunUntilIdle(); |
136 EXPECT_FALSE(notification_observer.HasReceivedNotification()); | 189 EXPECT_FALSE(notification_observer.HasReceivedNotification()); |
137 } | 190 } |
138 } | 191 } |
| 192 |
| 193 ExtensionStorageMonitor* storage_monitor_; |
139 }; | 194 }; |
140 | 195 |
141 // Control - No notifications should be shown if usage remains under the | 196 // Control - No notifications should be shown if usage remains under the |
142 // threshold. | 197 // threshold. |
143 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, UnderThreshold) { | 198 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, UnderThreshold) { |
144 const Extension* extension = InitWriteDataApp(); | 199 const Extension* extension = InitWriteDataApp(); |
145 ASSERT_TRUE(extension); | 200 ASSERT_TRUE(extension); |
146 WriteBytesNotExpectingNotification(extension, 1); | 201 WriteBytesNotExpectingNotification(extension, 1); |
147 } | 202 } |
148 | 203 |
149 // Ensure a notification is shown when usage reaches the first threshold. | 204 // Ensure a notification is shown when usage reaches the first threshold. |
150 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, ExceedInitialThreshold) { | 205 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, ExceedInitialThreshold) { |
151 const Extension* extension = InitWriteDataApp(); | 206 const Extension* extension = InitWriteDataApp(); |
152 ASSERT_TRUE(extension); | 207 ASSERT_TRUE(extension); |
153 WriteBytesExpectingNotification(extension, kInitialUsageThreshold); | 208 WriteBytesExpectingNotification(extension, GetInitialExtensionThreshold()); |
154 } | 209 } |
155 | 210 |
156 // Ensure a notification is shown when usage immediately exceeds double the | 211 // Ensure a notification is shown when usage immediately exceeds double the |
157 // first threshold. | 212 // first threshold. |
158 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, DoubleInitialThreshold) { | 213 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, DoubleInitialThreshold) { |
159 const Extension* extension = InitWriteDataApp(); | 214 const Extension* extension = InitWriteDataApp(); |
160 ASSERT_TRUE(extension); | 215 ASSERT_TRUE(extension); |
161 WriteBytesExpectingNotification(extension, kInitialUsageThreshold*2); | 216 WriteBytesExpectingNotification(extension, |
| 217 GetInitialExtensionThreshold() * 2); |
162 } | 218 } |
163 | 219 |
164 // Ensure that notifications are not fired if the next threshold has not been | 220 // Ensure that notifications are not fired if the next threshold has not been |
165 // reached. | 221 // reached. |
166 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, ThrottleNotifications) { | 222 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, ThrottleNotifications) { |
167 const Extension* extension = InitWriteDataApp(); | 223 const Extension* extension = InitWriteDataApp(); |
168 ASSERT_TRUE(extension); | 224 ASSERT_TRUE(extension); |
169 | 225 |
170 // Exceed the first threshold. | 226 // Exceed the first threshold. |
171 WriteBytesExpectingNotification(extension, kInitialUsageThreshold); | 227 WriteBytesExpectingNotification(extension, GetInitialExtensionThreshold()); |
172 | 228 |
173 // Stay within the next threshold. | 229 // Stay within the next threshold. |
174 WriteBytesNotExpectingNotification(extension, 1); | 230 WriteBytesNotExpectingNotification(extension, 1); |
175 } | 231 } |
176 | 232 |
177 // Verify that notifications are disabled when the user clicks the action button | 233 // Verify that notifications are disabled when the user clicks the action button |
178 // in the notification. | 234 // in the notification. |
179 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, UserDisabledNotifications) { | 235 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, UserDisabledNotifications) { |
180 const Extension* extension = InitWriteDataApp(); | 236 const Extension* extension = InitWriteDataApp(); |
181 ASSERT_TRUE(extension); | 237 ASSERT_TRUE(extension); |
182 WriteBytesExpectingNotification(extension, kInitialUsageThreshold); | 238 WriteBytesExpectingNotification(extension, GetInitialExtensionThreshold()); |
183 | 239 |
184 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); | 240 EXPECT_TRUE(IsStorageNotificationEnabled(extension->id())); |
185 ASSERT_TRUE(prefs); | |
186 EXPECT_TRUE(prefs->IsStorageNotificationEnabled(extension->id())); | |
187 | 241 |
188 // Fake clicking the notification button. | 242 // Fake clicking the notification button. |
189 message_center::MessageCenter::Get()->ClickOnNotificationButton( | 243 message_center::MessageCenter::Get()->ClickOnNotificationButton( |
190 GetNotificationId(extension->id()), | 244 GetNotificationId(extension->id()), |
191 ExtensionStorageMonitor::BUTTON_DISABLE_NOTIFICATION); | 245 ExtensionStorageMonitor::BUTTON_DISABLE_NOTIFICATION); |
192 | 246 |
193 EXPECT_FALSE(prefs->IsStorageNotificationEnabled(extension->id())); | 247 EXPECT_FALSE(IsStorageNotificationEnabled(extension->id())); |
194 | 248 |
195 // Expect to receive no further notifications when usage continues to | 249 // Expect to receive no further notifications when usage continues to |
196 // increase. | 250 // increase. |
197 int64 next_threshold = prefs->GetNextStorageThreshold(extension->id()); | 251 int64 next_threshold = GetNextStorageThreshold(extension->id()); |
198 int64 next_data_size = next_threshold - kInitialUsageThreshold; | 252 int64 next_data_size = next_threshold - GetInitialExtensionThreshold(); |
199 ASSERT_GE(next_data_size, 0); | 253 ASSERT_GT(next_data_size, 0); |
200 | 254 |
201 WriteBytesNotExpectingNotification(extension, next_data_size); | 255 WriteBytesNotExpectingNotification(extension, next_data_size); |
202 } | 256 } |
203 | 257 |
| 258 // Verify that thresholds for ephemeral apps are reset when they are |
| 259 // promoted to regular installed apps. |
| 260 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, EphemeralAppLowUsage) { |
| 261 const Extension* extension = InitWriteDataEphemeralApp(); |
| 262 ASSERT_TRUE(extension); |
| 263 WriteBytesExpectingNotification(extension, GetInitialEphemeralThreshold()); |
| 264 |
| 265 // Store the number of bytes until the next threshold is reached. |
| 266 int64 next_threshold = GetNextStorageThreshold(extension->id()); |
| 267 int64 next_data_size = next_threshold - GetInitialEphemeralThreshold(); |
| 268 ASSERT_GT(next_data_size, 0); |
| 269 EXPECT_GE(GetInitialExtensionThreshold(), next_threshold); |
| 270 |
| 271 // Promote the ephemeral app. |
| 272 ExtensionService* service = |
| 273 ExtensionSystem::Get(profile())->extension_service(); |
| 274 service->PromoteEphemeralApp(extension, false); |
| 275 |
| 276 // The next threshold should now be equal to the initial threshold for |
| 277 // extensions (which is higher than the initial threshold for ephemeral apps). |
| 278 EXPECT_EQ(GetInitialExtensionThreshold(), |
| 279 GetNextStorageThreshold(extension->id())); |
| 280 |
| 281 // Since the threshold was increased, a notification should not be |
| 282 // triggered. |
| 283 WriteBytesNotExpectingNotification(extension, next_data_size); |
| 284 } |
| 285 |
| 286 // Verify that thresholds for ephemeral apps are not reset when they are |
| 287 // promoted to regular installed apps if their usage is higher than the initial |
| 288 // threshold for installed extensions. |
| 289 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, EphemeralAppWithHighUsage) { |
| 290 const Extension* extension = InitWriteDataEphemeralApp(); |
| 291 ASSERT_TRUE(extension); |
| 292 WriteBytesExpectingNotification(extension, GetInitialExtensionThreshold()); |
| 293 int64 saved_next_threshold = GetNextStorageThreshold(extension->id()); |
| 294 |
| 295 // Promote the ephemeral app. |
| 296 ExtensionService* service = |
| 297 ExtensionSystem::Get(profile())->extension_service(); |
| 298 service->PromoteEphemeralApp(extension, false); |
| 299 |
| 300 // The next threshold should not have changed. |
| 301 EXPECT_EQ(saved_next_threshold, GetNextStorageThreshold(extension->id())); |
| 302 } |
| 303 |
| 304 // Ensure that monitoring is disabled for installed extensions if |
| 305 // |enable_for_all_extensions_| is false. This test can be removed if monitoring |
| 306 // is eventually enabled for all extensions. |
| 307 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, |
| 308 DisableForInstalledExtensions) { |
| 309 DisableForInstalledExtensions(); |
| 310 |
| 311 const Extension* extension = InitWriteDataApp(); |
| 312 ASSERT_TRUE(extension); |
| 313 WriteBytesNotExpectingNotification(extension, GetInitialExtensionThreshold()); |
| 314 } |
204 } // namespace extensions | 315 } // namespace extensions |
OLD | NEW |