OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/extensions/user_script_listener.h" |
| 6 |
| 7 #include <memory> |
| 8 |
5 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
6 #include "base/json/json_file_value_serializer.h" | 10 #include "base/json/json_file_value_serializer.h" |
7 #include "base/macros.h" | 11 #include "base/macros.h" |
8 #include "base/memory/scoped_ptr.h" | |
9 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
10 #include "base/threading/thread.h" | 13 #include "base/threading/thread.h" |
11 #include "chrome/browser/chrome_notification_types.h" | 14 #include "chrome/browser/chrome_notification_types.h" |
12 #include "chrome/browser/extensions/extension_service.h" | 15 #include "chrome/browser/extensions/extension_service.h" |
13 #include "chrome/browser/extensions/extension_service_test_base.h" | 16 #include "chrome/browser/extensions/extension_service_test_base.h" |
14 #include "chrome/browser/extensions/unpacked_installer.h" | 17 #include "chrome/browser/extensions/unpacked_installer.h" |
15 #include "chrome/browser/extensions/user_script_listener.h" | |
16 #include "chrome/common/chrome_paths.h" | 18 #include "chrome/common/chrome_paths.h" |
17 #include "chrome/test/base/testing_profile.h" | 19 #include "chrome/test/base/testing_profile.h" |
18 #include "content/public/browser/notification_service.h" | 20 #include "content/public/browser/notification_service.h" |
19 #include "content/public/browser/resource_controller.h" | 21 #include "content/public/browser/resource_controller.h" |
20 #include "content/public/browser/resource_throttle.h" | 22 #include "content/public/browser/resource_throttle.h" |
21 #include "extensions/browser/extension_registry.h" | 23 #include "extensions/browser/extension_registry.h" |
22 #include "net/base/request_priority.h" | 24 #include "net/base/request_priority.h" |
23 #include "net/url_request/url_request.h" | 25 #include "net/url_request/url_request.h" |
24 #include "net/url_request/url_request_filter.h" | 26 #include "net/url_request/url_request_filter.h" |
25 #include "net/url_request/url_request_interceptor.h" | 27 #include "net/url_request/url_request_interceptor.h" |
(...skipping 23 matching lines...) Expand all Loading... |
49 } | 51 } |
50 | 52 |
51 // ResourceController implementation: | 53 // ResourceController implementation: |
52 void Resume() override { request_->Start(); } | 54 void Resume() override { request_->Start(); } |
53 void Cancel() override { NOTREACHED(); } | 55 void Cancel() override { NOTREACHED(); } |
54 void CancelAndIgnore() override { NOTREACHED(); } | 56 void CancelAndIgnore() override { NOTREACHED(); } |
55 void CancelWithError(int error_code) override { NOTREACHED(); } | 57 void CancelWithError(int error_code) override { NOTREACHED(); } |
56 | 58 |
57 private: | 59 private: |
58 net::URLRequest* request_; | 60 net::URLRequest* request_; |
59 scoped_ptr<ResourceThrottle> throttle_; | 61 std::unique_ptr<ResourceThrottle> throttle_; |
60 }; | 62 }; |
61 | 63 |
62 // A simple test net::URLRequestJob. We don't care what it does, only that | 64 // A simple test net::URLRequestJob. We don't care what it does, only that |
63 // whether it starts and finishes. | 65 // whether it starts and finishes. |
64 class SimpleTestJob : public net::URLRequestTestJob { | 66 class SimpleTestJob : public net::URLRequestTestJob { |
65 public: | 67 public: |
66 SimpleTestJob(net::URLRequest* request, | 68 SimpleTestJob(net::URLRequest* request, |
67 net::NetworkDelegate* network_delegate) | 69 net::NetworkDelegate* network_delegate) |
68 : net::URLRequestTestJob(request, | 70 : net::URLRequestTestJob(request, |
69 network_delegate, | 71 network_delegate, |
70 test_headers(), | 72 test_headers(), |
71 kTestData, | 73 kTestData, |
72 true) {} | 74 true) {} |
73 private: | 75 private: |
74 ~SimpleTestJob() override {} | 76 ~SimpleTestJob() override {} |
75 }; | 77 }; |
76 | 78 |
77 // Yoinked from extension_manifest_unittest.cc. | 79 // Yoinked from extension_manifest_unittest.cc. |
78 scoped_ptr<base::DictionaryValue> LoadManifestFile(const base::FilePath path, | 80 std::unique_ptr<base::DictionaryValue> LoadManifestFile( |
79 std::string* error) { | 81 const base::FilePath path, |
| 82 std::string* error) { |
80 EXPECT_TRUE(base::PathExists(path)); | 83 EXPECT_TRUE(base::PathExists(path)); |
81 JSONFileValueDeserializer deserializer(path); | 84 JSONFileValueDeserializer deserializer(path); |
82 return base::DictionaryValue::From(deserializer.Deserialize(NULL, error)); | 85 return base::DictionaryValue::From(deserializer.Deserialize(NULL, error)); |
83 } | 86 } |
84 | 87 |
85 scoped_refptr<Extension> LoadExtension(const std::string& filename, | 88 scoped_refptr<Extension> LoadExtension(const std::string& filename, |
86 std::string* error) { | 89 std::string* error) { |
87 base::FilePath path; | 90 base::FilePath path; |
88 PathService::Get(chrome::DIR_TEST_DATA, &path); | 91 PathService::Get(chrome::DIR_TEST_DATA, &path); |
89 path = path. | 92 path = path. |
90 AppendASCII("extensions"). | 93 AppendASCII("extensions"). |
91 AppendASCII("manifest_tests"). | 94 AppendASCII("manifest_tests"). |
92 AppendASCII(filename.c_str()); | 95 AppendASCII(filename.c_str()); |
93 scoped_ptr<base::DictionaryValue> value = LoadManifestFile(path, error); | 96 std::unique_ptr<base::DictionaryValue> value = LoadManifestFile(path, error); |
94 if (!value) | 97 if (!value) |
95 return NULL; | 98 return NULL; |
96 return Extension::Create(path.DirName(), Manifest::UNPACKED, *value, | 99 return Extension::Create(path.DirName(), Manifest::UNPACKED, *value, |
97 Extension::NO_FLAGS, error); | 100 Extension::NO_FLAGS, error); |
98 } | 101 } |
99 | 102 |
100 class SimpleTestJobURLRequestInterceptor | 103 class SimpleTestJobURLRequestInterceptor |
101 : public net::URLRequestInterceptor { | 104 : public net::URLRequestInterceptor { |
102 public: | 105 public: |
103 SimpleTestJobURLRequestInterceptor() {} | 106 SimpleTestJobURLRequestInterceptor() {} |
104 ~SimpleTestJobURLRequestInterceptor() override {} | 107 ~SimpleTestJobURLRequestInterceptor() override {} |
105 | 108 |
106 // net::URLRequestJobFactory::ProtocolHandler | 109 // net::URLRequestJobFactory::ProtocolHandler |
107 net::URLRequestJob* MaybeInterceptRequest( | 110 net::URLRequestJob* MaybeInterceptRequest( |
108 net::URLRequest* request, | 111 net::URLRequest* request, |
109 net::NetworkDelegate* network_delegate) const override { | 112 net::NetworkDelegate* network_delegate) const override { |
110 return new SimpleTestJob(request, network_delegate); | 113 return new SimpleTestJob(request, network_delegate); |
111 } | 114 } |
112 | 115 |
113 private: | 116 private: |
114 DISALLOW_COPY_AND_ASSIGN(SimpleTestJobURLRequestInterceptor); | 117 DISALLOW_COPY_AND_ASSIGN(SimpleTestJobURLRequestInterceptor); |
115 }; | 118 }; |
116 | 119 |
117 } // namespace | 120 } // namespace |
118 | 121 |
119 class UserScriptListenerTest : public ExtensionServiceTestBase { | 122 class UserScriptListenerTest : public ExtensionServiceTestBase { |
120 public: | 123 public: |
121 UserScriptListenerTest() { | 124 UserScriptListenerTest() { |
122 net::URLRequestFilter::GetInstance()->AddHostnameInterceptor( | 125 net::URLRequestFilter::GetInstance()->AddHostnameInterceptor( |
123 "http", "google.com", | 126 "http", "google.com", std::unique_ptr<net::URLRequestInterceptor>( |
124 scoped_ptr<net::URLRequestInterceptor>( | 127 new SimpleTestJobURLRequestInterceptor())); |
125 new SimpleTestJobURLRequestInterceptor())); | |
126 net::URLRequestFilter::GetInstance()->AddHostnameInterceptor( | 128 net::URLRequestFilter::GetInstance()->AddHostnameInterceptor( |
127 "http", "example.com", | 129 "http", "example.com", std::unique_ptr<net::URLRequestInterceptor>( |
128 scoped_ptr<net::URLRequestInterceptor>( | 130 new SimpleTestJobURLRequestInterceptor())); |
129 new SimpleTestJobURLRequestInterceptor())); | |
130 } | 131 } |
131 | 132 |
132 ~UserScriptListenerTest() override { | 133 ~UserScriptListenerTest() override { |
133 net::URLRequestFilter::GetInstance()->RemoveHostnameHandler("http", | 134 net::URLRequestFilter::GetInstance()->RemoveHostnameHandler("http", |
134 "google.com"); | 135 "google.com"); |
135 net::URLRequestFilter::GetInstance()->RemoveHostnameHandler("http", | 136 net::URLRequestFilter::GetInstance()->RemoveHostnameHandler("http", |
136 "example.com"); | 137 "example.com"); |
137 } | 138 } |
138 | 139 |
139 void SetUp() override { | 140 void SetUp() override { |
140 ExtensionServiceTestBase::SetUp(); | 141 ExtensionServiceTestBase::SetUp(); |
141 | 142 |
142 InitializeEmptyExtensionService(); | 143 InitializeEmptyExtensionService(); |
143 service_->Init(); | 144 service_->Init(); |
144 base::MessageLoop::current()->RunUntilIdle(); | 145 base::MessageLoop::current()->RunUntilIdle(); |
145 | 146 |
146 listener_ = new UserScriptListener(); | 147 listener_ = new UserScriptListener(); |
147 } | 148 } |
148 | 149 |
149 void TearDown() override { | 150 void TearDown() override { |
150 listener_ = NULL; | 151 listener_ = NULL; |
151 base::MessageLoop::current()->RunUntilIdle(); | 152 base::MessageLoop::current()->RunUntilIdle(); |
152 ExtensionServiceTestBase::TearDown(); | 153 ExtensionServiceTestBase::TearDown(); |
153 } | 154 } |
154 | 155 |
155 protected: | 156 protected: |
156 scoped_ptr<net::URLRequest> StartTestRequest( | 157 std::unique_ptr<net::URLRequest> StartTestRequest( |
157 net::URLRequest::Delegate* delegate, | 158 net::URLRequest::Delegate* delegate, |
158 const std::string& url_string, | 159 const std::string& url_string, |
159 net::TestURLRequestContext* context) { | 160 net::TestURLRequestContext* context) { |
160 GURL url(url_string); | 161 GURL url(url_string); |
161 scoped_ptr<net::URLRequest> request(context->CreateRequest( | 162 std::unique_ptr<net::URLRequest> request( |
162 url, net::DEFAULT_PRIORITY, delegate)); | 163 context->CreateRequest(url, net::DEFAULT_PRIORITY, delegate)); |
163 | 164 |
164 ResourceThrottle* throttle = listener_->CreateResourceThrottle( | 165 ResourceThrottle* throttle = listener_->CreateResourceThrottle( |
165 url, content::RESOURCE_TYPE_MAIN_FRAME); | 166 url, content::RESOURCE_TYPE_MAIN_FRAME); |
166 | 167 |
167 bool defer = false; | 168 bool defer = false; |
168 if (throttle) { | 169 if (throttle) { |
169 request->SetUserData(NULL, | 170 request->SetUserData(NULL, |
170 new ThrottleController(request.get(), throttle)); | 171 new ThrottleController(request.get(), throttle)); |
171 | 172 |
172 throttle->WillStartRequest(&defer); | 173 throttle->WillStartRequest(&defer); |
(...skipping 29 matching lines...) Expand all Loading... |
202 }; | 203 }; |
203 | 204 |
204 namespace { | 205 namespace { |
205 | 206 |
206 TEST_F(UserScriptListenerTest, DelayAndUpdate) { | 207 TEST_F(UserScriptListenerTest, DelayAndUpdate) { |
207 LoadTestExtension(); | 208 LoadTestExtension(); |
208 base::MessageLoop::current()->RunUntilIdle(); | 209 base::MessageLoop::current()->RunUntilIdle(); |
209 | 210 |
210 net::TestDelegate delegate; | 211 net::TestDelegate delegate; |
211 net::TestURLRequestContext context; | 212 net::TestURLRequestContext context; |
212 scoped_ptr<net::URLRequest> request( | 213 std::unique_ptr<net::URLRequest> request( |
213 StartTestRequest(&delegate, kMatchingUrl, &context)); | 214 StartTestRequest(&delegate, kMatchingUrl, &context)); |
214 ASSERT_FALSE(request->is_pending()); | 215 ASSERT_FALSE(request->is_pending()); |
215 | 216 |
216 content::NotificationService::current()->Notify( | 217 content::NotificationService::current()->Notify( |
217 extensions::NOTIFICATION_USER_SCRIPTS_UPDATED, | 218 extensions::NOTIFICATION_USER_SCRIPTS_UPDATED, |
218 content::Source<Profile>(profile_.get()), | 219 content::Source<Profile>(profile_.get()), |
219 content::NotificationService::NoDetails()); | 220 content::NotificationService::NoDetails()); |
220 base::MessageLoop::current()->RunUntilIdle(); | 221 base::MessageLoop::current()->RunUntilIdle(); |
221 EXPECT_EQ(kTestData, delegate.data_received()); | 222 EXPECT_EQ(kTestData, delegate.data_received()); |
222 } | 223 } |
223 | 224 |
224 TEST_F(UserScriptListenerTest, DelayAndUnload) { | 225 TEST_F(UserScriptListenerTest, DelayAndUnload) { |
225 LoadTestExtension(); | 226 LoadTestExtension(); |
226 base::MessageLoop::current()->RunUntilIdle(); | 227 base::MessageLoop::current()->RunUntilIdle(); |
227 | 228 |
228 net::TestDelegate delegate; | 229 net::TestDelegate delegate; |
229 net::TestURLRequestContext context; | 230 net::TestURLRequestContext context; |
230 scoped_ptr<net::URLRequest> request( | 231 std::unique_ptr<net::URLRequest> request( |
231 StartTestRequest(&delegate, kMatchingUrl, &context)); | 232 StartTestRequest(&delegate, kMatchingUrl, &context)); |
232 ASSERT_FALSE(request->is_pending()); | 233 ASSERT_FALSE(request->is_pending()); |
233 | 234 |
234 UnloadTestExtension(); | 235 UnloadTestExtension(); |
235 base::MessageLoop::current()->RunUntilIdle(); | 236 base::MessageLoop::current()->RunUntilIdle(); |
236 | 237 |
237 // This is still not enough to start delayed requests. We have to notify the | 238 // This is still not enough to start delayed requests. We have to notify the |
238 // listener that the user scripts have been updated. | 239 // listener that the user scripts have been updated. |
239 ASSERT_FALSE(request->is_pending()); | 240 ASSERT_FALSE(request->is_pending()); |
240 | 241 |
241 content::NotificationService::current()->Notify( | 242 content::NotificationService::current()->Notify( |
242 extensions::NOTIFICATION_USER_SCRIPTS_UPDATED, | 243 extensions::NOTIFICATION_USER_SCRIPTS_UPDATED, |
243 content::Source<Profile>(profile_.get()), | 244 content::Source<Profile>(profile_.get()), |
244 content::NotificationService::NoDetails()); | 245 content::NotificationService::NoDetails()); |
245 base::MessageLoop::current()->RunUntilIdle(); | 246 base::MessageLoop::current()->RunUntilIdle(); |
246 EXPECT_EQ(kTestData, delegate.data_received()); | 247 EXPECT_EQ(kTestData, delegate.data_received()); |
247 } | 248 } |
248 | 249 |
249 TEST_F(UserScriptListenerTest, NoDelayNoExtension) { | 250 TEST_F(UserScriptListenerTest, NoDelayNoExtension) { |
250 net::TestDelegate delegate; | 251 net::TestDelegate delegate; |
251 net::TestURLRequestContext context; | 252 net::TestURLRequestContext context; |
252 scoped_ptr<net::URLRequest> request( | 253 std::unique_ptr<net::URLRequest> request( |
253 StartTestRequest(&delegate, kMatchingUrl, &context)); | 254 StartTestRequest(&delegate, kMatchingUrl, &context)); |
254 | 255 |
255 // The request should be started immediately. | 256 // The request should be started immediately. |
256 ASSERT_TRUE(request->is_pending()); | 257 ASSERT_TRUE(request->is_pending()); |
257 | 258 |
258 base::MessageLoop::current()->RunUntilIdle(); | 259 base::MessageLoop::current()->RunUntilIdle(); |
259 EXPECT_EQ(kTestData, delegate.data_received()); | 260 EXPECT_EQ(kTestData, delegate.data_received()); |
260 } | 261 } |
261 | 262 |
262 TEST_F(UserScriptListenerTest, NoDelayNotMatching) { | 263 TEST_F(UserScriptListenerTest, NoDelayNotMatching) { |
263 LoadTestExtension(); | 264 LoadTestExtension(); |
264 base::MessageLoop::current()->RunUntilIdle(); | 265 base::MessageLoop::current()->RunUntilIdle(); |
265 | 266 |
266 net::TestDelegate delegate; | 267 net::TestDelegate delegate; |
267 net::TestURLRequestContext context; | 268 net::TestURLRequestContext context; |
268 scoped_ptr<net::URLRequest> request( | 269 std::unique_ptr<net::URLRequest> request( |
269 StartTestRequest(&delegate, kNotMatchingUrl, &context)); | 270 StartTestRequest(&delegate, kNotMatchingUrl, &context)); |
270 | 271 |
271 // The request should be started immediately. | 272 // The request should be started immediately. |
272 ASSERT_TRUE(request->is_pending()); | 273 ASSERT_TRUE(request->is_pending()); |
273 | 274 |
274 base::MessageLoop::current()->RunUntilIdle(); | 275 base::MessageLoop::current()->RunUntilIdle(); |
275 EXPECT_EQ(kTestData, delegate.data_received()); | 276 EXPECT_EQ(kTestData, delegate.data_received()); |
276 } | 277 } |
277 | 278 |
278 TEST_F(UserScriptListenerTest, MultiProfile) { | 279 TEST_F(UserScriptListenerTest, MultiProfile) { |
(...skipping 10 matching lines...) Expand all Loading... |
289 | 290 |
290 extensions::ExtensionRegistry::Get(&profile2)->AddEnabled(extension); | 291 extensions::ExtensionRegistry::Get(&profile2)->AddEnabled(extension); |
291 | 292 |
292 content::NotificationService::current()->Notify( | 293 content::NotificationService::current()->Notify( |
293 extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, | 294 extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, |
294 content::Source<Profile>(&profile2), | 295 content::Source<Profile>(&profile2), |
295 content::Details<Extension>(extension.get())); | 296 content::Details<Extension>(extension.get())); |
296 | 297 |
297 net::TestDelegate delegate; | 298 net::TestDelegate delegate; |
298 net::TestURLRequestContext context; | 299 net::TestURLRequestContext context; |
299 scoped_ptr<net::URLRequest> request( | 300 std::unique_ptr<net::URLRequest> request( |
300 StartTestRequest(&delegate, kMatchingUrl, &context)); | 301 StartTestRequest(&delegate, kMatchingUrl, &context)); |
301 ASSERT_FALSE(request->is_pending()); | 302 ASSERT_FALSE(request->is_pending()); |
302 | 303 |
303 // When the first profile's user scripts are ready, the request should still | 304 // When the first profile's user scripts are ready, the request should still |
304 // be blocked waiting for profile2. | 305 // be blocked waiting for profile2. |
305 content::NotificationService::current()->Notify( | 306 content::NotificationService::current()->Notify( |
306 extensions::NOTIFICATION_USER_SCRIPTS_UPDATED, | 307 extensions::NOTIFICATION_USER_SCRIPTS_UPDATED, |
307 content::Source<Profile>(profile_.get()), | 308 content::Source<Profile>(profile_.get()), |
308 content::NotificationService::NoDetails()); | 309 content::NotificationService::NoDetails()); |
309 base::MessageLoop::current()->RunUntilIdle(); | 310 base::MessageLoop::current()->RunUntilIdle(); |
(...skipping 11 matching lines...) Expand all Loading... |
321 | 322 |
322 // Test when the script updated notification occurs before the throttle's | 323 // Test when the script updated notification occurs before the throttle's |
323 // WillStartRequest function is called. This can occur when there are multiple | 324 // WillStartRequest function is called. This can occur when there are multiple |
324 // throttles. | 325 // throttles. |
325 TEST_F(UserScriptListenerTest, ResumeBeforeStart) { | 326 TEST_F(UserScriptListenerTest, ResumeBeforeStart) { |
326 LoadTestExtension(); | 327 LoadTestExtension(); |
327 base::MessageLoop::current()->RunUntilIdle(); | 328 base::MessageLoop::current()->RunUntilIdle(); |
328 net::TestDelegate delegate; | 329 net::TestDelegate delegate; |
329 net::TestURLRequestContext context; | 330 net::TestURLRequestContext context; |
330 GURL url(kMatchingUrl); | 331 GURL url(kMatchingUrl); |
331 scoped_ptr<net::URLRequest> request(context.CreateRequest( | 332 std::unique_ptr<net::URLRequest> request( |
332 url, net::DEFAULT_PRIORITY, &delegate)); | 333 context.CreateRequest(url, net::DEFAULT_PRIORITY, &delegate)); |
333 | 334 |
334 ResourceThrottle* throttle = | 335 ResourceThrottle* throttle = |
335 listener_->CreateResourceThrottle(url, content::RESOURCE_TYPE_MAIN_FRAME); | 336 listener_->CreateResourceThrottle(url, content::RESOURCE_TYPE_MAIN_FRAME); |
336 ASSERT_TRUE(throttle); | 337 ASSERT_TRUE(throttle); |
337 request->SetUserData(NULL, new ThrottleController(request.get(), throttle)); | 338 request->SetUserData(NULL, new ThrottleController(request.get(), throttle)); |
338 | 339 |
339 ASSERT_FALSE(request->is_pending()); | 340 ASSERT_FALSE(request->is_pending()); |
340 | 341 |
341 content::NotificationService::current()->Notify( | 342 content::NotificationService::current()->Notify( |
342 extensions::NOTIFICATION_USER_SCRIPTS_UPDATED, | 343 extensions::NOTIFICATION_USER_SCRIPTS_UPDATED, |
343 content::Source<Profile>(profile_.get()), | 344 content::Source<Profile>(profile_.get()), |
344 content::NotificationService::NoDetails()); | 345 content::NotificationService::NoDetails()); |
345 base::MessageLoop::current()->RunUntilIdle(); | 346 base::MessageLoop::current()->RunUntilIdle(); |
346 | 347 |
347 bool defer = false; | 348 bool defer = false; |
348 throttle->WillStartRequest(&defer); | 349 throttle->WillStartRequest(&defer); |
349 ASSERT_FALSE(defer); | 350 ASSERT_FALSE(defer); |
350 } | 351 } |
351 | 352 |
352 } // namespace | 353 } // namespace |
353 | 354 |
354 } // namespace extensions | 355 } // namespace extensions |
OLD | NEW |