| Index: chrome/browser/apps/guest_view/app_view_browsertest.cc | 
| diff --git a/chrome/browser/apps/guest_view/app_view_browsertest.cc b/chrome/browser/apps/guest_view/app_view_browsertest.cc | 
| index 0278507d3b520be64442f238bf2ee3cfe3dab465..34cd72def7ea8b14183e477d96a5b6c4957ed539 100644 | 
| --- a/chrome/browser/apps/guest_view/app_view_browsertest.cc | 
| +++ b/chrome/browser/apps/guest_view/app_view_browsertest.cc | 
| @@ -9,8 +9,13 @@ | 
| #include "components/guest_view/browser/test_guest_view_manager.h" | 
| #include "content/public/browser/notification_service.h" | 
| #include "content/public/browser/render_process_host.h" | 
| +#include "content/public/browser/render_process_host_observer.h" | 
| #include "content/public/test/browser_test_utils.h" | 
| #include "content/public/test/test_utils.h" | 
| +#include "extensions/browser/app_window/app_window_registry.h" | 
| +#include "extensions/browser/guest_view/app_view/app_view_guest.h" | 
| +#include "extensions/browser/guest_view/extensions_guest_view_manager_delegate.h" | 
| +#include "extensions/browser/process_manager.h" | 
| #include "extensions/common/switches.h" | 
| #include "extensions/test/extension_test_message_listener.h" | 
| #include "net/test/embedded_test_server/embedded_test_server.h" | 
| @@ -20,6 +25,49 @@ | 
| using guest_view::GuestViewManager; | 
| using guest_view::TestGuestViewManagerFactory; | 
|  | 
| +namespace { | 
| + | 
| +class RenderProcessHostObserverForExit | 
| +    : public content::RenderProcessHostObserver { | 
| + public: | 
| +  explicit RenderProcessHostObserverForExit( | 
| +      content::RenderProcessHost* observed_host) | 
| +      : render_process_host_exited_(false), observed_host_(observed_host) { | 
| +    observed_host->AddObserver(this); | 
| +  } | 
| + | 
| +  void WaitUntilRenderProcessHostKilled() { | 
| +    if (render_process_host_exited_) | 
| +      return; | 
| +    message_loop_runner_ = new content::MessageLoopRunner; | 
| +    message_loop_runner_->Run(); | 
| +  } | 
| + | 
| +  base::TerminationStatus termination_status() const { return status_; } | 
| + | 
| + private: | 
| +  void RenderProcessExited(content::RenderProcessHost* host, | 
| +                           base::TerminationStatus status, | 
| +                           int exit_code) override { | 
| +    DCHECK(observed_host_ == host); | 
| +    render_process_host_exited_ = true; | 
| +    status_ = status; | 
| +    observed_host_->RemoveObserver(this); | 
| +    if (message_loop_runner_.get()) { | 
| +      message_loop_runner_->Quit(); | 
| +    } | 
| +  } | 
| + | 
| +  bool render_process_host_exited_; | 
| +  content::RenderProcessHost* observed_host_; | 
| +  scoped_refptr<content::MessageLoopRunner> message_loop_runner_; | 
| +  base::TerminationStatus status_; | 
| + | 
| +  DISALLOW_COPY_AND_ASSIGN(RenderProcessHostObserverForExit); | 
| +}; | 
| + | 
| +}  // namespace | 
| + | 
| class AppViewTest : public extensions::PlatformAppBrowserTest { | 
| public: | 
| AppViewTest() { | 
| @@ -59,8 +107,7 @@ class AppViewTest : public extensions::PlatformAppBrowserTest { | 
| done_listener.set_failure_message("TEST_FAILED"); | 
| if (!content::ExecuteScript( | 
| embedder_web_contents, | 
| -            base::StringPrintf("runTest('%s', '%s')", | 
| -                               test_name.c_str(), | 
| +            base::StringPrintf("runTest('%s', '%s')", test_name.c_str(), | 
| app_to_embed.c_str()))) { | 
| LOG(ERROR) << "UNABLE TO START TEST."; | 
| return; | 
| @@ -68,12 +115,29 @@ class AppViewTest : public extensions::PlatformAppBrowserTest { | 
| ASSERT_TRUE(done_listener.WaitUntilSatisfied()); | 
| } | 
|  | 
| +  guest_view::TestGuestViewManager* test_guest_view_manager() const { | 
| +    return test_guest_view_manager_; | 
| +  } | 
| + | 
| private: | 
| void SetUpCommandLine(base::CommandLine* command_line) override { | 
| extensions::PlatformAppBrowserTest::SetUpCommandLine(command_line); | 
| } | 
|  | 
| +  void SetUpOnMainThread() override { | 
| +    extensions::PlatformAppBrowserTest::SetUpOnMainThread(); | 
| +    test_guest_view_manager_ = static_cast<guest_view::TestGuestViewManager*>( | 
| +        guest_view::GuestViewManager::CreateWithDelegate( | 
| +            browser()->profile(), | 
| +            scoped_ptr<guest_view::GuestViewManagerDelegate>( | 
| +                new extensions::ExtensionsGuestViewManagerDelegate( | 
| +                    browser()->profile())))); | 
| +  } | 
| + | 
| TestGuestViewManagerFactory factory_; | 
| +  guest_view::TestGuestViewManager* test_guest_view_manager_; | 
| + | 
| +  DISALLOW_COPY_AND_ASSIGN(AppViewTest); | 
| }; | 
|  | 
| // Tests that <appview> is able to navigate to another installed app. | 
| @@ -125,3 +189,63 @@ IN_PROC_BROWSER_TEST_F(AppViewTest, TestAppViewEmbedSelfShouldFail) { | 
| skeleton_app->id(), | 
| NO_TEST_SERVER); | 
| } | 
| + | 
| +IN_PROC_BROWSER_TEST_F(AppViewTest, KillGuestWithInvalidInstanceID) { | 
| +  const extensions::Extension* mock_bad_app = | 
| +      LoadAndLaunchPlatformApp("app_view/bad_app", "AppViewTest.LAUNCHED"); | 
| + | 
| +  content::RenderProcessHost* bad_app_render_process_host = | 
| +      extensions::AppWindowRegistry::Get(browser()->profile()) | 
| +          ->GetCurrentAppWindowForApp(mock_bad_app->id()) | 
| +          ->web_contents() | 
| +          ->GetRenderProcessHost(); | 
| + | 
| +  // Monitor |mock_bad_app|'s RenderProcessHost for its exiting. | 
| +  RenderProcessHostObserverForExit exit_observer(bad_app_render_process_host); | 
| + | 
| +  // Choosing a |guest_instance_id| which does not exist. | 
| +  int invalid_guest_instance_id = | 
| +      test_guest_view_manager()->GetNextInstanceID(); | 
| +  // Call the desired function to verify that the |mock_bad_app| gets killed if | 
| +  // the provided |guest_instance_id| is not mapped to any "GuestView"'s. | 
| +  extensions::AppViewGuest::CompletePendingRequest( | 
| +      browser()->profile(), GURL("about:blank"), invalid_guest_instance_id, | 
| +      mock_bad_app->id(), bad_app_render_process_host); | 
| +  exit_observer.WaitUntilRenderProcessHostKilled(); | 
| +} | 
| + | 
| +IN_PROC_BROWSER_TEST_F(AppViewTest, KillGuestCommunicatingWithWrongAppView) { | 
| +  const extensions::Extension* host_app = | 
| +      LoadAndLaunchPlatformApp("app_view/host_app", "AppViewTest.LAUNCHED"); | 
| +  const extensions::Extension* mock_guest_extension = | 
| +      InstallPlatformApp("app_view/guest_app"); | 
| +  const extensions::Extension* mock_bad_app = | 
| +      LoadAndLaunchPlatformApp("app_view/bad_app", "AppViewTest.LAUNCHED"); | 
| + | 
| +  EXPECT_TRUE(content::ExecuteScript( | 
| +      extensions::AppWindowRegistry::Get(browser()->profile()) | 
| +          ->GetCurrentAppWindowForApp(host_app->id()) | 
| +          ->web_contents(), | 
| +      base::StringPrintf("onAppCommand('%s', '%s');", "EMBED", | 
| +                         mock_guest_extension->id().c_str()))); | 
| +  ExtensionTestMessageListener on_embed_requested_listener( | 
| +      "AppViewTest.EmbedRequested", true); | 
| +  EXPECT_TRUE(on_embed_requested_listener.WaitUntilSatisfied()); | 
| +  // Now assume the bad application is somehow sending a message to complete a | 
| +  // pending request to attach to <appview>. It should be killed. | 
| +  content::RenderProcessHost* bad_app_render_process_host = | 
| +      extensions::ProcessManager::Get(browser()->profile()) | 
| +          ->GetBackgroundHostForExtension(mock_bad_app->id()) | 
| +          ->render_process_host(); | 
| +  RenderProcessHostObserverForExit bad_app_obs(bad_app_render_process_host); | 
| +  // Make the false request. | 
| +  int guest_instance_id = | 
| +      extensions::AppViewGuest::GetAllRegisteredInstanceIdsForTesting()[0]; | 
| +  extensions::AppViewGuest::CompletePendingRequest( | 
| +      browser()->profile(), GURL("about:blank"), guest_instance_id, | 
| +      mock_bad_app->id(), bad_app_render_process_host); | 
| + | 
| +  on_embed_requested_listener.Reply("continue"); | 
| +  // Make sure the bad application has been terminated. | 
| +  bad_app_obs.WaitUntilRenderProcessHostKilled(); | 
| +} | 
|  |