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 "content/browser/plugin_service_impl.h" | 5 #include "content/browser/plugin_service_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
11 #include "chrome/browser/ui/browser.h" | 11 #include "content/public/browser/browser_context.h" |
12 #include "chrome/test/base/in_process_browser_test.h" | |
13 #include "chrome/test/base/testing_profile.h" | |
14 #include "chrome/test/base/ui_test_utils.h" | |
15 #include "content/public/browser/resource_context.h" | 12 #include "content/public/browser/resource_context.h" |
| 13 #include "content/public/browser/web_contents.h" |
16 #include "content/public/common/content_switches.h" | 14 #include "content/public/common/content_switches.h" |
17 #include "content/public/test/test_browser_thread.h" | 15 #include "content/public/test/test_browser_thread.h" |
| 16 #include "content/public/test/test_utils.h" |
| 17 #include "content/shell/shell.h" |
| 18 #include "content/test/content_browser_test.h" |
18 #include "testing/gmock/include/gmock/gmock.h" | 19 #include "testing/gmock/include/gmock/gmock.h" |
19 #include "webkit/plugins/npapi/plugin_list.h" | 20 #include "webkit/plugins/npapi/plugin_list.h" |
20 | 21 |
21 using content::BrowserThread; | 22 namespace content { |
22 | |
23 namespace { | |
24 | 23 |
25 const char kNPAPITestPluginMimeType[] = "application/vnd.npapi-test"; | 24 const char kNPAPITestPluginMimeType[] = "application/vnd.npapi-test"; |
26 | 25 |
27 void OpenChannel(PluginProcessHost::Client* client) { | 26 void OpenChannel(PluginProcessHost::Client* client) { |
28 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 27 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
29 // Start opening the channel | 28 // Start opening the channel |
30 PluginServiceImpl::GetInstance()->OpenChannelToNpapiPlugin( | 29 PluginServiceImpl::GetInstance()->OpenChannelToNpapiPlugin( |
31 0, 0, GURL(), GURL(), kNPAPITestPluginMimeType, client); | 30 0, 0, GURL(), GURL(), kNPAPITestPluginMimeType, client); |
32 } | 31 } |
33 | 32 |
34 // Mock up of the Client and the Listener classes that would supply the | 33 // Mock up of the Client and the Listener classes that would supply the |
35 // communication channel with the plugin. | 34 // communication channel with the plugin. |
36 class MockPluginProcessHostClient : public PluginProcessHost::Client, | 35 class MockPluginProcessHostClient : public PluginProcessHost::Client, |
37 public IPC::Listener { | 36 public IPC::Listener { |
38 public: | 37 public: |
39 MockPluginProcessHostClient(content::ResourceContext* context) | 38 MockPluginProcessHostClient(ResourceContext* context) |
40 : context_(context), | 39 : context_(context), |
41 channel_(NULL), | 40 channel_(NULL), |
42 set_plugin_info_called_(false) { | 41 set_plugin_info_called_(false) { |
43 } | 42 } |
44 | 43 |
45 virtual ~MockPluginProcessHostClient() { | 44 virtual ~MockPluginProcessHostClient() { |
46 if (channel_) | 45 if (channel_) |
47 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_); | 46 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_); |
48 } | 47 } |
49 | 48 |
50 // PluginProcessHost::Client implementation. | 49 // PluginProcessHost::Client implementation. |
51 virtual int ID() OVERRIDE { return 42; } | 50 virtual int ID() OVERRIDE { return 42; } |
52 virtual bool OffTheRecord() OVERRIDE { return false; } | 51 virtual bool OffTheRecord() OVERRIDE { return false; } |
53 virtual content::ResourceContext* GetResourceContext() OVERRIDE { | 52 virtual ResourceContext* GetResourceContext() OVERRIDE { |
54 return context_; | 53 return context_; |
55 } | 54 } |
56 virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE {} | 55 virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE {} |
57 virtual void OnSentPluginChannelRequest() OVERRIDE {} | 56 virtual void OnSentPluginChannelRequest() OVERRIDE {} |
58 | 57 |
59 virtual void OnChannelOpened(const IPC::ChannelHandle& handle) OVERRIDE { | 58 virtual void OnChannelOpened(const IPC::ChannelHandle& handle) OVERRIDE { |
60 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 59 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
61 ASSERT_TRUE(set_plugin_info_called_); | 60 ASSERT_TRUE(set_plugin_info_called_); |
62 ASSERT_TRUE(!channel_); | 61 ASSERT_TRUE(!channel_); |
63 channel_ = new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this); | 62 channel_ = new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 void Fail() { | 97 void Fail() { |
99 FAIL(); | 98 FAIL(); |
100 QuitMessageLoop(); | 99 QuitMessageLoop(); |
101 } | 100 } |
102 | 101 |
103 void QuitMessageLoop() { | 102 void QuitMessageLoop() { |
104 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 103 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
105 MessageLoop::QuitClosure()); | 104 MessageLoop::QuitClosure()); |
106 } | 105 } |
107 | 106 |
108 content::ResourceContext* context_; | 107 ResourceContext* context_; |
109 IPC::Channel* channel_; | 108 IPC::Channel* channel_; |
110 bool set_plugin_info_called_; | 109 bool set_plugin_info_called_; |
111 DISALLOW_COPY_AND_ASSIGN(MockPluginProcessHostClient); | 110 DISALLOW_COPY_AND_ASSIGN(MockPluginProcessHostClient); |
112 }; | 111 }; |
113 | 112 |
114 class PluginServiceTest : public InProcessBrowserTest { | 113 class PluginServiceTest : public ContentBrowserTest { |
115 public: | 114 public: |
116 PluginServiceTest() : InProcessBrowserTest() { } | 115 PluginServiceTest() {} |
| 116 |
| 117 ResourceContext* GetResourceContext() { |
| 118 return shell()->web_contents()->GetBrowserContext()->GetResourceContext(); |
| 119 } |
117 | 120 |
118 virtual void SetUpCommandLine(CommandLine* command_line) { | 121 virtual void SetUpCommandLine(CommandLine* command_line) { |
119 #ifdef OS_MACOSX | 122 #ifdef OS_MACOSX |
120 FilePath browser_directory; | 123 FilePath browser_directory; |
121 PathService::Get(base::DIR_MODULE, &browser_directory); | 124 PathService::Get(base::DIR_MODULE, &browser_directory); |
122 command_line->AppendSwitchPath(switches::kExtraPluginDir, | 125 command_line->AppendSwitchPath(switches::kExtraPluginDir, |
123 browser_directory.AppendASCII("plugins")); | 126 browser_directory.AppendASCII("plugins")); |
124 #endif | 127 #endif |
125 // TODO(jam): since these plugin tests are running under Chrome, we need to | 128 // TODO(jam): since these plugin tests are running under Chrome, we need to |
126 // tell it to disable its security features for old plugins. Once this is | 129 // tell it to disable its security features for old plugins. Once this is |
127 // running under content_browsertests, these flags won't be needed. | 130 // running under content_browsertests, these flags won't be needed. |
128 // http://crbug.com/90448 | 131 // http://crbug.com/90448 |
129 // switches::kAlwaysAuthorizePlugins | 132 // switches::kAlwaysAuthorizePlugins |
130 command_line->AppendSwitch("always-authorize-plugins"); | 133 command_line->AppendSwitch("always-authorize-plugins"); |
131 } | 134 } |
132 }; | 135 }; |
133 | 136 |
134 // Try to open a channel to the test plugin. Minimal plugin process spawning | 137 // Try to open a channel to the test plugin. Minimal plugin process spawning |
135 // test for the PluginService interface. | 138 // test for the PluginService interface. |
136 IN_PROC_BROWSER_TEST_F(PluginServiceTest, OpenChannelToPlugin) { | 139 IN_PROC_BROWSER_TEST_F(PluginServiceTest, OpenChannelToPlugin) { |
137 MockPluginProcessHostClient mock_client( | 140 MockPluginProcessHostClient mock_client(GetResourceContext()); |
138 browser()->profile()->GetResourceContext()); | |
139 BrowserThread::PostTask( | 141 BrowserThread::PostTask( |
140 BrowserThread::IO, FROM_HERE, | 142 BrowserThread::IO, FROM_HERE, |
141 base::Bind(&OpenChannel, &mock_client)); | 143 base::Bind(&OpenChannel, &mock_client)); |
142 content::RunMessageLoop(); | 144 RunMessageLoop(); |
143 } | 145 } |
144 | 146 |
145 // A strict mock that fails if any of the methods are called. They shouldn't be | 147 // A strict mock that fails if any of the methods are called. They shouldn't be |
146 // called since the request should get canceled before then. | 148 // called since the request should get canceled before then. |
147 class MockCanceledPluginServiceClient : public PluginProcessHost::Client { | 149 class MockCanceledPluginServiceClient : public PluginProcessHost::Client { |
148 public: | 150 public: |
149 MockCanceledPluginServiceClient(content::ResourceContext* context) | 151 MockCanceledPluginServiceClient(ResourceContext* context) |
150 : context_(context), | 152 : context_(context), |
151 get_resource_context_called_(false) { | 153 get_resource_context_called_(false) { |
152 } | 154 } |
153 | 155 |
154 virtual ~MockCanceledPluginServiceClient() {} | 156 virtual ~MockCanceledPluginServiceClient() {} |
155 | 157 |
156 // Client implementation. | 158 // Client implementation. |
157 MOCK_METHOD0(ID, int()); | 159 MOCK_METHOD0(ID, int()); |
158 virtual content::ResourceContext* GetResourceContext() OVERRIDE { | 160 virtual ResourceContext* GetResourceContext() OVERRIDE { |
159 get_resource_context_called_ = true; | 161 get_resource_context_called_ = true; |
160 return context_; | 162 return context_; |
161 } | 163 } |
162 MOCK_METHOD0(OffTheRecord, bool()); | 164 MOCK_METHOD0(OffTheRecord, bool()); |
163 MOCK_METHOD1(OnFoundPluginProcessHost, void(PluginProcessHost* host)); | 165 MOCK_METHOD1(OnFoundPluginProcessHost, void(PluginProcessHost* host)); |
164 MOCK_METHOD0(OnSentPluginChannelRequest, void()); | 166 MOCK_METHOD0(OnSentPluginChannelRequest, void()); |
165 MOCK_METHOD1(OnChannelOpened, void(const IPC::ChannelHandle& handle)); | 167 MOCK_METHOD1(OnChannelOpened, void(const IPC::ChannelHandle& handle)); |
166 MOCK_METHOD1(SetPluginInfo, void(const webkit::WebPluginInfo& info)); | 168 MOCK_METHOD1(SetPluginInfo, void(const webkit::WebPluginInfo& info)); |
167 MOCK_METHOD0(OnError, void()); | 169 MOCK_METHOD0(OnError, void()); |
168 | 170 |
169 bool get_resource_context_called() const { | 171 bool get_resource_context_called() const { |
170 return get_resource_context_called_; | 172 return get_resource_context_called_; |
171 } | 173 } |
172 | 174 |
173 private: | 175 private: |
174 content::ResourceContext* context_; | 176 ResourceContext* context_; |
175 bool get_resource_context_called_; | 177 bool get_resource_context_called_; |
176 | 178 |
177 DISALLOW_COPY_AND_ASSIGN(MockCanceledPluginServiceClient); | 179 DISALLOW_COPY_AND_ASSIGN(MockCanceledPluginServiceClient); |
178 }; | 180 }; |
179 | 181 |
180 void QuitUIMessageLoopFromIOThread() { | 182 void QuitUIMessageLoopFromIOThread() { |
181 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 183 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
182 MessageLoop::QuitClosure()); | 184 MessageLoop::QuitClosure()); |
183 } | 185 } |
184 | 186 |
185 void OpenChannelAndThenCancel(PluginProcessHost::Client* client) { | 187 void OpenChannelAndThenCancel(PluginProcessHost::Client* client) { |
186 OpenChannel(client); | 188 OpenChannel(client); |
187 // Immediately cancel it. This is guaranteed to work since PluginService needs | 189 // Immediately cancel it. This is guaranteed to work since PluginService needs |
188 // to consult its filter on the FILE thread. | 190 // to consult its filter on the FILE thread. |
189 PluginServiceImpl::GetInstance()->CancelOpenChannelToNpapiPlugin(client); | 191 PluginServiceImpl::GetInstance()->CancelOpenChannelToNpapiPlugin(client); |
190 // Before we terminate the test, add a roundtrip through the FILE thread to | 192 // Before we terminate the test, add a roundtrip through the FILE thread to |
191 // make sure that it's had a chance to post back to the IO thread. Then signal | 193 // make sure that it's had a chance to post back to the IO thread. Then signal |
192 // the UI thread to stop and exit the test. | 194 // the UI thread to stop and exit the test. |
193 BrowserThread::PostTaskAndReply( | 195 BrowserThread::PostTaskAndReply( |
194 BrowserThread::FILE, FROM_HERE, | 196 BrowserThread::FILE, FROM_HERE, |
195 base::Bind(&base::DoNothing), | 197 base::Bind(&base::DoNothing), |
196 base::Bind(&QuitUIMessageLoopFromIOThread)); | 198 base::Bind(&QuitUIMessageLoopFromIOThread)); |
197 } | 199 } |
198 | 200 |
199 // Should not attempt to open a channel, since it should be canceled early on. | 201 // Should not attempt to open a channel, since it should be canceled early on. |
200 IN_PROC_BROWSER_TEST_F(PluginServiceTest, CancelOpenChannelToPluginService) { | 202 IN_PROC_BROWSER_TEST_F(PluginServiceTest, CancelOpenChannelToPluginService) { |
201 ::testing::StrictMock<MockCanceledPluginServiceClient> mock_client( | 203 ::testing::StrictMock<MockCanceledPluginServiceClient> mock_client( |
202 browser()->profile()->GetResourceContext()); | 204 GetResourceContext()); |
203 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 205 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
204 base::Bind(OpenChannelAndThenCancel, &mock_client)); | 206 base::Bind(OpenChannelAndThenCancel, &mock_client)); |
205 content::RunMessageLoop(); | 207 RunMessageLoop(); |
206 EXPECT_TRUE(mock_client.get_resource_context_called()); | 208 EXPECT_TRUE(mock_client.get_resource_context_called()); |
207 } | 209 } |
208 | 210 |
209 class MockCanceledBeforeSentPluginProcessHostClient | 211 class MockCanceledBeforeSentPluginProcessHostClient |
210 : public MockCanceledPluginServiceClient { | 212 : public MockCanceledPluginServiceClient { |
211 public: | 213 public: |
212 MockCanceledBeforeSentPluginProcessHostClient( | 214 MockCanceledBeforeSentPluginProcessHostClient( |
213 content::ResourceContext* context) | 215 ResourceContext* context) |
214 : MockCanceledPluginServiceClient(context), | 216 : MockCanceledPluginServiceClient(context), |
215 set_plugin_info_called_(false), | 217 set_plugin_info_called_(false), |
216 on_found_plugin_process_host_called_(false), | 218 on_found_plugin_process_host_called_(false), |
217 host_(NULL) {} | 219 host_(NULL) {} |
218 | 220 |
219 virtual ~MockCanceledBeforeSentPluginProcessHostClient() {} | 221 virtual ~MockCanceledBeforeSentPluginProcessHostClient() {} |
220 | 222 |
221 // Client implementation. | 223 // Client implementation. |
222 virtual void SetPluginInfo(const webkit::WebPluginInfo& info) OVERRIDE { | 224 virtual void SetPluginInfo(const webkit::WebPluginInfo& info) OVERRIDE { |
223 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 bool set_plugin_info_called_; | 264 bool set_plugin_info_called_; |
263 bool on_found_plugin_process_host_called_; | 265 bool on_found_plugin_process_host_called_; |
264 PluginProcessHost* host_; | 266 PluginProcessHost* host_; |
265 | 267 |
266 DISALLOW_COPY_AND_ASSIGN(MockCanceledBeforeSentPluginProcessHostClient); | 268 DISALLOW_COPY_AND_ASSIGN(MockCanceledBeforeSentPluginProcessHostClient); |
267 }; | 269 }; |
268 | 270 |
269 IN_PROC_BROWSER_TEST_F( | 271 IN_PROC_BROWSER_TEST_F( |
270 PluginServiceTest, CancelBeforeSentOpenChannelToPluginProcessHost) { | 272 PluginServiceTest, CancelBeforeSentOpenChannelToPluginProcessHost) { |
271 ::testing::StrictMock<MockCanceledBeforeSentPluginProcessHostClient> | 273 ::testing::StrictMock<MockCanceledBeforeSentPluginProcessHostClient> |
272 mock_client(browser()->profile()->GetResourceContext()); | 274 mock_client(GetResourceContext()); |
273 BrowserThread::PostTask( | 275 BrowserThread::PostTask( |
274 BrowserThread::IO, FROM_HERE, | 276 BrowserThread::IO, FROM_HERE, |
275 base::Bind(&OpenChannel, &mock_client)); | 277 base::Bind(&OpenChannel, &mock_client)); |
276 content::RunMessageLoop(); | 278 RunMessageLoop(); |
277 EXPECT_TRUE(mock_client.get_resource_context_called()); | 279 EXPECT_TRUE(mock_client.get_resource_context_called()); |
278 EXPECT_TRUE(mock_client.set_plugin_info_called()); | 280 EXPECT_TRUE(mock_client.set_plugin_info_called()); |
279 EXPECT_TRUE(mock_client.on_found_plugin_process_host_called()); | 281 EXPECT_TRUE(mock_client.on_found_plugin_process_host_called()); |
280 } | 282 } |
281 | 283 |
282 class MockCanceledAfterSentPluginProcessHostClient | 284 class MockCanceledAfterSentPluginProcessHostClient |
283 : public MockCanceledBeforeSentPluginProcessHostClient { | 285 : public MockCanceledBeforeSentPluginProcessHostClient { |
284 public: | 286 public: |
285 MockCanceledAfterSentPluginProcessHostClient( | 287 MockCanceledAfterSentPluginProcessHostClient( |
286 content::ResourceContext* context) | 288 ResourceContext* context) |
287 : MockCanceledBeforeSentPluginProcessHostClient(context), | 289 : MockCanceledBeforeSentPluginProcessHostClient(context), |
288 on_sent_plugin_channel_request_called_(false) {} | 290 on_sent_plugin_channel_request_called_(false) {} |
289 virtual ~MockCanceledAfterSentPluginProcessHostClient() {} | 291 virtual ~MockCanceledAfterSentPluginProcessHostClient() {} |
290 | 292 |
291 // Client implementation. | 293 // Client implementation. |
292 | 294 |
293 virtual int ID() OVERRIDE { return 42; } | 295 virtual int ID() OVERRIDE { return 42; } |
294 virtual bool OffTheRecord() OVERRIDE { return false; } | 296 virtual bool OffTheRecord() OVERRIDE { return false; } |
295 | 297 |
296 // We override this guy again since we don't want to cancel yet. | 298 // We override this guy again since we don't want to cancel yet. |
(...skipping 17 matching lines...) Expand all Loading... |
314 private: | 316 private: |
315 bool on_sent_plugin_channel_request_called_; | 317 bool on_sent_plugin_channel_request_called_; |
316 | 318 |
317 DISALLOW_COPY_AND_ASSIGN(MockCanceledAfterSentPluginProcessHostClient); | 319 DISALLOW_COPY_AND_ASSIGN(MockCanceledAfterSentPluginProcessHostClient); |
318 }; | 320 }; |
319 | 321 |
320 // Should not attempt to open a channel, since it should be canceled early on. | 322 // Should not attempt to open a channel, since it should be canceled early on. |
321 IN_PROC_BROWSER_TEST_F( | 323 IN_PROC_BROWSER_TEST_F( |
322 PluginServiceTest, CancelAfterSentOpenChannelToPluginProcessHost) { | 324 PluginServiceTest, CancelAfterSentOpenChannelToPluginProcessHost) { |
323 ::testing::StrictMock<MockCanceledAfterSentPluginProcessHostClient> | 325 ::testing::StrictMock<MockCanceledAfterSentPluginProcessHostClient> |
324 mock_client(browser()->profile()->GetResourceContext()); | 326 mock_client(GetResourceContext()); |
325 BrowserThread::PostTask( | 327 BrowserThread::PostTask( |
326 BrowserThread::IO, FROM_HERE, | 328 BrowserThread::IO, FROM_HERE, |
327 base::Bind(&OpenChannel, &mock_client)); | 329 base::Bind(&OpenChannel, &mock_client)); |
328 content::RunMessageLoop(); | 330 RunMessageLoop(); |
329 EXPECT_TRUE(mock_client.get_resource_context_called()); | 331 EXPECT_TRUE(mock_client.get_resource_context_called()); |
330 EXPECT_TRUE(mock_client.set_plugin_info_called()); | 332 EXPECT_TRUE(mock_client.set_plugin_info_called()); |
331 EXPECT_TRUE(mock_client.on_found_plugin_process_host_called()); | 333 EXPECT_TRUE(mock_client.on_found_plugin_process_host_called()); |
332 EXPECT_TRUE(mock_client.on_sent_plugin_channel_request_called()); | 334 EXPECT_TRUE(mock_client.on_sent_plugin_channel_request_called()); |
333 } | 335 } |
334 | 336 |
335 } // namespace | 337 } // namespace content |
OLD | NEW |