blob: 1a4969cefd6e369ebb352ca19382b5b52170919b [file] [log] [blame]
// Copyright 2018 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 "extensions/shell/browser/shell_keep_alive_requester.h"
#include <memory>
#include "apps/app_lifetime_monitor_factory.h"
#include "base/macros.h"
#include "components/keep_alive_registry/keep_alive_registry.h"
#include "content/public/browser/browser_context.h"
#include "extensions/browser/disable_reason.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extensions_test.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/extension_id.h"
namespace extensions {
class ShellKeepAliveRequesterTest : public ExtensionsTest {
protected:
ShellKeepAliveRequesterTest() = default;
~ShellKeepAliveRequesterTest() override = default;
void SetUp() override {
// Register factory so it's created with the BrowserContext.
apps::AppLifetimeMonitorFactory::GetInstance();
ExtensionsTest::SetUp();
keep_alive_requester_ =
std::make_unique<ShellKeepAliveRequester>(browser_context());
}
void TearDown() override {
keep_alive_requester_.reset();
ExtensionsTest::TearDown();
}
protected:
std::unique_ptr<ShellKeepAliveRequester> keep_alive_requester_;
private:
DISALLOW_COPY_AND_ASSIGN(ShellKeepAliveRequesterTest);
};
// Tests with an extension.
TEST_F(ShellKeepAliveRequesterTest, Extension) {
scoped_refptr<const Extension> extension =
ExtensionBuilder("extension", ExtensionBuilder::Type::EXTENSION).Build();
// No keep-alive is used for extensions that aren't platform apps.
keep_alive_requester_->OnExtensionLoaded(browser_context(), extension.get());
EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
ExtensionPrefs::Get(browser_context())
->AddDisableReason(extension->id(), disable_reason::DISABLE_RELOAD);
keep_alive_requester_->OnExtensionUnloaded(browser_context(), extension.get(),
UnloadedExtensionReason::DISABLE);
EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
}
// Tests with a platform app.
TEST_F(ShellKeepAliveRequesterTest, PlatformApp) {
scoped_refptr<const Extension> extension =
ExtensionBuilder("platform_app", ExtensionBuilder::Type::PLATFORM_APP)
.Build();
keep_alive_requester_->OnExtensionLoaded(browser_context(), extension.get());
// Expect a keep-alive while waiting for the app to launch a window.
EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
keep_alive_requester_->OnAppActivated(browser_context(), extension->id());
EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
// No keep-alives are registered if the extension stops running.
keep_alive_requester_->OnAppStop(browser_context(), extension->id());
EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
}
// Tests with a platform app that doesn't open a window.
TEST_F(ShellKeepAliveRequesterTest, PlatformAppNoWindow) {
scoped_refptr<const Extension> extension =
ExtensionBuilder("platform_app", ExtensionBuilder::Type::PLATFORM_APP)
.Build();
keep_alive_requester_->OnExtensionLoaded(browser_context(), extension.get());
// Expect a keep-alive while waiting for the app to launch a window.
EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
// Eventually, the app's background host is destroyed.
keep_alive_requester_->OnAppStop(browser_context(), extension->id());
EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
}
// Tests with a platform app that is reloaded.
TEST_F(ShellKeepAliveRequesterTest, PlatformAppReload) {
scoped_refptr<const Extension> extension =
ExtensionBuilder("platform_app", ExtensionBuilder::Type::PLATFORM_APP)
.Build();
keep_alive_requester_->OnExtensionLoaded(browser_context(), extension.get());
// Expect a keep-alive while waiting for the app to launch a window.
EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
keep_alive_requester_->OnAppActivated(browser_context(), extension->id());
EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
// Disable the app for a reload.
keep_alive_requester_->StartTrackingReload(extension.get());
ExtensionPrefs::Get(browser_context())
->AddDisableReason(extension->id(), disable_reason::DISABLE_RELOAD);
keep_alive_requester_->OnAppStop(browser_context(), extension->id());
keep_alive_requester_->OnExtensionUnloaded(browser_context(), extension.get(),
UnloadedExtensionReason::DISABLE);
// Expect a keep-alive while waiting for the app to finish reloading.
EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
keep_alive_requester_->OnExtensionLoaded(browser_context(), extension.get());
keep_alive_requester_->StopTrackingReload(extension->id());
// Expect a keep-alive while waiting for the app to launch a window again.
EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
keep_alive_requester_->OnAppActivated(browser_context(), extension->id());
EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
}
// Tests with a platform app that is reloaded, but fails to load.
TEST_F(ShellKeepAliveRequesterTest, PlatformAppReloadFailure) {
scoped_refptr<const Extension> extension =
ExtensionBuilder("platform_app", ExtensionBuilder::Type::PLATFORM_APP)
.Build();
keep_alive_requester_->OnExtensionLoaded(browser_context(), extension.get());
// Expect a keep-alive while waiting for the app to launch a window.
EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
keep_alive_requester_->OnAppActivated(browser_context(), extension->id());
EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
// Disable the app for a reload.
keep_alive_requester_->StartTrackingReload(extension.get());
keep_alive_requester_->OnAppStop(browser_context(), extension->id());
ExtensionPrefs::Get(browser_context())
->AddDisableReason(extension->id(), disable_reason::DISABLE_RELOAD);
keep_alive_requester_->OnExtensionUnloaded(browser_context(), extension.get(),
UnloadedExtensionReason::DISABLE);
// Expect a keep-alive while waiting for the app to finish reloading that is
// removed when the app fails to load.
EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
keep_alive_requester_->StopTrackingReload(extension->id());
EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
}
// Tests with a platform app that reloads before opening a window.
TEST_F(ShellKeepAliveRequesterTest, PlatformAppNoWindowReload) {
scoped_refptr<const Extension> extension =
ExtensionBuilder("platform_app", ExtensionBuilder::Type::PLATFORM_APP)
.Build();
keep_alive_requester_->OnExtensionLoaded(browser_context(), extension.get());
// Expect a keep-alive while waiting for the app to launch a window.
EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
// Disable the app for a reload.
keep_alive_requester_->StartTrackingReload(extension.get());
keep_alive_requester_->OnAppStop(browser_context(), extension->id());
ExtensionPrefs::Get(browser_context())
->AddDisableReason(extension->id(), disable_reason::DISABLE_RELOAD);
keep_alive_requester_->OnExtensionUnloaded(browser_context(), extension.get(),
UnloadedExtensionReason::DISABLE);
// Expect a keep-alive while waiting for the app to finish reloading.
EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
keep_alive_requester_->OnExtensionLoaded(browser_context(), extension.get());
keep_alive_requester_->StopTrackingReload(extension->id());
// Expect a keep-alive while waiting for the app to launch a window.
EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
keep_alive_requester_->OnAppActivated(browser_context(), extension->id());
EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
}
// Tests with a platform app that is reloaded, but doesn't open a window again.
TEST_F(ShellKeepAliveRequesterTest, PlatformAppReloadNoWindow) {
scoped_refptr<const Extension> extension =
ExtensionBuilder("platform_app", ExtensionBuilder::Type::PLATFORM_APP)
.Build();
keep_alive_requester_->OnExtensionLoaded(browser_context(), extension.get());
// Expect a keep-alive while waiting for the app to launch a window.
EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
keep_alive_requester_->OnAppActivated(browser_context(), extension->id());
EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
// Disable the app for a reload.
keep_alive_requester_->StartTrackingReload(extension.get());
keep_alive_requester_->OnAppStop(browser_context(), extension->id());
ExtensionPrefs::Get(browser_context())
->AddDisableReason(extension->id(), disable_reason::DISABLE_RELOAD);
keep_alive_requester_->OnExtensionUnloaded(browser_context(), extension.get(),
UnloadedExtensionReason::DISABLE);
// Expect a keep-alive while waiting for the app to finish reloading.
EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
keep_alive_requester_->OnExtensionLoaded(browser_context(), extension.get());
keep_alive_requester_->StopTrackingReload(extension->id());
// Expect a keep-alive while waiting for the app to launch a window again.
EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
// Eventually the app stops.
keep_alive_requester_->OnAppStop(browser_context(), extension->id());
EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
}
} // namespace extensions