| // Copyright 2020 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ash/app_mode/kiosk_session_plugin_handler.h" |
| |
| #include "chrome/browser/ash/app_mode/kiosk_session_plugin_handler_delegate.h" |
| #include "chrome/test/base/testing_browser_process.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/test/browser_task_environment.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using content::WebContents; |
| using content::WebContentsObserver; |
| |
| namespace ash { |
| |
| namespace { |
| |
| constexpr char kValidPluginPath[] = "/path/to/valid_plugin"; |
| constexpr char kInvalidPluginPath[] = "/path/to/invalid_plugin"; |
| constexpr char kProcessId = 2; |
| constexpr int kPluginChildId = 2; |
| |
| } // namespace |
| |
| class TestKioskSessionPluginHandlerDelegate |
| : public KioskSessionPluginHandlerDelegate { |
| public: |
| TestKioskSessionPluginHandlerDelegate() = default; |
| ~TestKioskSessionPluginHandlerDelegate() override = default; |
| |
| bool ShouldHandlePlugin(const base::FilePath& plugin_path) const override { |
| return plugin_path.AsUTF8Unsafe() == kValidPluginPath; |
| } |
| |
| void OnPluginCrashed(const base::FilePath& plugin_path) override { |
| has_crashed_ = true; |
| } |
| |
| void OnPluginHung(const std::set<int>& hung_plugins) override {} |
| |
| bool has_crashed() const { return has_crashed_; } |
| |
| private: |
| bool has_crashed_ = false; |
| }; |
| |
| class KioskSessionPluginHandlerTest : public testing::Test { |
| public: |
| KioskSessionPluginHandlerTest() = default; |
| ~KioskSessionPluginHandlerTest() override = default; |
| |
| void SetUp() override { |
| delegate_ = std::make_unique<TestKioskSessionPluginHandlerDelegate>(); |
| handler_ = std::make_unique<KioskSessionPluginHandler>(delegate_.get()); |
| } |
| |
| TestKioskSessionPluginHandlerDelegate* delegate() const { |
| return delegate_.get(); |
| } |
| |
| KioskSessionPluginHandler* handler() const { return handler_.get(); } |
| |
| private: |
| content::BrowserTaskEnvironment task_environment_; |
| std::unique_ptr<TestKioskSessionPluginHandlerDelegate> delegate_; |
| std::unique_ptr<KioskSessionPluginHandler> handler_; |
| }; |
| |
| TEST_F(KioskSessionPluginHandlerTest, ObserveAndDestroyWebContents) { |
| // At the beginning, there is no watcher. |
| EXPECT_EQ(handler()->GetWatchersForTesting().size(), 0U); |
| |
| // The number of watchers increases after a new WebContents instance is |
| // observed. |
| TestingProfile profile1; |
| std::unique_ptr<WebContents> contents1 = |
| WebContents::Create(WebContents::CreateParams(&profile1)); |
| handler()->Observe(contents1.get()); |
| EXPECT_EQ(handler()->GetWatchersForTesting().size(), 1U); |
| |
| // The number of watchers increases again after another new WebContents |
| // instance is observed. |
| TestingProfile profile2; |
| std::unique_ptr<WebContents> contents2 = |
| WebContents::Create(WebContents::CreateParams(&profile2)); |
| handler()->Observe(contents2.get()); |
| |
| std::vector<KioskSessionPluginHandler::Observer*> watchers = |
| handler()->GetWatchersForTesting(); |
| EXPECT_EQ(watchers.size(), 2U); |
| |
| // The number of watchers returns to zero after each WebContents instance is |
| // destroyed. |
| for (WebContentsObserver* observer : watchers) |
| observer->WebContentsDestroyed(); |
| EXPECT_EQ(handler()->GetWatchersForTesting().size(), 0U); |
| } |
| |
| TEST_F(KioskSessionPluginHandlerTest, PluginCrashed) { |
| TestingProfile profile; |
| std::unique_ptr<WebContents> contents = |
| WebContents::Create(WebContents::CreateParams(&profile)); |
| handler()->Observe(contents.get()); |
| WebContentsObserver* watcher = handler()->GetWatchersForTesting().front(); |
| |
| // At the beginning, no crash is notified to the delegate. |
| EXPECT_FALSE(delegate()->has_crashed()); |
| |
| // No crash is notified if the |plugin_path| is invalid. |
| watcher->PluginCrashed(base::FilePath(kInvalidPluginPath), |
| base::ProcessId(kProcessId)); |
| EXPECT_FALSE(delegate()->has_crashed()); |
| |
| // Crash is notified if the |plugin_path| is valid. |
| watcher->PluginCrashed(base::FilePath(kValidPluginPath), |
| base::ProcessId(kProcessId)); |
| EXPECT_TRUE(delegate()->has_crashed()); |
| } |
| |
| TEST_F(KioskSessionPluginHandlerTest, PluginHungStatusChanged) { |
| TestingProfile profile; |
| std::unique_ptr<WebContents> contents = |
| WebContents::Create(WebContents::CreateParams(&profile)); |
| handler()->Observe(contents.get()); |
| |
| KioskSessionPluginHandler::Observer* observer = |
| handler()->GetWatchersForTesting().front(); |
| WebContentsObserver* watcher = observer; |
| |
| // At the beginning, there is no hung plugin. |
| EXPECT_EQ(observer->GetHungPluginsForTesting().size(), 0U); |
| |
| // The hung plugin is not stored if the |plugin_path| is invalid. |
| watcher->PluginHungStatusChanged(kPluginChildId, |
| base::FilePath(kInvalidPluginPath), true); |
| EXPECT_EQ(observer->GetHungPluginsForTesting().size(), 0U); |
| |
| // The hung plugin is not stored if the |is_hung| is false. |
| watcher->PluginHungStatusChanged(kPluginChildId, |
| base::FilePath(kValidPluginPath), false); |
| EXPECT_EQ(observer->GetHungPluginsForTesting().size(), 0U); |
| |
| // The hung plugin is store. |
| watcher->PluginHungStatusChanged(kPluginChildId, |
| base::FilePath(kValidPluginPath), true); |
| EXPECT_EQ(observer->GetHungPluginsForTesting().size(), 1U); |
| } |
| |
| } // namespace ash |