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 | |
5 #include "base/strings/stringprintf.h" | 4 #include "base/strings/stringprintf.h" |
6 #include "chrome/browser/apps/app_browsertest_util.h" | 5 #include "chrome/browser/apps/app_browsertest_util.h" |
7 #include "components/guest_view/browser/guest_view_manager.h" | 6 #include "components/guest_view/browser/guest_view_manager.h" |
8 #include "components/guest_view/browser/guest_view_manager_factory.h" | 7 #include "components/guest_view/browser/guest_view_manager_factory.h" |
9 #include "components/guest_view/browser/test_guest_view_manager.h" | 8 #include "components/guest_view/browser/test_guest_view_manager.h" |
9 #include "content/public/browser/notification_observer.h" | |
10 #include "content/public/browser/notification_service.h" | 10 #include "content/public/browser/notification_service.h" |
11 #include "content/public/browser/render_process_host.h" | 11 #include "content/public/browser/render_process_host.h" |
12 #include "content/public/browser/render_process_host_observer.h" | |
12 #include "content/public/test/browser_test_utils.h" | 13 #include "content/public/test/browser_test_utils.h" |
13 #include "content/public/test/test_utils.h" | 14 #include "content/public/test/test_utils.h" |
15 #include "extensions/browser/app_window/app_window_registry.h" | |
16 #include "extensions/browser/guest_view/app_view/app_view_guest.h" | |
17 #include "extensions/browser/guest_view/extensions_guest_view_manager_delegate.h " | |
18 #include "extensions/browser/process_manager.h" | |
14 #include "extensions/common/switches.h" | 19 #include "extensions/common/switches.h" |
15 #include "extensions/test/extension_test_message_listener.h" | 20 #include "extensions/test/extension_test_message_listener.h" |
16 #include "net/test/embedded_test_server/embedded_test_server.h" | 21 #include "net/test/embedded_test_server/embedded_test_server.h" |
17 #include "net/test/embedded_test_server/http_request.h" | 22 #include "net/test/embedded_test_server/http_request.h" |
18 #include "net/test/embedded_test_server/http_response.h" | 23 #include "net/test/embedded_test_server/http_response.h" |
19 | 24 |
20 using guest_view::GuestViewManager; | 25 using guest_view::GuestViewManager; |
21 using guest_view::TestGuestViewManagerFactory; | 26 using guest_view::TestGuestViewManagerFactory; |
22 | 27 |
28 namespace { | |
29 | |
30 class RenderProcessHostObserverForExit | |
31 : public content::RenderProcessHostObserver { | |
32 public: | |
33 explicit RenderProcessHostObserverForExit( | |
34 content::RenderProcessHost* observed_host) | |
35 : render_process_host_exited_(false), | |
36 observed_host_(observed_host), | |
37 message_loop_runner_(nullptr) { | |
38 observed_host->AddObserver(this); | |
39 LOG(INFO) << "Listening for RPH Exit (ID = " << observed_host->GetID() | |
40 << ")"; | |
41 } | |
42 | |
43 void WaitUntilRenderProcessHostKilled() { | |
44 if (render_process_host_exited_) | |
45 return; | |
46 message_loop_runner_ = new content::MessageLoopRunner; | |
47 message_loop_runner_->Run(); | |
48 } | |
49 | |
50 base::TerminationStatus termination_status() { return status_; } | |
51 | |
52 private: | |
53 void RenderProcessExited(content::RenderProcessHost* host, | |
54 base::TerminationStatus status, | |
55 int exit_code) override { | |
56 LOG(INFO) << "RPH is exiting. (ID = " << host->GetID() << ")."; | |
57 DCHECK(observed_host_ == host); | |
58 render_process_host_exited_ = true; | |
59 status_ = status; | |
60 observed_host_->RemoveObserver(this); | |
61 if (message_loop_runner_.get()) { | |
62 message_loop_runner_->Quit(); | |
63 } | |
64 } | |
65 | |
66 bool render_process_host_exited_; | |
67 content::RenderProcessHost* observed_host_; | |
68 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; | |
69 base::TerminationStatus status_; | |
70 }; | |
71 | |
72 } // namespace | |
73 | |
23 class AppViewTest : public extensions::PlatformAppBrowserTest { | 74 class AppViewTest : public extensions::PlatformAppBrowserTest { |
24 public: | 75 public: |
25 AppViewTest() { | 76 AppViewTest() { |
26 GuestViewManager::set_factory_for_testing(&factory_); | 77 GuestViewManager::set_factory_for_testing(&factory_); |
27 } | 78 } |
28 | 79 |
29 enum TestServer { | 80 enum TestServer { |
30 NEEDS_TEST_SERVER, | 81 NEEDS_TEST_SERVER, |
31 NO_TEST_SERVER | 82 NO_TEST_SERVER |
32 }; | 83 }; |
(...skipping 19 matching lines...) Expand all Loading... | |
52 GetFirstAppWindowWebContents(); | 103 GetFirstAppWindowWebContents(); |
53 if (!embedder_web_contents) { | 104 if (!embedder_web_contents) { |
54 LOG(ERROR) << "UNABLE TO FIND EMBEDDER WEB CONTENTS."; | 105 LOG(ERROR) << "UNABLE TO FIND EMBEDDER WEB CONTENTS."; |
55 return; | 106 return; |
56 } | 107 } |
57 | 108 |
58 ExtensionTestMessageListener done_listener("TEST_PASSED", false); | 109 ExtensionTestMessageListener done_listener("TEST_PASSED", false); |
59 done_listener.set_failure_message("TEST_FAILED"); | 110 done_listener.set_failure_message("TEST_FAILED"); |
60 if (!content::ExecuteScript( | 111 if (!content::ExecuteScript( |
61 embedder_web_contents, | 112 embedder_web_contents, |
62 base::StringPrintf("runTest('%s', '%s')", | 113 base::StringPrintf("runTest('%s', '%s')", test_name.c_str(), |
63 test_name.c_str(), | |
64 app_to_embed.c_str()))) { | 114 app_to_embed.c_str()))) { |
65 LOG(ERROR) << "UNABLE TO START TEST."; | 115 LOG(ERROR) << "UNABLE TO START TEST."; |
66 return; | 116 return; |
67 } | 117 } |
68 ASSERT_TRUE(done_listener.WaitUntilSatisfied()); | 118 ASSERT_TRUE(done_listener.WaitUntilSatisfied()); |
69 } | 119 } |
70 | 120 |
121 guest_view::TestGuestViewManager* GetGuestViewManager() { | |
122 guest_view::TestGuestViewManager* manager = | |
123 static_cast<guest_view::TestGuestViewManager*>( | |
124 guest_view::TestGuestViewManager::FromBrowserContext( | |
125 browser()->profile())); | |
126 if (!manager) { | |
127 manager = static_cast<guest_view::TestGuestViewManager*>( | |
128 GuestViewManager::CreateWithDelegate( | |
129 browser()->profile(), | |
130 scoped_ptr<guest_view::GuestViewManagerDelegate>( | |
131 new extensions::ExtensionsGuestViewManagerDelegate( | |
132 browser()->profile())))); | |
133 } | |
134 return manager; | |
135 } | |
136 | |
71 private: | 137 private: |
72 void SetUpCommandLine(base::CommandLine* command_line) override { | 138 void SetUpCommandLine(base::CommandLine* command_line) override { |
73 extensions::PlatformAppBrowserTest::SetUpCommandLine(command_line); | 139 extensions::PlatformAppBrowserTest::SetUpCommandLine(command_line); |
74 } | 140 } |
75 | 141 |
76 TestGuestViewManagerFactory factory_; | 142 TestGuestViewManagerFactory factory_; |
77 }; | 143 }; |
78 | 144 |
79 // Tests that <appview> is able to navigate to another installed app. | 145 // Tests that <appview> is able to navigate to another installed app. |
80 IN_PROC_BROWSER_TEST_F(AppViewTest, TestAppViewWithUndefinedDataShouldSucceed) { | 146 IN_PROC_BROWSER_TEST_F(AppViewTest, TestAppViewWithUndefinedDataShouldSucceed) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
118 | 184 |
119 // Tests that <appview> does not embed self (the app which owns appview). | 185 // Tests that <appview> does not embed self (the app which owns appview). |
120 IN_PROC_BROWSER_TEST_F(AppViewTest, TestAppViewEmbedSelfShouldFail) { | 186 IN_PROC_BROWSER_TEST_F(AppViewTest, TestAppViewEmbedSelfShouldFail) { |
121 const extensions::Extension* skeleton_app = | 187 const extensions::Extension* skeleton_app = |
122 InstallPlatformApp("app_view/shim/skeleton"); | 188 InstallPlatformApp("app_view/shim/skeleton"); |
123 TestHelper("testAppViewEmbedSelfShouldFail", | 189 TestHelper("testAppViewEmbedSelfShouldFail", |
124 "app_view/shim", | 190 "app_view/shim", |
125 skeleton_app->id(), | 191 skeleton_app->id(), |
126 NO_TEST_SERVER); | 192 NO_TEST_SERVER); |
127 } | 193 } |
194 | |
195 IN_PROC_BROWSER_TEST_F(AppViewTest, TestKillGuestWithInvalidInstanceID) { | |
196 const extensions::Extension* mock_bad_app = | |
197 LoadAndLaunchPlatformApp("app_view/bad_app", "AppViewTest.LAUNCHED"); | |
198 | |
199 content::RenderProcessHost* bad_app_render_process_host = | |
200 extensions::AppWindowRegistry::Get(browser()->profile()) | |
201 ->GetCurrentAppWindowForApp(mock_bad_app->id()) | |
202 ->web_contents() | |
203 ->GetRenderProcessHost(); | |
204 | |
205 // Monitor |mock_bad_app|'s "RenderProcessHost" for its exiting. | |
206 RenderProcessHostObserverForExit exit_observer(bad_app_render_process_host); | |
207 | |
208 // Get/Create the instance of "GuestViewManager". | |
209 guest_view::GuestViewManager* guest_view_manager = GetGuestViewManager(); | |
210 EXPECT_TRUE(guest_view_manager != nullptr); | |
211 | |
212 // Choosing a |guest_instance_id| which does not exist. | |
213 int invalid_guest_instance_id = guest_view_manager->GetNextInstanceID(); | |
214 LOG(INFO) << "Guest instance ID: " << invalid_guest_instance_id; | |
215 | |
216 // Call the desired function to verify that the |mock_bad_app| gets killed if | |
217 // the provided |guest_instance_id| is not mapped to any "GuestView"'s. | |
218 extensions::AppViewGuest::CompletePendingRequest( | |
219 browser()->profile(), GURL("about:blank"), invalid_guest_instance_id, | |
220 mock_bad_app->id(), bad_app_render_process_host->GetID()); | |
221 exit_observer.WaitUntilRenderProcessHostKilled(); | |
222 EXPECT_EQ(exit_observer.termination_status(), | |
223 base::TERMINATION_STATUS_PROCESS_WAS_KILLED); | |
224 } | |
225 | |
226 IN_PROC_BROWSER_TEST_F(AppViewTest, | |
227 TestKillGuestCommunicatingWithWrongAppView) { | |
228 const extensions::Extension* host_app = | |
229 LoadAndLaunchPlatformApp("app_view/host_app", "AppViewTest.LAUNCHED"); | |
230 const extensions::Extension* mock_guest_extension = | |
231 InstallPlatformApp("app_view/guest_app"); | |
232 const extensions::Extension* mock_bad_app = | |
233 LoadAndLaunchPlatformApp("app_view/bad_app", "AppViewTest.LAUNCHED"); | |
234 // Ask the host to create and load an <appview> | |
235 EXPECT_TRUE(content::ExecuteScript( | |
236 extensions::AppWindowRegistry::Get(browser()->profile()) | |
237 ->GetCurrentAppWindowForApp(host_app->id()) | |
238 ->web_contents(), | |
239 base::StringPrintf("onAppCommand('%s', '%s');", "EMBED", | |
240 mock_guest_extension->id().c_str()))); | |
241 // Now listen for the guest content to announce that it is being requested to | |
242 // be embedded. | |
243 ExtensionTestMessageListener on_embed_requested_listener( | |
244 "AppViewTest.EmbedRequested", true); | |
245 EXPECT_TRUE(on_embed_requested_listener.WaitUntilSatisfied()); | |
246 // Now assume the bad application is somehow sending a message to complete a | |
247 // pending request to attach to <appview>. It should be killed. | |
248 content::RenderProcessHost* bad_app_render_process_host = | |
249 extensions::ProcessManager::Get(browser()->profile()) | |
250 ->GetBackgroundHostForExtension(mock_bad_app->id()) | |
251 ->render_process_host(); | |
252 RenderProcessHostObserverForExit bad_app_obs(bad_app_render_process_host); | |
253 // Make the false request. | |
254 int guest_instance_id = | |
255 extensions::AppViewGuest::GetAllRegisteredInstanceIdsForTesting()[0]; | |
256 extensions::AppViewGuest::CompletePendingRequest( | |
257 browser()->profile(), GURL("about:blank"), guest_instance_id, | |
258 mock_bad_app->id(), bad_app_render_process_host->GetID()); | |
259 bad_app_obs.WaitUntilRenderProcessHostKilled(); | |
260 | |
261 EXPECT_EQ(bad_app_obs.termination_status(), | |
262 base::TERMINATION_STATUS_PROCESS_WAS_KILLED); | |
263 // Proceed with the rest of embedding of the guest app. | |
264 LOG(INFO) << "Forcing the 'guest_app' to finalize embedding process by" | |
265 << " executing script."; | |
266 EXPECT_TRUE(content::ExecuteScript( | |
267 extensions::ProcessManager::Get(browser()->profile()) | |
268 ->GetBackgroundHostForExtension(mock_guest_extension->id()) | |
269 ->host_contents(), | |
270 "continueEmbedding();")); | |
271 } | |
272 | |
273 IN_PROC_BROWSER_TEST_F( | |
274 AppViewTest, | |
275 TestKillGuestCommunicatingWithWrongAppViewUsingChromeSendMessageAPI) { | |
lazyboy
2015/06/29 20:05:33
Here and in other test, You should remove the pref
EhsanK
2015/06/30 16:53:10
Done.
| |
276 const extensions::Extension* host_app = | |
277 LoadAndLaunchPlatformApp("app_view/host_app", "AppViewTest.LAUNCHED"); | |
278 const extensions::Extension* mock_guest_extension = | |
279 InstallPlatformApp("app_view/guest_app"); | |
280 const extensions::Extension* mock_bad_app = | |
281 LoadAndLaunchPlatformApp("app_view/bad_app", "AppViewTest.LAUNCHED"); | |
282 // Ask the host to create and load an <appview> | |
283 EXPECT_TRUE(content::ExecuteScript( | |
284 extensions::AppWindowRegistry::Get(browser()->profile()) | |
285 ->GetCurrentAppWindowForApp(host_app->id()) | |
286 ->web_contents(), | |
287 base::StringPrintf("onAppCommand('%s', '%s');", "EMBED", | |
288 mock_guest_extension->id().c_str()))); | |
289 // Now listen for the guest content to announce that it is being requested to | |
290 // be embedded. | |
291 ExtensionTestMessageListener on_embed_requested_listener( | |
292 "AppViewTest.EmbedRequested", true); | |
293 EXPECT_TRUE(on_embed_requested_listener.WaitUntilSatisfied()); | |
294 // Now assume the bad application is somehow sending a message to complete a | |
295 // pending request to attach to <appview>. It should be killed. | |
296 content::RenderProcessHost* bad_app_render_process_host = | |
297 extensions::ProcessManager::Get(browser()->profile()) | |
298 ->GetBackgroundHostForExtension(mock_bad_app->id()) | |
299 ->render_process_host(); | |
300 RenderProcessHostObserverForExit bad_app_obs(bad_app_render_process_host); | |
301 // Make the false request. | |
302 int guest_instance_id = | |
303 extensions::AppViewGuest::GetAllRegisteredInstanceIdsForTesting()[0]; | |
304 extensions::AppViewGuest::CompletePendingRequest( | |
305 browser()->profile(), GURL("about:blank"), guest_instance_id, | |
306 mock_bad_app->id(), bad_app_render_process_host->GetID()); | |
307 bad_app_obs.WaitUntilRenderProcessHostKilled(); | |
lazyboy
2015/06/29 20:05:33
I got a chance to run this test locally.
I think t
EhsanK
2015/06/30 16:53:11
You are right. Thanks!. Done.
| |
308 | |
309 EXPECT_EQ(bad_app_obs.termination_status(), | |
310 base::TERMINATION_STATUS_PROCESS_WAS_KILLED); | |
311 // Proceed with the rest of embedding of the guest app. | |
312 LOG(INFO) << "Replying the message from 'guest_app' so that it can finalize" | |
313 << " It's embedding."; | |
314 on_embed_requested_listener.Reply("continue"); | |
315 LOG(INFO) << "Message sent!"; | |
316 } | |
OLD | NEW |