blob: 4cbfabd5c836f5f546a6d9ff3065c9d86f53c359 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <vector>
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_keeplist_chromeos.h"
#include "chrome/browser/lacros/browser_test_util.h"
#include "chrome/browser/lacros/for_which_extension_type.h"
#include "chrome/browser/lacros/lacros_extension_apps_controller.h"
#include "chrome/browser/lacros/lacros_extension_apps_publisher.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chromeos/lacros/lacros_test_helper.h"
#include "chromeos/startup/browser_params_proxy.h"
#include "content/public/test/browser_test.h"
#include "extension_keeplist_chromeos.h"
#include "extensions/browser/app_window/app_window.h"
#include "extensions/browser/app_window/app_window_registry.h"
namespace extensions {
class LacrosExtensionKeeplistTest : public ExtensionApiTest {
public:
void SetUpOnMainThread() override {
ExtensionApiTest::SetUpOnMainThread();
ash_keeplist_browser_init_params_supported_ =
!chromeos::BrowserParamsProxy::Get()->ExtensionKeepList().is_null();
}
protected:
bool AshKeeplistFromBrowserInitParamsSupported() {
return ash_keeplist_browser_init_params_supported_;
}
private:
bool ash_keeplist_browser_init_params_supported_ = false;
};
// Test the Ash extension keeplist data in Lacros against Ash versions that
// support passing Ash extension keep list to Lacros with
// crosapi::mojom::BrowserInitParams.
IN_PROC_BROWSER_TEST_F(LacrosExtensionKeeplistTest,
AshKeeplistFromBrowserInitParamsSupported) {
// This test does not apply to unsupported ash version.
if (!AshKeeplistFromBrowserInitParamsSupported()) {
GTEST_SKIP();
}
// For Ash running in the version that supports passing Ash extension keep
// list to Lacros with crosapi::mojom::BrowserInitParams, just do some minimum
// sanity check to make sure the extension list passed from Ash is not empty.
// We have a more sophiscaited test in extension_keeplist_ash_browsertest.cc
// to verify the keep lists are idnetical in Ash and Lacros for such case.
EXPECT_FALSE(extensions::GetExtensionsRunInOSAndStandaloneBrowser().empty());
EXPECT_FALSE(
extensions::GetExtensionAppsRunInOSAndStandaloneBrowser().empty());
EXPECT_FALSE(extensions::GetExtensionsRunInOSOnly().empty());
EXPECT_FALSE(extensions::GetExtensionAppsRunInOSOnly().empty());
}
// Test the Ash extension keeplist data in Lacros against older Ash versions
// that do NOT support passing Ash extension keep list to Lacros with
// crosapi::mojom::BrowserInitParams.
IN_PROC_BROWSER_TEST_F(LacrosExtensionKeeplistTest,
AshKeeplistFromBrowserInitParamsNotSupported) {
// This test only applies to older ash version which does not support
// passing Ash extension keeplist data via crosapi::mojom::BrowserInitParams.
if (AshKeeplistFromBrowserInitParamsSupported()) {
GTEST_SKIP();
}
// Verify that Lacros uses the static compiled ash extension keep list.
// This tests the backward compatibility support of ash extension keeplist.
ASSERT_EQ(extensions::GetExtensionsRunInOSAndStandaloneBrowser().size(),
ExtensionsRunInOSAndStandaloneBrowserAllowlistSizeForTest());
ASSERT_EQ(extensions::GetExtensionAppsRunInOSAndStandaloneBrowser().size(),
ExtensionAppsRunInOSAndStandaloneBrowserAllowlistSizeForTest());
ASSERT_EQ(extensions::GetExtensionsRunInOSOnly().size(),
ExtensionsRunInOSOnlyAllowlistSizeForTest());
ASSERT_EQ(extensions::GetExtensionAppsRunInOSOnly().size(),
ExtensionAppsRunInOSOnlyAllowlistSizeForTest());
}
class ExtensionAppsAppServiceBlocklistTest
: public extensions::ExtensionBrowserTest {
public:
void InstallFakeGnubbydApp() {
DCHECK(gnubbyd_app_id_.empty());
const extensions::Extension* extension = LoadExtension(
test_data_dir_.AppendASCII("ash_extension_keeplist/fake_gnubbyd_app"));
gnubbyd_app_id_ = extension->id();
EXPECT_EQ(gnubbyd_app_id_, extension_misc::kGnubbyAppId);
}
void InstallFakeGCSEExtension() {
DCHECK(!gcse_extension_);
gcse_extension_ = LoadExtension(test_data_dir_.AppendASCII(
"ash_extension_keeplist/fake_GCSE_extension"));
EXPECT_EQ(gcse_extension_->id(), extension_misc::kGCSEExtensionId);
}
const std::string& gnubbyd_app_id() const { return gnubbyd_app_id_; }
const extensions::Extension* gcse_extension() { return gcse_extension_; }
private:
// extensions::ExtensionBrowserTest:
void TearDownOnMainThread() override {
CloseAllAppWindows();
extensions::ExtensionBrowserTest::TearDownOnMainThread();
}
void CloseAllAppWindows() {
for (extensions::AppWindow* app_window :
extensions::AppWindowRegistry::Get(profile())->app_windows()) {
app_window->GetBaseWindow()->Close();
}
// Wait for item to stop existing in shelf.
if (!gnubbyd_app_id_.empty()) {
ASSERT_TRUE(browser_test_util::WaitForShelfItem(gnubbyd_app_id_,
/*exists=*/false));
}
}
std::string gnubbyd_app_id_;
const extensions::Extension* gcse_extension_ = nullptr;
};
// This tests publishing and launching gnubbyd app (running in both ash and
// lacros) with app service. It installs a fake gnubbyd app to simulate the test
// case.
// TODO(crbug.com/1409199): Remove the fake gnubbyd app, and configure ash with
// a testing app to exercise the test case.
IN_PROC_BROWSER_TEST_F(ExtensionAppsAppServiceBlocklistTest,
GnubbydAppLaunchInAppList) {
if (!extensions::IsAppServiceBlocklistCrosapiSupported()) {
GTEST_SKIP() << "Unsupported ash version";
}
// Create the controller and publisher.
std::unique_ptr<LacrosExtensionAppsPublisher> publisher =
LacrosExtensionAppsPublisher::MakeForChromeApps();
publisher->Initialize();
std::unique_ptr<LacrosExtensionAppsController> controller =
LacrosExtensionAppsController::MakeForChromeApps();
controller->Initialize(publisher->publisher());
InstallFakeGnubbydApp();
EXPECT_TRUE(extensions::ExtensionAppRunsInBothOSAndStandaloneBrowser(
gnubbyd_app_id()));
EXPECT_FALSE(
extensions::ExtensionAppBlockListedForAppServiceInStandaloneBrowser(
gnubbyd_app_id()));
// Gnubbyd item should not exist in the shelf before the app is launched.
ASSERT_TRUE(
browser_test_util::WaitForShelfItem(gnubbyd_app_id(), /*exists=*/false));
// There should be no app windows.
ASSERT_TRUE(
extensions::AppWindowRegistry::Get(profile())->app_windows().empty());
// The fake gnubbyd app should have been published in app service by lacros,
// and can be launched from app list.
chromeos::LacrosService::Get()
->GetRemote<crosapi::mojom::TestController>()
->LaunchAppFromAppList(gnubbyd_app_id());
// Wait for item to exist in shelf.
ASSERT_TRUE(
browser_test_util::WaitForShelfItem(gnubbyd_app_id(), /*exists=*/true));
}
// This tests the backward compatibility for gnubbyd app with older ash which
// does not supports app list block list. It installs a fake gnubbyd app to
// simulate the test case.
// TODO(crbug.com/1409199): Remove the fake gnubbyd app, and configure ash
// with a testing app to exercise the test case.
IN_PROC_BROWSER_TEST_F(ExtensionAppsAppServiceBlocklistTest,
GnubbydAppNotLaunchInAppList) {
if (extensions::IsAppServiceBlocklistCrosapiSupported()) {
GTEST_SKIP()
<< "This test should not run with the new ash supporting app service "
"block list";
}
// Create the controller and publisher.
std::unique_ptr<LacrosExtensionAppsPublisher> publisher =
LacrosExtensionAppsPublisher::MakeForChromeApps();
publisher->Initialize();
std::unique_ptr<LacrosExtensionAppsController> controller =
LacrosExtensionAppsController::MakeForChromeApps();
controller->Initialize(publisher->publisher());
InstallFakeGnubbydApp();
EXPECT_TRUE(extensions::ExtensionAppRunsInBothOSAndStandaloneBrowser(
gnubbyd_app_id()));
// No gnubbyd app item should exist in the shelf before the window is
// launched.
ASSERT_TRUE(
browser_test_util::WaitForShelfItem(gnubbyd_app_id(), /*exists=*/false));
// There should be no app windows.
ASSERT_TRUE(
extensions::AppWindowRegistry::Get(profile())->app_windows().empty());
chromeos::LacrosService::Get()
->GetRemote<crosapi::mojom::TestController>()
->LaunchAppFromAppList(gnubbyd_app_id());
// With the older ash which does not support app service block list, gnubbyd
// app should not be published in app service, and can't be launched in app
// list.
// No gnubbyd item should exist in the shelf.
ASSERT_TRUE(
browser_test_util::WaitForShelfItem(gnubbyd_app_id(), /*exists=*/false));
// There should be no app windows.
ASSERT_TRUE(
extensions::AppWindowRegistry::Get(profile())->app_windows().empty());
}
// This tests the GCSE extension (running in both ash and lacros) should be
// rejected by ForWhichExtensionType, i.e., returning false for Matches()), with
// ash which supports app service block list.
// TODO(crbug.com/1409199): Remove the fake GCSE extension, and configure ash
// with a testing extension to exercise the test case.
IN_PROC_BROWSER_TEST_F(ExtensionAppsAppServiceBlocklistTest,
GCSEExtensionNotMatchWithBlocklistSupport) {
if (!extensions::IsAppServiceBlocklistCrosapiSupported()) {
GTEST_SKIP() << "Test should not run with old ash version";
}
ForWhichExtensionType for_which_type =
ForWhichExtensionType(InitForExtensions());
InstallFakeGCSEExtension();
EXPECT_TRUE(extensions::ExtensionRunsInBothOSAndStandaloneBrowser(
gcse_extension()->id()));
EXPECT_FALSE(for_which_type.Matches(gcse_extension()));
}
// This tests the GCSE extension (running in both ash and lacros) should be
// rejected by ForWhichExtensionType, i.e., returning false for Matches()), with
// the older ash which does not support app service block list.
// This verifies the fix for crbug.com/1408982.
// TODO(crbug.com/1409199): Remove the fake GCSE extension, and configure ash
// with a testing extension to exercise the test case.
IN_PROC_BROWSER_TEST_F(ExtensionAppsAppServiceBlocklistTest,
GCSEExtensionNotMatchWithoutBlocklistSupport) {
if (extensions::IsAppServiceBlocklistCrosapiSupported()) {
GTEST_SKIP() << "Test should not run with new ash version";
}
ForWhichExtensionType for_which_type =
ForWhichExtensionType(InitForExtensions());
InstallFakeGCSEExtension();
EXPECT_TRUE(extensions::ExtensionRunsInBothOSAndStandaloneBrowser(
gcse_extension()->id()));
EXPECT_FALSE(for_which_type.Matches(gcse_extension()));
}
} // namespace extensions