#include <stddef.h>
#include <memory>
#include "apps/launcher.h"
#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/apps/app_service/app_launch_params.h"
#include "chrome/browser/apps/app_service/app_service_proxy.h"
#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
#include "chrome/browser/apps/app_service/launch_utils.h"
#include "chrome/browser/apps/platform_apps/app_browsertest_util.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/devtools/devtools_window_testing.h"
#include "chrome/browser/extensions/api/permissions/permissions_api.h"
#include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/extensions/app_launch_params.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h"
#include "chrome/browser/web_applications/extension_status_utils.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/test_switches.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "components/services/app_service/public/cpp/app_launch_util.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/host_zoom_map.h"
#include "content/public/browser/overlay_window.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/video_picture_in_picture_window_controller.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "extensions/browser/app_window/app_window.h"
#include "extensions/browser/app_window/app_window_registry.h"
#include "extensions/browser/app_window/native_app_window.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/browser/pref_names.h"
#include "extensions/common/api/app_runtime.h"
#include "extensions/common/constants.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "printing/buildflags/buildflags.h"
#include "third_party/blink/public/common/features.h"
#include "ui/base/window_open_disposition.h"
#include "url/gurl.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/apps/app_service/chrome_app_deprecation/chrome_app_deprecation.h"
#include "chrome/browser/ash/login/test/local_state_mixin.h"
#include "chrome/browser/ash/test/kiosk_app_logged_in_browser_test_mixin.h"
#include "chromeos/dbus/power/fake_power_manager_client.h"
#include "components/user_manager/user_manager.h"
#endif
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
#include "chrome/browser/printing/test_print_preview_observer.h"
#include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
#endif
using content::WebContents;
using web_modal::WebContentsModalDialogManager;
namespace app_runtime = extensions::api::app_runtime;
namespace extensions {
namespace {
bool ExpectChromeAppsDefaultEnabled() {
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
return false;
#else
return true;
#endif
}
class PlatformAppContextMenu : public RenderViewContextMenu {
public:
PlatformAppContextMenu(content::RenderFrameHost& render_frame_host,
const content::ContextMenuParams& params)
: RenderViewContextMenu(render_frame_host, params) {}
bool HasCommandWithId(int command_id) {
return menu_model_.GetIndexOfCommandId(command_id).has_value();
}
void Show() override {}
};
class TabsAddedObserver : public TabStripModelObserver {
public:
TabsAddedObserver(Browser* browser, size_t observations)
: observations_(observations) {
browser->tab_strip_model()->AddObserver(this);
}
TabsAddedObserver(const TabsAddedObserver&) = delete;
TabsAddedObserver& operator=(const TabsAddedObserver&) = delete;
~TabsAddedObserver() override = default;
void OnTabStripModelChanged(
TabStripModel* tab_strip_model,
const TabStripModelChange& change,
const TabStripSelectionChange& selection) override {
if (change.type() != TabStripModelChange::kInserted)
return;
for (auto& tab : change.GetInsert()->contents)
observed_tabs_.push_back(tab.contents.get());
if (observed_tabs_.size() >= observations_)
run_loop_.Quit();
}
void Wait() { run_loop_.Run(); }
const std::vector<raw_ptr<content::WebContents, VectorExperimental>>& tabs() {
return observed_tabs_;
}
private:
base::RunLoop run_loop_;
size_t observations_;
std::vector<raw_ptr<content::WebContents, VectorExperimental>> observed_tabs_;
};
#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_WIN)
bool CopyTestDataAndGetTestFilePath(const base::FilePath& test_data_file,
const base::FilePath& temp_dir,
const char* filename,
base::FilePath* file_path) {
base::FilePath path =
temp_dir.AppendASCII(filename).NormalizePathSeparators();
if (!(base::CopyFile(test_data_file, path)))
return false;
*file_path = path;
return true;
}
#endif
class PlatformAppWithFileBrowserTest : public PlatformAppBrowserTest {
public:
PlatformAppWithFileBrowserTest()
: enable_chrome_apps_(
&extensions::testing::g_enable_chrome_apps_for_testing,
true) {
set_open_about_blank_on_browser_launch(false);
}
protected:
bool RunPlatformAppTestWithFileInTestDataDir(
const std::string& extension_name,
const std::string& test_file) {
base::FilePath test_doc(test_data_dir_.AppendASCII(test_file));
test_doc = test_doc.NormalizePathSeparators();
return RunPlatformAppTestWithCommandLine(
extension_name, MakeCommandLineWithTestFilePath(test_doc));
}
bool RunPlatformAppTestWithFile(const std::string& extension_name,
const base::FilePath& test_file_path) {
return RunPlatformAppTestWithCommandLine(
extension_name, MakeCommandLineWithTestFilePath(test_file_path));
}
bool RunPlatformAppTestWithNothing(const std::string& extension_name) {
return RunPlatformAppTestWithCommandLine(
extension_name, *base::CommandLine::ForCurrentProcess());
}
void RunPlatformAppTestWithFiles(const std::string& extension_name,
const std::string& test_file) {
extensions::ResultCatcher catcher;
base::FilePath test_doc(test_data_dir_.AppendASCII(test_file));
base::FilePath file_path = test_doc.NormalizePathSeparators();
base::FilePath extension_path = test_data_dir_.AppendASCII(extension_name);
const extensions::Extension* extension = LoadExtension(extension_path);
ASSERT_TRUE(extension);
std::vector<base::FilePath> launch_files;
launch_files.push_back(file_path);
apps::AppServiceProxyFactory::GetForProfile(browser()->profile())
->LaunchAppWithFiles(
extension->id(),
apps::GetEventFlags(WindowOpenDisposition::NEW_FOREGROUND_TAB,
true ),
apps::LaunchSource::kFromTest, std::move(launch_files));
ASSERT_TRUE(catcher.GetNextResult());
}
private:
bool RunPlatformAppTestWithCommandLine(
const std::string& extension_name,
const base::CommandLine& command_line) {
extensions::ResultCatcher catcher;
base::FilePath extension_path = test_data_dir_.AppendASCII(extension_name);
const extensions::Extension* extension = LoadExtension(extension_path);
if (!extension) {
message_ = "Failed to load extension.";
return false;
}
apps::AppLaunchParams params(
extension->id(), apps::LaunchContainer::kLaunchContainerNone,
WindowOpenDisposition::NEW_WINDOW, apps::LaunchSource::kFromTest);
params.command_line = command_line;
params.current_directory = test_data_dir_;
apps::AppServiceProxyFactory::GetForProfile(browser()->profile())
->LaunchAppWithParams(std::move(params));
if (!catcher.GetNextResult()) {
message_ = catcher.message();
return false;
}
return true;
}
base::CommandLine MakeCommandLineWithTestFilePath(
const base::FilePath& test_file) {
base::CommandLine command_line = *base::CommandLine::ForCurrentProcess();
command_line.AppendArgPath(test_file);
return command_line;
}
private:
base::AutoReset<bool> enable_chrome_apps_;
};
const char kChromiumURL[] = "https://chromium.org";
#if !BUILDFLAG(IS_CHROMEOS)
const char kTestFilePath[] = "platform_apps/launch_files/test.txt";
#endif
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, CreateAndCloseAppWindow) {
const Extension* extension = LoadAndLaunchPlatformApp("minimal", "Launched");
AppWindow* window = CreateAppWindow(browser()->profile(), extension);
CloseAppWindow(window);
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, OnLaunchedEvent) {
ASSERT_TRUE(RunExtensionTest("platform_apps/launch",
{.launch_as_platform_app = true}))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, DisabledWindowProperties) {
ASSERT_TRUE(RunExtensionTest("platform_apps/disabled_window_properties",
{.launch_as_platform_app = true}))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, EmptyContextMenu) {
LoadAndLaunchPlatformApp("minimal", "Launched");
WebContents* web_contents = GetFirstAppWindowWebContents();
ASSERT_TRUE(web_contents);
content::ContextMenuParams params;
auto menu = std::make_unique<PlatformAppContextMenu>(
*web_contents->GetPrimaryMainFrame(), params);
menu->Init();
ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTELEMENT));
ASSERT_TRUE(
menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE));
ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_RELOAD_PACKAGED_APP));
ASSERT_FALSE(menu->HasCommandWithId(IDC_BACK));
ASSERT_FALSE(menu->HasCommandWithId(IDC_SAVE_PAGE));
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, AppWithContextMenu) {
LoadAndLaunchPlatformApp("context_menu", "Launched");
WebContents* web_contents = GetFirstAppWindowWebContents();
ASSERT_TRUE(web_contents);
content::ContextMenuParams params;
auto menu = std::make_unique<PlatformAppContextMenu>(
*web_contents->GetPrimaryMainFrame(), params);
menu->Init();
int first_extensions_command_id =
ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0);
ASSERT_TRUE(menu->HasCommandWithId(first_extensions_command_id));
ASSERT_TRUE(menu->HasCommandWithId(first_extensions_command_id + 1));
ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTELEMENT));
ASSERT_TRUE(
menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE));
ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_RELOAD_PACKAGED_APP));
ASSERT_FALSE(menu->HasCommandWithId(IDC_BACK));
ASSERT_FALSE(menu->HasCommandWithId(IDC_SAVE_PAGE));
ASSERT_FALSE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_UNDO));
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, InstalledAppWithContextMenu) {
const Extension* extension = InstallPlatformApp("context_menu");
ASSERT_TRUE(extension);
#if BUILDFLAG(IS_CHROMEOS)
apps::chrome_app_deprecation::ScopedAddAppToAllowlistForTesting allowlist(
extension->id());
#endif
ExtensionTestMessageListener launched_listener("Launched");
{
content::CreateAndLoadWebContentsObserver app_loaded_observer;
LaunchPlatformApp(extension);
app_loaded_observer.Wait();
}
ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
WebContents* web_contents = GetFirstAppWindowWebContents();
ASSERT_TRUE(web_contents);
content::ContextMenuParams params;
auto menu = std::make_unique<PlatformAppContextMenu>(
*web_contents->GetPrimaryMainFrame(), params);
menu->Init();
int extensions_custom_id =
ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0);
ASSERT_TRUE(menu->HasCommandWithId(extensions_custom_id));
ASSERT_TRUE(menu->HasCommandWithId(extensions_custom_id + 1));
ASSERT_FALSE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTELEMENT));
ASSERT_FALSE(
menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE));
ASSERT_FALSE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_RELOAD_PACKAGED_APP));
ASSERT_FALSE(menu->HasCommandWithId(IDC_BACK));
ASSERT_FALSE(menu->HasCommandWithId(IDC_SAVE_PAGE));
ASSERT_FALSE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_UNDO));
}
#if BUILDFLAG(IS_MAC)
#define MAYBE_AppWithContextMenuTextField DISABLED_AppWithContextMenuTextField
#else
#define MAYBE_AppWithContextMenuTextField AppWithContextMenuTextField
#endif
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
MAYBE_AppWithContextMenuTextField) {
LoadAndLaunchPlatformApp("context_menu", "Launched");
WebContents* web_contents = GetFirstAppWindowWebContents();
ASSERT_TRUE(web_contents);
content::ContextMenuParams params;
params.is_editable = true;
auto menu = std::make_unique<PlatformAppContextMenu>(
*web_contents->GetPrimaryMainFrame(), params);
menu->Init();
int extensions_custom_id =
ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0);
ASSERT_TRUE(menu->HasCommandWithId(extensions_custom_id));
ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTELEMENT));
ASSERT_TRUE(
menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE));
ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_RELOAD_PACKAGED_APP));
ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_UNDO));
ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_COPY));
ASSERT_FALSE(menu->HasCommandWithId(IDC_BACK));
ASSERT_FALSE(menu->HasCommandWithId(IDC_SAVE_PAGE));
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, AppWithContextMenuSelection) {
LoadAndLaunchPlatformApp("context_menu", "Launched");
WebContents* web_contents = GetFirstAppWindowWebContents();
ASSERT_TRUE(web_contents);
content::ContextMenuParams params;
params.selection_text = u"Hello World";
auto menu = std::make_unique<PlatformAppContextMenu>(
*web_contents->GetPrimaryMainFrame(), params);
menu->Init();
int extensions_custom_id =
ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0);
ASSERT_TRUE(menu->HasCommandWithId(extensions_custom_id));
ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTELEMENT));
ASSERT_TRUE(
menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE));
ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_RELOAD_PACKAGED_APP));
ASSERT_FALSE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_UNDO));
ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_COPY));
ASSERT_FALSE(menu->HasCommandWithId(IDC_BACK));
ASSERT_FALSE(menu->HasCommandWithId(IDC_SAVE_PAGE));
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, AppWithContextMenuClicked) {
LoadAndLaunchPlatformApp("context_menu_click", "Launched");
WebContents* web_contents = GetFirstAppWindowWebContents();
ASSERT_TRUE(web_contents);
content::ContextMenuParams params;
params.page_url = GURL("http://foo.bar");
auto menu = std::make_unique<PlatformAppContextMenu>(
*web_contents->GetPrimaryMainFrame(), params);
menu->Init();
int extensions_custom_id =
ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0);
ASSERT_TRUE(menu->HasCommandWithId(extensions_custom_id));
ExtensionTestMessageListener onclicked_listener("onClicked fired for id1");
menu->ExecuteCommand(extensions_custom_id, 0);
ASSERT_TRUE(onclicked_listener.WaitUntilSatisfied());
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, DISABLED_DisallowNavigation) {
TabsAddedObserver observer(browser(), 1);
ASSERT_TRUE(StartEmbeddedTestServer());
ASSERT_TRUE(RunExtensionTest("platform_apps/navigation",
{.launch_as_platform_app = true}))
<< message_;
observer.Wait();
ASSERT_EQ(1U, observer.tabs().size());
EXPECT_EQ(GURL(kChromiumURL), observer.tabs()[0]->GetURL());
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
DisallowBackgroundPageNavigation) {
const size_t kExpectedNumberOfTabs = 2u;
TabsAddedObserver observer(browser(), kExpectedNumberOfTabs);
ASSERT_TRUE(RunExtensionTest("platform_apps/background_page_navigation",
{.launch_as_platform_app = true}))
<< message_;
observer.Wait();
ASSERT_EQ(kExpectedNumberOfTabs, observer.tabs().size());
EXPECT_FALSE(
content::WaitForLoadStop(observer.tabs()[kExpectedNumberOfTabs - 1]));
EXPECT_EQ(GURL(kChromiumURL),
observer.tabs()[kExpectedNumberOfTabs - 1]->GetURL());
EXPECT_FALSE(
content::WaitForLoadStop(observer.tabs()[kExpectedNumberOfTabs - 2]));
EXPECT_EQ(GURL(kChromiumURL),
observer.tabs()[kExpectedNumberOfTabs - 2]->GetURL());
}
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
BUILDFLAG(IS_MAC)
#define MAYBE_Iframes DISABLED_Iframes
#else
#define MAYBE_Iframes Iframes
#endif
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, MAYBE_Iframes) {
ASSERT_TRUE(StartEmbeddedTestServer());
ASSERT_TRUE(RunExtensionTest("platform_apps/iframes",
{.launch_as_platform_app = true}))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, AllowFileSystemURLNavigation) {
if (!base::FeatureList::IsEnabled(
blink::features::kFileSystemUrlNavigationForChromeAppsOnly)) {
GTEST_SKIP();
}
ASSERT_TRUE(RunExtensionTest("platform_apps/filesystem_url",
{.launch_as_platform_app = true}))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, DisallowStorage) {
ASSERT_TRUE(RunExtensionTest("platform_apps/storage",
{.launch_as_platform_app = true}))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, Restrictions) {
ASSERT_TRUE(RunExtensionTest("platform_apps/restrictions",
{.launch_as_platform_app = true}))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, PlatformAppsOnly) {
ASSERT_TRUE(RunExtensionTest("platform_apps/apps_only", {},
{.ignore_manifest_warnings = true}))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, DISABLED_Isolation) {
ASSERT_TRUE(StartEmbeddedTestServer());
GURL set_cookie_url = embedded_test_server()->GetURL(
"/extensions/platform_apps/isolation/set_cookie.html");
GURL::Replacements replace_host;
replace_host.SetHostStr("localhost");
set_cookie_url = set_cookie_url.ReplaceComponents(replace_host);
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), set_cookie_url));
int cookie_size;
std::string cookie_value;
ui_test_utils::GetCookies(set_cookie_url,
browser()->tab_strip_model()->GetWebContentsAt(0),
&cookie_size, &cookie_value);
ASSERT_EQ("testCookie=1", cookie_value);
ASSERT_TRUE(RunExtensionTest("platform_apps/isolation",
{.launch_as_platform_app = true}))
<< message_;
}
#if BUILDFLAG(IS_WIN)
#define MAYBE_ExtensionWindowingApis DISABLED_ExtensionWindowingApis
#else
#define MAYBE_ExtensionWindowingApis ExtensionWindowingApis
#endif
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, MAYBE_ExtensionWindowingApis) {
const Extension* extension =
LoadExtension(test_data_dir_.AppendASCII("common/background_page"));
ASSERT_EQ(1U, RunGetWindowsFunctionForExtension(extension));
ASSERT_EQ(0U, GetAppWindowCount());
LoadAndLaunchPlatformApp("minimal", "Launched");
ASSERT_EQ(1U, GetAppWindowCount());
int app_window_id = GetFirstAppWindow()->session_id().id();
ASSERT_EQ(1U, RunGetWindowsFunctionForExtension(extension));
ASSERT_FALSE(RunGetWindowFunctionForExtension(app_window_id, extension));
LoadAndLaunchPlatformApp("context_menu", "Launched");
ASSERT_EQ(2U, GetAppWindowCount());
}
#if !BUILDFLAG(IS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest,
LaunchFilesWithFileExtension) {
RunPlatformAppTestWithFiles("platform_apps/launch_file_by_extension",
kTestFilePath);
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest, LaunchWithFile) {
ASSERT_TRUE(RunPlatformAppTestWithFileInTestDataDir(
"platform_apps/launch_file", kTestFilePath))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest, LaunchWithRelativeFile) {
ASSERT_TRUE(
RunPlatformAppTestWithFile("platform_apps/launch_file",
base::FilePath::FromUTF8Unsafe(kTestFilePath)))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest,
LaunchWithFileExtension) {
ASSERT_TRUE(RunPlatformAppTestWithFileInTestDataDir(
"platform_apps/launch_file_by_extension", kTestFilePath))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest,
LaunchAllowListedExtensionWithFile) {
ASSERT_TRUE(RunPlatformAppTestWithFileInTestDataDir(
"platform_apps/launch_allowlisted_ext_with_file", kTestFilePath))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest,
LaunchWithFileExtensionAndMimeType) {
ASSERT_TRUE(RunPlatformAppTestWithFileInTestDataDir(
"platform_apps/launch_file_by_extension_and_type", kTestFilePath))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest,
LaunchWithFileWithoutExtension) {
ASSERT_TRUE(RunPlatformAppTestWithFileInTestDataDir(
"platform_apps/launch_file_with_no_extension",
"platform_apps/launch_files/test"))
<< message_;
}
#if !BUILDFLAG(IS_WIN)
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest,
LaunchWithFileEmptyExtension) {
base::ScopedAllowBlockingForTesting allow_blocking;
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath test_file;
ASSERT_TRUE(
CopyTestDataAndGetTestFilePath(test_data_dir_.AppendASCII(kTestFilePath),
temp_dir.GetPath(), "test.", &test_file));
ASSERT_TRUE(RunPlatformAppTestWithFile(
"platform_apps/launch_file_with_no_extension", test_file))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest,
LaunchWithFileEmptyExtensionAcceptAny) {
base::ScopedAllowBlockingForTesting allow_blocking;
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath test_file;
ASSERT_TRUE(
CopyTestDataAndGetTestFilePath(test_data_dir_.AppendASCII(kTestFilePath),
temp_dir.GetPath(), "test.", &test_file));
ASSERT_TRUE(RunPlatformAppTestWithFile(
"platform_apps/launch_file_with_any_extension", test_file))
<< message_;
}
#endif
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest,
LaunchWithFileWithoutExtensionAcceptAny) {
ASSERT_TRUE(RunPlatformAppTestWithFileInTestDataDir(
"platform_apps/launch_file_with_any_extension",
"platform_apps/launch_files/test"))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest,
LaunchWithFileAcceptAnyExtension) {
ASSERT_TRUE(RunPlatformAppTestWithFileInTestDataDir(
"platform_apps/launch_file_with_any_extension", kTestFilePath))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest,
LaunchWithWrongExtension) {
ASSERT_TRUE(RunPlatformAppTestWithFileInTestDataDir(
"platform_apps/launch_wrong_extension", kTestFilePath))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest,
LaunchWithWrongEmptyExtension) {
ASSERT_TRUE(RunPlatformAppTestWithFileInTestDataDir(
"platform_apps/launch_wrong_extension",
"platform_apps/launch_files/test"))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest, LaunchWithWrongType) {
ASSERT_TRUE(RunPlatformAppTestWithFileInTestDataDir(
"platform_apps/launch_wrong_type", kTestFilePath))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest, LaunchWithNoIntent) {
ASSERT_TRUE(RunPlatformAppTestWithFileInTestDataDir(
"platform_apps/launch_no_intent", kTestFilePath))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest,
LaunchWithSniffableType) {
ASSERT_TRUE(RunPlatformAppTestWithFileInTestDataDir(
"platform_apps/launch_file_by_extension_and_type",
"platform_apps/launch_files/test.unknownextension"))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest, LaunchNoType) {
ASSERT_TRUE(RunPlatformAppTestWithFileInTestDataDir(
"platform_apps/launch_application_octet_stream",
"platform_apps/launch_files/test_binary.unknownextension"))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest, LaunchNoFile) {
ASSERT_TRUE(RunPlatformAppTestWithFileInTestDataDir(
"platform_apps/launch_invalid",
"platform_apps/launch_files/doesnotexist.txt"))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest, LaunchWithDirectory) {
ASSERT_TRUE(RunPlatformAppTestWithFileInTestDataDir(
"platform_apps/launch_invalid", "platform_apps/launch_files"))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest, LaunchWithNothing) {
ASSERT_TRUE(RunPlatformAppTestWithNothing("platform_apps/launch_nothing"))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest, GetDisplayPath) {
ASSERT_TRUE(RunPlatformAppTestWithFileInTestDataDir(
"platform_apps/get_display_path", kTestFilePath))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest, LaunchNewFile) {
base::ScopedAllowBlockingForTesting allow_blocking;
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
ASSERT_TRUE(RunPlatformAppTestWithFile(
"platform_apps/launch_new_file",
temp_dir.GetPath().AppendASCII("new_file.txt")))
<< message_;
}
#endif
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, OpenLink) {
ASSERT_TRUE(StartEmbeddedTestServer());
ui_test_utils::TabAddedWaiter tab_added_waiter(browser());
LoadAndLaunchPlatformApp("open_link", "Launched");
tab_added_waiter.Wait();
ASSERT_EQ(2, browser()->tab_strip_model()->count());
}
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
#define MAYBE_AppWindowRestoreState DISABLED_AppWindowRestoreState
#else
#define MAYBE_AppWindowRestoreState AppWindowRestoreState
#endif
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, MAYBE_AppWindowRestoreState) {
ASSERT_TRUE(RunExtensionTest("platform_apps/restore_state",
{.launch_as_platform_app = true}));
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
AppWindowAdjustBoundsToBeVisibleOnScreen) {
const Extension* extension = LoadAndLaunchPlatformApp("minimal", "Launched");
AppWindow* window = CreateAppWindow(browser()->profile(), extension);
gfx::Rect cached_bounds(80, 100, 400, 400);
gfx::Rect cached_screen_bounds(0, 0, 1600, 900);
gfx::Rect current_screen_bounds(0, 0, 1600, 900);
gfx::Size minimum_size(200, 200);
gfx::Rect bounds;
CallAdjustBoundsToBeVisibleOnScreenForAppWindow(
window, cached_bounds, cached_screen_bounds, current_screen_bounds,
minimum_size, &bounds);
EXPECT_EQ(bounds, cached_bounds);
gfx::Rect empty_screen_bounds;
CallAdjustBoundsToBeVisibleOnScreenForAppWindow(
window, cached_bounds, empty_screen_bounds, current_screen_bounds,
minimum_size, &bounds);
EXPECT_EQ(bounds, cached_bounds);
gfx::Rect horizontal_out_of_screen_bounds(-800, 100, 400, 400);
CallAdjustBoundsToBeVisibleOnScreenForAppWindow(
window, horizontal_out_of_screen_bounds, gfx::Rect(-1366, 0, 1600, 900),
current_screen_bounds, minimum_size, &bounds);
EXPECT_EQ(bounds, gfx::Rect(0, 100, 400, 400));
gfx::Rect vertical_out_of_screen_bounds(10, 1000, 400, 400);
CallAdjustBoundsToBeVisibleOnScreenForAppWindow(
window, vertical_out_of_screen_bounds, gfx::Rect(-1366, 0, 1600, 900),
current_screen_bounds, minimum_size, &bounds);
EXPECT_EQ(bounds, gfx::Rect(10, 500, 400, 400));
gfx::Rect big_cache_bounds(10, 10, 1000, 1000);
CallAdjustBoundsToBeVisibleOnScreenForAppWindow(
window, big_cache_bounds, gfx::Rect(0, 0, 1600, 1000),
gfx::Rect(0, 0, 800, 600), minimum_size, &bounds);
EXPECT_EQ(bounds, gfx::Rect(0, 0, 800, 600));
CallAdjustBoundsToBeVisibleOnScreenForAppWindow(
window, big_cache_bounds, gfx::Rect(0, 0, 1600, 1000),
gfx::Rect(0, 0, 800, 600), gfx::Size(900, 900), &bounds);
EXPECT_EQ(bounds, gfx::Rect(0, 0, 900, 900));
}
namespace {
#if BUILDFLAG(IS_LINUX) && !defined(NDEBUG)
#define MAYBE_PlatformAppDevToolsBrowserTest \
DISABLED_PlatformAppDevToolsBrowserTest
#else
#define MAYBE_PlatformAppDevToolsBrowserTest PlatformAppDevToolsBrowserTest
#endif
class MAYBE_PlatformAppDevToolsBrowserTest : public PlatformAppBrowserTest {
protected:
enum TestFlags {
RELAUNCH = 0x1,
HAS_ID = 0x2,
};
void RunTestWithDevTools(const char* name, int test_flags);
};
void MAYBE_PlatformAppDevToolsBrowserTest::RunTestWithDevTools(const char* name,
int test_flags) {
using content::DevToolsAgentHost;
const Extension* extension = LoadAndLaunchPlatformApp(name, "Launched");
ASSERT_TRUE(extension);
AppWindow* window = GetFirstAppWindow();
ASSERT_TRUE(window);
ASSERT_EQ(window->window_key().empty(), (test_flags & HAS_ID) == 0);
content::WebContents* web_contents = window->web_contents();
ASSERT_TRUE(web_contents);
DevToolsWindowTesting::OpenDevToolsWindowSync(web_contents, false);
if (test_flags & RELAUNCH) {
CloseAppWindow(window);
ASSERT_FALSE(GetFirstAppWindow());
#if BUILDFLAG(IS_CHROMEOS)
apps::chrome_app_deprecation::ScopedAddAppToAllowlistForTesting allowlist(
extension->id());
#endif
content::CreateAndLoadWebContentsObserver app_loaded_observer(
2);
apps::AppServiceProxyFactory::GetForProfile(browser()->profile())
->LaunchAppWithParams(apps::AppLaunchParams(
extension->id(), apps::LaunchContainer::kLaunchContainerNone,
WindowOpenDisposition::NEW_WINDOW, apps::LaunchSource::kFromTest));
app_loaded_observer.Wait();
window = GetFirstAppWindow();
ASSERT_TRUE(window);
web_contents = window->web_contents();
ASSERT_TRUE(web_contents);
ASSERT_TRUE(DevToolsAgentHost::HasFor(web_contents));
}
}
}
IN_PROC_BROWSER_TEST_F(MAYBE_PlatformAppDevToolsBrowserTest, ReOpenedWithID) {
RunTestWithDevTools("minimal_id", RELAUNCH | HAS_ID);
}
IN_PROC_BROWSER_TEST_F(MAYBE_PlatformAppDevToolsBrowserTest, ReOpenedWithURL) {
RunTestWithDevTools("minimal", RELAUNCH);
}
#if BUILDFLAG(IS_MAC)
#define MAYBE_ConstrainedWindowRequest DISABLED_ConstrainedWindowRequest
#else
#define MAYBE_ConstrainedWindowRequest DISABLED_ConstrainedWindowRequest
#endif
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, MAYBE_ConstrainedWindowRequest) {
PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
const Extension* extension =
LoadAndLaunchPlatformApp("optional_permission_request", "Launched");
ASSERT_TRUE(extension) << "Failed to load extension.";
WebContents* web_contents = GetFirstAppWindowWebContents();
ASSERT_TRUE(web_contents);
WebContentsModalDialogManager* web_contents_modal_dialog_manager =
WebContentsModalDialogManager::FromWebContents(web_contents);
EXPECT_TRUE(web_contents_modal_dialog_manager->IsDialogActive());
ExtensionTestMessageListener listener("PermissionRequestDone");
WebContentsModalDialogManager::TestApi test_api(
web_contents_modal_dialog_manager);
test_api.CloseAllDialogs();
ASSERT_TRUE(listener.WaitUntilSatisfied());
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, ReloadRelaunches) {
ExtensionTestMessageListener launched_listener("Launched",
ReplyBehavior::kWillReply);
const Extension* extension =
LoadAndLaunchPlatformApp("reload", &launched_listener);
ASSERT_TRUE(extension);
ASSERT_TRUE(GetFirstAppWindow());
ExtensionTestMessageListener launched_listener2("Launched");
launched_listener.Reply("reload");
ASSERT_TRUE(launched_listener2.WaitUntilSatisfied());
ASSERT_TRUE(GetFirstAppWindow());
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
ComponentReloadLoadsLazyBackgroundPage) {
ExtensionTestMessageListener launched_listener("Launched",
ReplyBehavior::kWillReply);
const Extension* component_app = LoadExtensionAsComponentWithManifest(
test_data_dir_.AppendASCII("platform_apps")
.AppendASCII("component_reload"),
FILE_PATH_LITERAL("manifest.json"));
ASSERT_TRUE(component_app);
ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
ExtensionTestMessageListener launched_listener2("Launched");
launched_listener.Reply("reload");
ASSERT_TRUE(launched_listener2.WaitUntilSatisfied());
}
class PlatformAppChromeAppsDeprecationTest
: public PlatformAppBrowserTest,
public ::testing::WithParamInterface<bool> {
public:
PlatformAppChromeAppsDeprecationTest()
: chrome_apps_maybe_enabled_(
&extensions::testing::g_enable_chrome_apps_for_testing,
AreChromeAppsEnabledForTesting()) {}
bool AreChromeAppsEnabledForTesting() { return GetParam(); }
private:
base::AutoReset<bool> chrome_apps_maybe_enabled_;
};
IN_PROC_BROWSER_TEST_P(PlatformAppChromeAppsDeprecationTest,
PlatformAppInAppService) {
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("platform_apps").AppendASCII("minimal"),
{.context_type = ContextType::kFromManifest}));
ExtensionId packaged_app_id = last_loaded_extension_id();
apps::AppServiceProxy* proxy =
apps::AppServiceProxyFactory::GetForProfile(profile());
ASSERT_TRUE(proxy);
bool called = false;
proxy->AppRegistryCache().ForOneApp(
packaged_app_id,
[&called](const apps::AppUpdate& update) { called = true; });
if (AreChromeAppsEnabledForTesting()) {
EXPECT_TRUE(called);
} else {
EXPECT_EQ(ExpectChromeAppsDefaultEnabled(), called);
}
}
INSTANTIATE_TEST_SUITE_P(
,
PlatformAppChromeAppsDeprecationTest,
::testing::Values(true, false));
namespace {
class CheckExtensionInstalledObserver
: public extensions::ExtensionRegistryObserver {
public:
explicit CheckExtensionInstalledObserver(Profile* profile)
: seen_(false), registry_(extensions::ExtensionRegistry::Get(profile)) {
registry_->AddObserver(this);
}
~CheckExtensionInstalledObserver() override {
registry_->RemoveObserver(this);
}
bool seen() const { return seen_; }
void OnExtensionWillBeInstalled(content::BrowserContext* browser_context,
const extensions::Extension* extension,
bool is_update,
const std::string& old_name) override {
EXPECT_FALSE(seen_);
seen_ = true;
}
private:
bool seen_;
raw_ptr<extensions::ExtensionRegistry> registry_;
};
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
PRE_PRE_ComponentAppBackgroundPage) {
CheckExtensionInstalledObserver should_install(browser()->profile());
content::CreateAndLoadWebContentsObserver app_loaded_observer;
const Extension* extension = LoadExtensionAsComponent(
test_data_dir_.AppendASCII("platform_apps").AppendASCII("component"));
ASSERT_TRUE(extension);
app_loaded_observer.Wait();
ASSERT_TRUE(should_install.seen());
ExtensionTestMessageListener launched_listener("Launched");
apps::AppServiceProxyFactory::GetForProfile(browser()->profile())
->LaunchAppWithParams(apps::AppLaunchParams(
extension->id(), apps::LaunchContainer::kLaunchContainerNone,
WindowOpenDisposition::NEW_WINDOW, apps::LaunchSource::kFromTest));
ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, PRE_ComponentAppBackgroundPage) {
CheckExtensionInstalledObserver should_not_install(browser()->profile());
const Extension* extension = LoadExtensionAsComponent(
test_data_dir_.AppendASCII("platform_apps").AppendASCII("component"));
ASSERT_TRUE(extension);
ExtensionTestMessageListener launched_listener("Launched");
apps::AppServiceProxyFactory::GetForProfile(browser()->profile())
->LaunchAppWithParams(apps::AppLaunchParams(
extension->id(), apps::LaunchContainer::kLaunchContainerNone,
WindowOpenDisposition::NEW_WINDOW, apps::LaunchSource::kFromTest));
ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
ASSERT_FALSE(should_not_install.seen());
ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(browser()->profile());
extensions::EventRouter::Get(browser()->profile())
->ClearRegisteredEventsForTest(extension->id());
ScopedDictPrefUpdate update(extension_prefs->pref_service(),
extensions::pref_names::kExtensions);
std::string key(extension->id());
key += ".manifest.version";
update->SetByDottedPath(key, "1");
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, ComponentAppBackgroundPage) {
CheckExtensionInstalledObserver should_install(browser()->profile());
content::CreateAndLoadWebContentsObserver app_loaded_observer;
const Extension* extension = LoadExtensionAsComponent(
test_data_dir_.AppendASCII("platform_apps").AppendASCII("component"));
ASSERT_TRUE(extension);
app_loaded_observer.Wait();
ASSERT_TRUE(should_install.seen());
ExtensionTestMessageListener launched_listener("Launched");
apps::AppServiceProxyFactory::GetForProfile(browser()->profile())
->LaunchAppWithParams(apps::AppLaunchParams(
extension->id(), apps::LaunchContainer::kLaunchContainerNone,
WindowOpenDisposition::NEW_WINDOW, apps::LaunchSource::kFromTest));
ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
DISABLED_ComponentExtensionRuntimeReload) {
content::CreateAndLoadWebContentsObserver app_loaded_observer;
const Extension* extension = LoadExtensionAsComponent(
test_data_dir_.AppendASCII("platform_apps").AppendASCII("component"));
ASSERT_TRUE(extension);
app_loaded_observer.Wait();
{
ExtensionTestMessageListener launched_listener("Launched");
apps::AppServiceProxyFactory::GetForProfile(browser()->profile())
->LaunchAppWithParams(apps::AppLaunchParams(
extension->id(), apps::LaunchContainer::kLaunchContainerNone,
WindowOpenDisposition::NEW_WINDOW, apps::LaunchSource::kFromTest));
ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
}
{
ExtensionTestMessageListener launched_listener("Launched");
ASSERT_TRUE(ExecuteScriptInBackgroundPageNoWait(
extension->id(),
"window.domAutomationController.send(0);"
"chrome.runtime.reload();"));
ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
}
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, Messaging) {
ResultCatcher result_catcher;
LoadAndLaunchPlatformApp("messaging/app2", "Ready");
LoadAndLaunchPlatformApp("messaging/app1", "Launched");
EXPECT_TRUE(result_catcher.GetNextResult());
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, DISABLED_WebContentsHasFocus) {
LoadAndLaunchPlatformApp("minimal", "Launched");
EXPECT_EQ(1LU, GetAppWindowCount());
EXPECT_TRUE(GetFirstAppWindow()
->web_contents()
->GetRenderWidgetHostView()
->HasFocus());
}
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
WindowDotPrintShouldBringUpPrintPreview) {
printing::TestPrintPreviewObserver print_observer(false);
ASSERT_TRUE(RunExtensionTest("platform_apps/print_api",
{.launch_as_platform_app = true}))
<< message_;
print_observer.WaitUntilPreviewIsReady();
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
DISABLED_ClosingWindowWhilePrintingShouldNotCrash) {
printing::TestPrintPreviewObserver print_observer(false);
ASSERT_TRUE(RunExtensionTest("platform_apps/print_api",
{.launch_as_platform_app = true}))
<< message_;
print_observer.WaitUntilPreviewIsReady();
GetFirstAppWindow()->GetBaseWindow()->Close();
}
#endif
#if BUILDFLAG(IS_CHROMEOS)
class PlatformAppIncognitoBrowserTest : public PlatformAppBrowserTest,
public AppWindowRegistry::Observer {
public:
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitch(switches::kIncognito);
PlatformAppBrowserTest::SetUpCommandLine(command_line);
}
void SetUp() override {
ComponentLoader::EnableBackgroundExtensionsForTesting();
PlatformAppBrowserTest::SetUp();
}
void OnAppWindowAdded(AppWindow* app_window) override {
opener_app_ids_.insert(app_window->extension_id());
}
protected:
std::set<std::string> opener_app_ids_;
};
IN_PROC_BROWSER_TEST_F(PlatformAppIncognitoBrowserTest,
DISABLED_IncognitoComponentApp) {
const Extension* file_manager =
extension_registry()->enabled_extensions().GetByID(
extension_misc::kFilesManagerAppId);
ASSERT_TRUE(file_manager != nullptr);
Profile* incognito_profile =
profile()->GetPrimaryOTRProfile(true);
ASSERT_TRUE(incognito_profile != nullptr);
EventRouter* router = EventRouter::Get(incognito_profile);
ASSERT_TRUE(router != nullptr);
while (!router->ExtensionHasEventListener(
file_manager->id(), app_runtime::OnLaunched::kEventName)) {
content::RunAllPendingInMessageLoop();
}
AppWindowRegistry* registry = AppWindowRegistry::Get(incognito_profile);
ASSERT_TRUE(registry != nullptr);
registry->AddObserver(this);
apps::AppServiceProxyFactory::GetForProfile(incognito_profile)
->Launch(file_manager->id(),
apps::GetEventFlags(WindowOpenDisposition::NEW_FOREGROUND_TAB,
true ),
apps::LaunchSource::kFromTest);
while (!base::Contains(opener_app_ids_, file_manager->id())) {
content::RunAllPendingInMessageLoop();
}
}
class RestartKioskDeviceTest : public PlatformAppBrowserTest,
public ash::LocalStateMixin::Delegate {
public:
RestartKioskDeviceTest() { set_chromeos_user_ = false; }
void SetUpLocalState() override {
user_manager::UserManager::Get()->RecordOwner(
AccountId::FromUserEmail("not_current_user@example.com"));
}
void SetUpOnMainThread() override {
PlatformAppBrowserTest::SetUpOnMainThread();
chromeos::FakePowerManagerClient* fake_power_manager_client =
chromeos::FakePowerManagerClient::Get();
ASSERT_NE(nullptr, fake_power_manager_client);
fake_power_manager_client->set_restart_callback(base::DoNothing());
}
protected:
static int num_request_restart_calls() {
return chromeos::FakePowerManagerClient::Get()->num_request_restart_calls();
}
private:
ash::LocalStateMixin local_state_mixin_{&mixin_host_, this};
ash::KioskAppLoggedInBrowserTestMixin login_mixin_{&mixin_host_,
"kiosk-app-account"};
};
IN_PROC_BROWSER_TEST_F(RestartKioskDeviceTest, Restart) {
ASSERT_EQ(0, num_request_restart_calls());
ExtensionTestMessageListener launched_listener("Launched",
ReplyBehavior::kWillReply);
const Extension* extension =
LoadAndLaunchPlatformApp("restart_device", &launched_listener);
ASSERT_TRUE(extension);
launched_listener.Reply("restart");
ExtensionTestMessageListener restart_requested_listener("restartRequested");
ASSERT_TRUE(restart_requested_listener.WaitUntilSatisfied());
EXPECT_EQ(1, num_request_restart_calls());
}
#endif
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, ReinstallDataCleanup) {
std::string extension_id;
{
const Extension* extension =
LoadAndLaunchPlatformApp("reinstall_data_cleanup", "Launched");
ASSERT_TRUE(extension);
extension_id = extension->id();
ResultCatcher result_catcher;
EXPECT_TRUE(result_catcher.GetNextResult());
}
UninstallExtension(extension_id);
content::RunAllPendingInMessageLoop();
{
const Extension* extension =
LoadAndLaunchPlatformApp("reinstall_data_cleanup", "Launched");
ASSERT_TRUE(extension);
ASSERT_EQ(extension_id, extension->id());
ResultCatcher result_catcher;
EXPECT_TRUE(result_catcher.GetNextResult());
}
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, AppsIgnoreDefaultZoom) {
const Extension* extension = LoadAndLaunchPlatformApp("minimal", "Launched");
browser()->profile()->GetZoomLevelPrefs()->SetDefaultZoomLevelPref(1);
ExtensionTestMessageListener launched_listener("Launched");
#if BUILDFLAG(IS_CHROMEOS)
apps::chrome_app_deprecation::ScopedAddAppToAllowlistForTesting allowlist(
extension->id());
#endif
LaunchPlatformApp(extension);
EXPECT_TRUE(launched_listener.WaitUntilSatisfied());
WebContents* web_contents = GetFirstAppWindowWebContents();
content::HostZoomMap* app_host_zoom_map =
content::HostZoomMap::Get(web_contents->GetSiteInstance());
EXPECT_EQ(0, app_host_zoom_map->GetDefaultZoomLevel());
EXPECT_EQ(0, app_host_zoom_map->GetZoomLevel(web_contents));
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, AppWindowIframe) {
LoadAndLaunchPlatformApp("app_window_send_message",
"APP_WINDOW_CREATE_CALLBACK");
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, NewWindowWithNonExistingFile) {
ASSERT_TRUE(
RunExtensionTest("platform_apps/new_window_with_non_existing_file",
{.launch_as_platform_app = true}));
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, SandboxedLocalFile) {
ASSERT_TRUE(RunExtensionTest("platform_apps/sandboxed_local_file",
{.launch_as_platform_app = true}));
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, NewWindowAboutBlank) {
ASSERT_TRUE(RunExtensionTest("platform_apps/new_window_about_blank",
{.launch_as_platform_app = true}));
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
TouchpadPinchSyntheticWheelEvents) {
LoadAndLaunchPlatformApp("touchpad_pinch", "Launched");
WebContents* web_contents = GetFirstAppWindowWebContents();
ASSERT_TRUE(web_contents);
content::MainThreadFrameObserver synchronize_threads(
web_contents->GetRenderWidgetHostView()->GetRenderWidgetHost());
synchronize_threads.Wait();
ExtensionTestMessageListener synthetic_wheel_listener("Seen wheel event");
const gfx::Rect contents_rect = web_contents->GetContainerBounds();
const gfx::Point pinch_position(contents_rect.width() / 2,
contents_rect.height() / 2);
content::SimulateGesturePinchSequence(web_contents, pinch_position, 1.23,
blink::WebGestureDevice::kTouchpad);
ASSERT_TRUE(synthetic_wheel_listener.WaitUntilSatisfied());
}
#if defined(LEAK_SANITIZER)
#define MAYBE_VideoPictureInPicture DISABLED_VideoPictureInPicture
#else
#define MAYBE_VideoPictureInPicture VideoPictureInPicture
#endif
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, MAYBE_VideoPictureInPicture) {
LoadAndLaunchPlatformApp("picture_in_picture", "Launched");
WebContents* web_contents = GetFirstAppWindowWebContents();
ASSERT_TRUE(web_contents);
content::VideoPictureInPictureWindowController* window_controller =
content::PictureInPictureWindowController::
GetOrCreateVideoPictureInPictureController(web_contents);
EXPECT_FALSE(window_controller->GetWindowForTesting());
EXPECT_EQ(true, content::EvalJs(web_contents, "enterPictureInPicture();"));
ASSERT_TRUE(window_controller->GetWindowForTesting());
EXPECT_TRUE(window_controller->GetWindowForTesting()->IsVisible());
EXPECT_EQ(true, content::EvalJs(web_contents, "exitPictureInPicture();"));
EXPECT_FALSE(window_controller->GetWindowForTesting()->IsVisible());
}
}