#include "extensions/shell/browser/shell_desktop_controller_aura.h"
#include <memory>
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/time/time.h"
#include "components/keep_alive_registry/keep_alive_registry.h"
#include "extensions/browser/app_window/app_window.h"
#include "extensions/browser/app_window/app_window_registry.h"
#include "extensions/browser/browsertest_util.h"
#include "extensions/shell/browser/desktop_controller.h"
#include "extensions/shell/test/shell_apitest.h"
#include "extensions/test/result_catcher.h"
namespace extensions {
class ShellDesktopControllerAuraBrowserTest : public ShellApiTest {
public:
ShellDesktopControllerAuraBrowserTest() = default;
~ShellDesktopControllerAuraBrowserTest() override = default;
ShellDesktopControllerAuraBrowserTest(
const ShellDesktopControllerAuraBrowserTest&) = delete;
ShellDesktopControllerAuraBrowserTest& operator=(
const ShellDesktopControllerAuraBrowserTest&) = delete;
void LoadAndLaunchApp() {
ASSERT_FALSE(app_);
app_ = LoadApp("platform_app");
ASSERT_TRUE(app_);
ResultCatcher catcher;
EXPECT_TRUE(catcher.GetNextResult());
EXPECT_EQ(1u,
AppWindowRegistry::Get(browser_context())->app_windows().size());
}
protected:
AppWindow* GetAppWindow() {
EXPECT_GT(AppWindowRegistry::Get(browser_context())->app_windows().size(),
0u);
return AppWindowRegistry::Get(browser_context())->app_windows().front();
}
void SetUpOnMainThread() override {
ShellApiTest::SetUpOnMainThread();
desktop_controller_ =
static_cast<ShellDesktopControllerAura*>(DesktopController::instance());
ASSERT_TRUE(desktop_controller_);
}
void TearDownOnMainThread() override {
EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
desktop_controller_ = nullptr;
ShellApiTest::TearDownOnMainThread();
}
void RunDesktopController() {
desktop_controller_->PreMainMessageLoopRun();
auto run_loop = std::make_unique<base::RunLoop>();
desktop_controller_->WillRunMainMessageLoop(run_loop);
run_loop->Run();
desktop_controller_->PostMainMessageLoopRun();
}
scoped_refptr<const Extension> app_;
private:
raw_ptr<ShellDesktopControllerAura> desktop_controller_ = nullptr;
};
IN_PROC_BROWSER_TEST_F(ShellDesktopControllerAuraBrowserTest, CloseAppWindow) {
bool test_succeeded = false;
base::SingleThreadTaskRunner::GetCurrentDefault()->PostTaskAndReply(
FROM_HERE,
base::BindOnce(&ShellDesktopControllerAuraBrowserTest::LoadAndLaunchApp,
base::Unretained(this)),
base::BindLambdaForTesting([this, &test_succeeded]() {
GetAppWindow()->OnNativeClose();
test_succeeded = true;
}));
RunDesktopController();
EXPECT_TRUE(test_succeeded)
<< "DesktopController quit before test completed.";
}
IN_PROC_BROWSER_TEST_F(ShellDesktopControllerAuraBrowserTest, TwoAppWindows) {
bool test_succeeded = false;
base::SingleThreadTaskRunner::GetCurrentDefault()->PostTaskAndReply(
FROM_HERE,
base::BindOnce(&ShellDesktopControllerAuraBrowserTest::LoadAndLaunchApp,
base::Unretained(this)),
base::BindLambdaForTesting([this, &test_succeeded]() {
ASSERT_TRUE(browsertest_util::ExecuteScriptInBackgroundPageNoWait(
browser_context(), app_->id(),
"chrome.app.window.create('/hello.html');"));
ResultCatcher catcher;
ASSERT_TRUE(catcher.GetNextResult());
GetAppWindow()->OnNativeClose();
base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
FROM_HERE, base::BindLambdaForTesting([this, &test_succeeded]() {
GetAppWindow()->OnNativeClose();
test_succeeded = true;
}),
base::Milliseconds(500));
}));
RunDesktopController();
EXPECT_TRUE(test_succeeded)
<< "DesktopController quit before test completed.";
}
IN_PROC_BROWSER_TEST_F(ShellDesktopControllerAuraBrowserTest, ReloadApp) {
bool test_succeeded = false;
base::SingleThreadTaskRunner::GetCurrentDefault()->PostTaskAndReply(
FROM_HERE,
base::BindOnce(&ShellDesktopControllerAuraBrowserTest::LoadAndLaunchApp,
base::Unretained(this)),
base::BindLambdaForTesting([this, &test_succeeded]() {
ASSERT_TRUE(browsertest_util::ExecuteScriptInBackgroundPageNoWait(
browser_context(), app_->id(), "chrome.runtime.reload();"));
ResultCatcher catcher;
ASSERT_TRUE(catcher.GetNextResult());
base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
FROM_HERE, base::BindLambdaForTesting([this, &test_succeeded]() {
AppWindow* app_window = AppWindowRegistry::Get(browser_context())
->app_windows()
.front();
app_window->OnNativeClose();
test_succeeded = true;
}),
base::Milliseconds(500));
}));
RunDesktopController();
EXPECT_TRUE(test_succeeded)
<< "DesktopController quit before test completed.";
}
}