blob: 095cf3a5473a5e8a76ba1cc770cbc4d4b1fa0bc7 [file] [log] [blame]
// 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/apps/app_service/launch_utils.h"
#include "build/build_config.h"
#include "chrome/browser/apps/app_service/app_launch_params.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/testing_profile.h"
#include "components/services/app_service/public/cpp/intent_util.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/display/types/display_constants.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "chromeos/crosapi/mojom/app_service_types.mojom.h"
#endif // BUILDFLAG(IS_CHROMEOS)
class LaunchUtilsTest : public testing::Test {
protected:
apps::AppLaunchParams CreateLaunchParams(
apps::mojom::LaunchContainer container,
WindowOpenDisposition disposition,
bool preferred_container,
apps::mojom::LaunchContainer fallback_container =
apps::mojom::LaunchContainer::kLaunchContainerNone) {
return apps::CreateAppIdLaunchParamsWithEventFlags(
app_id,
apps::GetEventFlags(container, disposition, preferred_container),
apps::mojom::LaunchSource::kFromChromeInternal,
display::kInvalidDisplayId, fallback_container);
}
std::string app_id = "aaa";
content::BrowserTaskEnvironment task_environment_;
TestingProfile profile_;
};
TEST_F(LaunchUtilsTest, WindowContainerAndWindowDisposition) {
auto container = apps::mojom::LaunchContainer::kLaunchContainerWindow;
auto disposition = WindowOpenDisposition::NEW_WINDOW;
auto params = CreateLaunchParams(container, disposition, false);
EXPECT_EQ(container, params.container);
EXPECT_EQ(disposition, params.disposition);
}
TEST_F(LaunchUtilsTest, TabContainerAndForegoundTabDisposition) {
auto container = apps::mojom::LaunchContainer::kLaunchContainerTab;
auto disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
auto params = CreateLaunchParams(container, disposition, false);
EXPECT_EQ(container, params.container);
EXPECT_EQ(disposition, params.disposition);
}
TEST_F(LaunchUtilsTest, TabContainerAndBackgoundTabDisposition) {
auto container = apps::mojom::LaunchContainer::kLaunchContainerTab;
auto disposition = WindowOpenDisposition::NEW_BACKGROUND_TAB;
auto params = CreateLaunchParams(container, disposition, false);
EXPECT_EQ(container, params.container);
EXPECT_EQ(disposition, params.disposition);
}
TEST_F(LaunchUtilsTest, PreferContainerWithTab) {
auto container = apps::mojom::LaunchContainer::kLaunchContainerNone;
auto disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
auto preferred_container =
apps::mojom::LaunchContainer::kLaunchContainerWindow;
auto params =
CreateLaunchParams(container, disposition, true, preferred_container);
EXPECT_EQ(preferred_container, params.container);
EXPECT_EQ(disposition, params.disposition);
}
TEST_F(LaunchUtilsTest, PreferContainerWithWindow) {
auto container = apps::mojom::LaunchContainer::kLaunchContainerNone;
auto disposition = WindowOpenDisposition::NEW_WINDOW;
auto preferred_container =
apps::mojom::LaunchContainer::kLaunchContainerWindow;
auto params =
CreateLaunchParams(container, disposition, true, preferred_container);
EXPECT_EQ(preferred_container, params.container);
EXPECT_EQ(WindowOpenDisposition::NEW_FOREGROUND_TAB, params.disposition);
}
TEST_F(LaunchUtilsTest, UseIntentFullUrlInLaunchParams) {
auto container = apps::mojom::LaunchContainer::kLaunchContainerNone;
auto disposition = WindowOpenDisposition::NEW_WINDOW;
const GURL url = GURL("https://example.com/?query=1#frag");
auto intent = apps_util::CreateIntentFromUrl(url);
auto params = apps::CreateAppLaunchParamsForIntent(
app_id, apps::GetEventFlags(container, disposition, true),
apps::mojom::LaunchSource::kFromChromeInternal,
display::kInvalidDisplayId,
apps::mojom::LaunchContainer::kLaunchContainerWindow, std::move(intent),
&profile_);
EXPECT_EQ(url, params.override_url);
}
TEST_F(LaunchUtilsTest, IntentFilesAreCopiedToLaunchParams) {
auto container = apps::mojom::LaunchContainer::kLaunchContainerNone;
auto disposition = WindowOpenDisposition::NEW_WINDOW;
std::vector<apps::mojom::IntentFilePtr> files;
auto file = apps::mojom::IntentFile::New();
std::string file_path = "filesystem:http://foo.com/test/foo.txt";
file->url = GURL(file_path);
EXPECT_TRUE(file->url.is_valid());
file->mime_type = "text/plain";
files.push_back(std::move(file));
auto intent = apps_util::CreateViewIntentFromFiles(std::move(files));
auto params = apps::CreateAppLaunchParamsForIntent(
app_id, apps::GetEventFlags(container, disposition, true),
apps::mojom::LaunchSource::kFromChromeInternal,
display::kInvalidDisplayId,
apps::mojom::LaunchContainer::kLaunchContainerWindow, std::move(intent),
&profile_);
#if BUILDFLAG(IS_CHROMEOS_ASH)
ASSERT_EQ(params.launch_files.size(), 1U);
EXPECT_EQ("foo.txt", params.launch_files[0].MaybeAsASCII());
#else
ASSERT_EQ(params.launch_files.size(), 0U);
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
}
TEST_F(LaunchUtilsTest, GetLaunchFilesFromCommandLine_NoAppID) {
// Validate an empty vector is returned if there is
// no AppID specified on the command line.
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
std::vector<base::FilePath> launch_files =
apps::GetLaunchFilesFromCommandLine(command_line);
EXPECT_EQ(launch_files.size(), 0U);
}
TEST_F(LaunchUtilsTest, GetLaunchFilesFromCommandLine_NoFiles) {
// Validate an empty vector is returned if there are
// no files specified on the command line.
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
command_line.AppendSwitchASCII(switches::kAppId, "test");
std::vector<base::FilePath> launch_files =
apps::GetLaunchFilesFromCommandLine(command_line);
EXPECT_EQ(launch_files.size(), 0U);
}
TEST_F(LaunchUtilsTest, GetLaunchFilesFromCommandLine_SingleFile) {
// Validate a vector with size 1 is returned, and the
// contents match the command line parameter.
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
command_line.AppendSwitchASCII(switches::kAppId, "test");
command_line.AppendArg("filename");
std::vector<base::FilePath> launch_files =
apps::GetLaunchFilesFromCommandLine(command_line);
ASSERT_EQ(launch_files.size(), 1U);
EXPECT_EQ(launch_files[0], base::FilePath(FILE_PATH_LITERAL("filename")));
}
TEST_F(LaunchUtilsTest, GetLaunchFilesFromCommandLine_MultipleFiles) {
// Validate a vector with size 2 is returned, and the
// contents match the command line parameter.
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
command_line.AppendSwitchASCII(switches::kAppId, "test");
command_line.AppendArg("filename");
command_line.AppendArg("filename2");
std::vector<base::FilePath> launch_files =
apps::GetLaunchFilesFromCommandLine(command_line);
ASSERT_EQ(launch_files.size(), 2U);
EXPECT_EQ(launch_files[0], base::FilePath(FILE_PATH_LITERAL("filename")));
EXPECT_EQ(launch_files[1], base::FilePath(FILE_PATH_LITERAL("filename2")));
}
TEST_F(LaunchUtilsTest, GetLaunchFilesFromCommandLine_FileProtocol) {
// Validate a vector with size 1 is returned, and the
// contents match the command line parameter. This uses
// the file protocol to reference the file.
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
command_line.AppendSwitchASCII(switches::kAppId, "test");
command_line.AppendArg("file://filename");
std::vector<base::FilePath> launch_files =
apps::GetLaunchFilesFromCommandLine(command_line);
ASSERT_EQ(launch_files.size(), 1U);
EXPECT_EQ(launch_files[0],
base::FilePath(FILE_PATH_LITERAL("file://filename")));
}
// Verifies that a non-file protocol is not treated as a filename.
TEST_F(LaunchUtilsTest, GetLaunchFilesFromCommandLine_CustomProtocol) {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
command_line.AppendSwitchASCII(switches::kAppId, "test");
command_line.AppendArg("web+test://filename");
std::vector<base::FilePath> launch_files =
apps::GetLaunchFilesFromCommandLine(command_line);
EXPECT_EQ(0U, launch_files.size());
}
#if BUILDFLAG(IS_CHROMEOS)
// Verifies that convert params (with no override url, intent, files) to crosapi
// and back works.
TEST_F(LaunchUtilsTest, ConvertToCrosapi) {
auto container = apps::mojom::LaunchContainer::kLaunchContainerWindow;
auto disposition = WindowOpenDisposition::NEW_WINDOW;
auto params = CreateLaunchParams(container, disposition, false);
auto crosapi_params = apps::ConvertLaunchParamsToCrosapi(params, &profile_);
auto converted_params =
apps::ConvertCrosapiToLaunchParams(crosapi_params, &profile_);
EXPECT_EQ(params.app_id, converted_params.app_id);
EXPECT_EQ(params.container, converted_params.container);
EXPECT_EQ(params.disposition, converted_params.disposition);
EXPECT_EQ(params.launch_source, converted_params.launch_source);
}
// Verifies that convert params with override url to crosapi and back works.
TEST_F(LaunchUtilsTest, ConvertToCrosapiUrl) {
auto container = apps::mojom::LaunchContainer::kLaunchContainerWindow;
auto disposition = WindowOpenDisposition::NEW_WINDOW;
auto params = CreateLaunchParams(container, disposition, false);
params.override_url = GURL("abc.example.com");
auto crosapi_params = apps::ConvertLaunchParamsToCrosapi(params, &profile_);
auto converted_params =
apps::ConvertCrosapiToLaunchParams(crosapi_params, &profile_);
EXPECT_EQ(params.app_id, converted_params.app_id);
EXPECT_EQ(params.container, converted_params.container);
EXPECT_EQ(params.disposition, converted_params.disposition);
EXPECT_EQ(params.launch_source, converted_params.launch_source);
EXPECT_EQ(params.override_url, converted_params.override_url);
}
// Verifies that convert params with files to crosapi and back works.
TEST_F(LaunchUtilsTest, ConvertToCrosapiFiles) {
auto container = apps::mojom::LaunchContainer::kLaunchContainerWindow;
auto disposition = WindowOpenDisposition::NEW_WINDOW;
auto params = CreateLaunchParams(container, disposition, false);
params.launch_files.push_back(base::FilePath("root"));
auto crosapi_params = apps::ConvertLaunchParamsToCrosapi(params, &profile_);
auto converted_params =
apps::ConvertCrosapiToLaunchParams(crosapi_params, &profile_);
EXPECT_EQ(params.app_id, converted_params.app_id);
EXPECT_EQ(params.container, converted_params.container);
EXPECT_EQ(params.disposition, converted_params.disposition);
EXPECT_EQ(params.launch_source, converted_params.launch_source);
EXPECT_EQ(params.launch_files, converted_params.launch_files);
}
// Verifies that convert params with intent to crosapi and back works.
TEST_F(LaunchUtilsTest, ConvertToCrosapiIntent) {
auto container = apps::mojom::LaunchContainer::kLaunchContainerWindow;
auto disposition = WindowOpenDisposition::NEW_WINDOW;
auto params = CreateLaunchParams(container, disposition, false);
params.intent = apps_util::CreateIntentFromUrl(GURL("abc.example.com"));
auto crosapi_params = apps::ConvertLaunchParamsToCrosapi(params, &profile_);
auto converted_params =
apps::ConvertCrosapiToLaunchParams(crosapi_params, &profile_);
EXPECT_EQ(params.app_id, converted_params.app_id);
EXPECT_EQ(params.container, converted_params.container);
EXPECT_EQ(params.disposition, converted_params.disposition);
EXPECT_EQ(apps::mojom::LaunchSource::kFromIntentUrl,
converted_params.launch_source);
EXPECT_EQ(params.intent, converted_params.intent);
}
// Verifies that convert params from crosapi with incomplete params works.
TEST_F(LaunchUtilsTest, FromCrosapiIncomplete) {
auto params = crosapi::mojom::LaunchParams::New();
params->app_id = "aaaa";
params->launch_source = apps::mojom::LaunchSource::kFromIntentUrl;
auto converted_params = apps::ConvertCrosapiToLaunchParams(params, &profile_);
EXPECT_EQ(params->app_id, converted_params.app_id);
EXPECT_EQ(apps::mojom::LaunchContainer::kLaunchContainerNone,
converted_params.container);
EXPECT_EQ(WindowOpenDisposition::UNKNOWN, converted_params.disposition);
EXPECT_EQ(apps::mojom::LaunchSource::kFromIntentUrl,
converted_params.launch_source);
}
#if BUILDFLAG(IS_CHROMEOS_LACROS)
TEST_F(LaunchUtilsTest, FromCrosapiIntent) {
constexpr char kIntentMimeType[] = "image/*";
constexpr char kShareText[] = "Message";
constexpr char kFilePath[] = "/tmp/picture.png";
constexpr char kFileMimeType[] = "image/png";
constexpr char kBaseName[] = "picture.png";
crosapi::mojom::LaunchParamsPtr crosapi_params =
crosapi::mojom::LaunchParams::New();
crosapi_params->container =
crosapi::mojom::LaunchContainer::kLaunchContainerWindow;
crosapi_params->disposition =
crosapi::mojom::WindowOpenDisposition::kNewForegroundTab;
crosapi_params->launch_source = apps::mojom::LaunchSource::kFromSharesheet;
crosapi_params->intent = crosapi::mojom::Intent::New();
crosapi_params->intent->action = apps_util::kIntentActionSend;
crosapi_params->intent->mime_type = kIntentMimeType;
crosapi_params->intent->share_text = kShareText;
{
std::vector<crosapi::mojom::IntentFilePtr> crosapi_files;
auto crosapi_file = crosapi::mojom::IntentFile::New();
crosapi_file->file_path = base::FilePath(kFilePath);
crosapi_file->mime_type = kFileMimeType;
crosapi_files.push_back(std::move(crosapi_file));
crosapi_params->intent->files = std::move(crosapi_files);
}
auto converted_params =
apps::ConvertCrosapiToLaunchParams(crosapi_params, &profile_);
EXPECT_EQ(converted_params.container,
apps::mojom::LaunchContainer::kLaunchContainerWindow);
EXPECT_EQ(converted_params.disposition,
WindowOpenDisposition::NEW_FOREGROUND_TAB);
EXPECT_EQ(converted_params.launch_source,
apps::mojom::LaunchSource::kFromSharesheet);
EXPECT_EQ(converted_params.launch_files.size(), 1U);
EXPECT_EQ(converted_params.launch_files[0], base::FilePath(kFilePath));
EXPECT_EQ(converted_params.intent->action, apps_util::kIntentActionSend);
EXPECT_EQ(converted_params.intent->mime_type, kIntentMimeType);
EXPECT_EQ(converted_params.intent->share_text, kShareText);
EXPECT_EQ(converted_params.intent->files->size(), 1U);
EXPECT_EQ((*converted_params.intent->files)[0]->file_name,
base::SafeBaseName::Create(kBaseName));
EXPECT_EQ((*converted_params.intent->files)[0]->mime_type, kFileMimeType);
}
#endif // BUILDFLAG(IS_CHROMEOS_LACROS)
#endif // BUILDFLAG(IS_CHROMEOS)