#include "chrome/browser/web_applications/policy/web_app_policy_manager.h"
#include <memory>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>
#include "base/containers/extend.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/gmock_expected_support.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/web_applications/external_install_options.h"
#include "chrome/browser/web_applications/externally_managed_app_manager.h"
#include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h"
#include "chrome/browser/web_applications/os_integration/os_integration_manager.h"
#include "chrome/browser/web_applications/policy/web_app_policy_constants.h"
#include "chrome/browser/web_applications/test/fake_externally_managed_app_manager.h"
#include "chrome/browser/web_applications/test/fake_web_app_provider.h"
#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h"
#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
#include "chrome/browser/web_applications/test/web_app_test.h"
#include "chrome/browser/web_applications/test/web_app_test_utils.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_command_manager.h"
#include "chrome/browser/web_applications/web_app_helpers.h"
#include "chrome/browser/web_applications/web_app_install_utils.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_registrar_observer.h"
#include "chrome/browser/web_applications/web_app_registry_update.h"
#include "chrome/browser/web_applications/web_app_sync_bridge.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/scoped_testing_local_state.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "components/webapps/browser/install_result_code.h"
#include "components/webapps/common/web_app_id.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkColor.h"
#include "url/gurl.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/constants/ash_features.h"
#include "ash/constants/ash_switches.h"
#include "base/test/scoped_command_line.h"
#include "chrome/browser/ash/crosapi/browser_util.h"
#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/browser/ash/system_web_apps/test_support/test_system_web_app_manager.h"
#include "chromeos/ash/components/standalone_browser/feature_refs.h"
#include "components/user_manager/scoped_user_manager.h"
#include "components/user_manager/user_names.h"
#endif
#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/policy/system_features_disable_list_policy_handler.h"
#include "components/policy/core/common/policy_pref_names.h"
#endif
#if BUILDFLAG(IS_WIN)
#include "base/base_paths_win.h"
#include "base/test/scoped_path_override.h"
#endif
namespace web_app {
namespace {
const char kWebAppSettingWithDefaultConfiguration[] = …;
const char kDefaultFallbackAppName[] = …;
constexpr char kWindowedUrl[] = …;
constexpr char kTabbedUrl[] = …;
constexpr char kNoContainerUrl[] = …;
const char kDefaultCustomAppName[] = …;
constexpr char kDefaultCustomIconUrl[] = …;
constexpr char kUnsecureIconUrl[] = …;
constexpr char kDefaultCustomIconHash[] = …;
base::Value::Dict GetWindowedItem() { … }
ExternalInstallOptions GetWindowedInstallOptions(
PlaceholderResolutionBehavior placeholder_resolution_behavior =
PlaceholderResolutionBehavior::kClose) { … }
base::Value::Dict GetTabbedItem() { … }
ExternalInstallOptions GetTabbedInstallOptions(
PlaceholderResolutionBehavior placeholder_resolution_behavior =
PlaceholderResolutionBehavior::kClose) { … }
base::Value::Dict GetNoContainerItem() { … }
ExternalInstallOptions GetNoContainerInstallOptions(
PlaceholderResolutionBehavior placeholder_resolution_behavior =
PlaceholderResolutionBehavior::kClose) { … }
base::Value::Dict GetCreateDesktopShortcutDefaultItem() { … }
ExternalInstallOptions GetCreateDesktopShortcutDefaultInstallOptions(
PlaceholderResolutionBehavior placeholder_resolution_behavior =
PlaceholderResolutionBehavior::kClose) { … }
base::Value::Dict GetCreateDesktopShortcutFalseItem() { … }
ExternalInstallOptions GetCreateDesktopShortcutFalseInstallOptions(
PlaceholderResolutionBehavior placeholder_resolution_behavior =
PlaceholderResolutionBehavior::kClose) { … }
base::Value::Dict GetCreateDesktopShortcutTrueItem() { … }
ExternalInstallOptions GetCreateDesktopShortcutTrueInstallOptions(
PlaceholderResolutionBehavior placeholder_resolution_behavior =
PlaceholderResolutionBehavior::kClose) { … }
class MockAppRegistrarObserver : public WebAppRegistrarObserver { … };
base::Value::Dict GetFallbackAppNameItem() { … }
ExternalInstallOptions GetFallbackAppNameInstallOptions(
PlaceholderResolutionBehavior placeholder_resolution_behavior =
PlaceholderResolutionBehavior::kClose) { … }
base::Value::Dict GetCustomAppNameItem(std::string name) { … }
ExternalInstallOptions GetCustomAppNameInstallOptions(
std::string name,
PlaceholderResolutionBehavior placeholder_resolution_behavior =
PlaceholderResolutionBehavior::kClose) { … }
base::Value::Dict GetCustomAppIconItem(bool secure = true) { … }
ExternalInstallOptions GetCustomAppIconInstallOptions(
PlaceholderResolutionBehavior placeholder_resolution_behavior =
PlaceholderResolutionBehavior::kClose) { … }
void SetWebAppSettingsListPref(Profile* profile, const std::string_view pref) { … }
void SetWebAppInstallForceListPref(Profile* profile,
const std::string_view pref) { … }
}
class WebAppPolicyManagerTestBase : public ChromeRenderViewHostTestHarness { … };
class WebAppPolicyManagerTest : public WebAppPolicyManagerTestBase,
public testing::WithParamInterface<bool> { … };
TEST_P(WebAppPolicyManagerTest, NoPrefValues) { … }
TEST_P(WebAppPolicyManagerTest, NoForceInstalledApps) { … }
TEST_P(WebAppPolicyManagerTest, NoWebAppSettings) { … }
TEST_P(WebAppPolicyManagerTest, WebAppSettingsInvalidDefaultConfiguration) { … }
TEST_P(WebAppPolicyManagerTest,
WebAppSettingsInvalidDefaultConfigurationWithValidAppPolicy) { … }
TEST_P(WebAppPolicyManagerTest, WebAppSettingsNoDefaultConfiguration) { … }
TEST_P(WebAppPolicyManagerTest, WebAppSettingsWithDefaultConfiguration) { … }
TEST_P(WebAppPolicyManagerTest, TwoForceInstalledApps) { … }
TEST_P(WebAppPolicyManagerTest, ForceInstallAppWithNoDefaultLaunchContainer) { … }
TEST_P(WebAppPolicyManagerTest,
ForceInstallAppWithDefaultCreateDesktopShortcut) { … }
TEST_P(WebAppPolicyManagerTest, ForceInstallAppWithCreateDesktopShortcut) { … }
TEST_P(WebAppPolicyManagerTest, ForceInstallAppWithFallbackAppName) { … }
TEST_P(WebAppPolicyManagerTest, ForceInstallAppWithCustomAppIcon) { … }
TEST_P(WebAppPolicyManagerTest, ForceInstallAppWithUnsecureCustomAppIcon) { … }
TEST_P(WebAppPolicyManagerTest, ForceInstallAppWithCustomAppName) { … }
TEST_P(WebAppPolicyManagerTest, ForceInstallAppWithCustomAppNameRefresh) { … }
TEST_P(WebAppPolicyManagerTest, DynamicRefresh) { … }
TEST_P(WebAppPolicyManagerTest, UninstallAppInstalledInPreviousSession) { … }
TEST_P(WebAppPolicyManagerTest, UninstallAppInstalledInCurrentSession) { … }
TEST_P(WebAppPolicyManagerTest, ReinstallPlaceholderAppSuccess) { … }
TEST_P(WebAppPolicyManagerTest, DoNotReinstallIfNotPlaceholder) { … }
TEST_P(WebAppPolicyManagerTest, ReinstallPlaceholderAppWithFallbackAppName) { … }
TEST_P(WebAppPolicyManagerTest, TryToInexistentPlaceholderApp) { … }
TEST_P(WebAppPolicyManagerTest, SayRefreshTwoTimesQuickly) { … }
TEST_P(WebAppPolicyManagerTest, InstallResultHistogram) { … }
TEST_P(WebAppPolicyManagerTest, InvalidUrlParsingSkipped) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
TEST_P(WebAppPolicyManagerTest, DisableSystemWebApps) {
auto disabled_apps = policy_manager().GetDisabledSystemWebApps();
EXPECT_TRUE(disabled_apps.empty());
testing_local_state_.Get()->SetUserPref(
policy::policy_prefs::kSystemFeaturesDisableList,
base::Value::List()
.Append(static_cast<int>(policy::SystemFeature::kCamera))
.Append(static_cast<int>(policy::SystemFeature::kOsSettings))
.Append(static_cast<int>(policy::SystemFeature::kScanning))
.Append(static_cast<int>(policy::SystemFeature::kExplore))
.Append(static_cast<int>(policy::SystemFeature::kCrosh))
.Append(static_cast<int>(policy::SystemFeature::kTerminal))
.Append(static_cast<int>(policy::SystemFeature::kGallery))
.Append(static_cast<int>(policy::SystemFeature::kPrintJobs))
.Append(static_cast<int>(policy::SystemFeature::kKeyShortcuts))
.Append(static_cast<int>(policy::SystemFeature::kRecorder)));
base::RunLoop().RunUntilIdle();
const std::set<ash::SystemWebAppType> expected_disabled_apps{
ash::SystemWebAppType::CAMERA,
ash::SystemWebAppType::SETTINGS,
ash::SystemWebAppType::SCANNING,
ash::SystemWebAppType::HELP,
ash::SystemWebAppType::CROSH,
ash::SystemWebAppType::TERMINAL,
ash::SystemWebAppType::MEDIA,
ash::SystemWebAppType::PRINT_MANAGEMENT,
ash::SystemWebAppType::SHORTCUT_CUSTOMIZATION,
ash::SystemWebAppType::RECORDER};
disabled_apps = policy_manager().GetDisabledSystemWebApps();
EXPECT_EQ(disabled_apps, expected_disabled_apps);
EXPECT_FALSE(policy_manager().IsDisabledAppsModeHidden());
testing_local_state_.Get()->SetUserPref(
policy::policy_prefs::kSystemFeaturesDisableMode,
base::Value(policy::kHiddenDisableMode));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(policy_manager().IsDisabledAppsModeHidden());
}
#endif
TEST_P(WebAppPolicyManagerTest, WebAppSettingsDynamicRefresh) { … }
TEST_P(WebAppPolicyManagerTest,
WebAppSettingsApplyToExistingForceInstalledApp) { … }
TEST_P(WebAppPolicyManagerTest, WebAppSettingsForceInstallNewApps) { … }
INSTANTIATE_TEST_SUITE_P(…);
class WebAppPolicyManagerPreventCloseTest
: public WebAppPolicyManagerTestBase,
public testing::WithParamInterface<
std::tuple<bool ,
bool >> { … };
TEST_P(WebAppPolicyManagerPreventCloseTest, WebAppSettingsPreventClose) { … }
INSTANTIATE_TEST_SUITE_P(…);
class WebAppPolicyForceUnregistrationTest : public WebAppTest { … };
TEST_F(WebAppPolicyForceUnregistrationTest,
RefreshPolicyTrueRemovesOsIntegration) { … }
TEST_F(WebAppPolicyForceUnregistrationTest,
RefreshPolicyFalseDoesNotRemovesOsIntegration) { … }
TEST_F(WebAppPolicyForceUnregistrationTest,
OtherPoliciesDoNotAffectOsIntegration) { … }
TEST_F(WebAppPolicyForceUnregistrationTest,
ManifestWildcardDoNotAffectOsIntegration) { … }
TEST_F(WebAppPolicyForceUnregistrationTest,
ManifestIdDoesNotExistDoesNotCrash) { … }
TEST_F(WebAppPolicyForceUnregistrationTest,
MultiAppOsIntegrationRemovalBothCorrect) { … }
TEST_F(WebAppPolicyForceUnregistrationTest,
MultiAppOsIntegrationRemovalOneCorrect) { … }
}