#include "chrome/browser/web_applications/web_app_install_finalizer.h"
#include <map>
#include <utility>
#include "base/barrier_callback.h"
#include "base/check_is_test.h"
#include "base/containers/contains.h"
#include "base/containers/flat_set.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/not_fatal_until.h"
#include "base/notreached.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "base/types/optional_ref.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/web_applications/commands/web_app_uninstall_command.h"
#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_integrity_block_data.h"
#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_storage_location.h"
#include "chrome/browser/web_applications/jobs/uninstall/remove_install_source_job.h"
#include "chrome/browser/web_applications/jobs/uninstall/remove_install_url_job.h"
#include "chrome/browser/web_applications/jobs/uninstall/remove_web_app_job.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/os_integration/web_app_shortcuts_menu.h"
#include "chrome/browser/web_applications/policy/web_app_policy_manager.h"
#include "chrome/browser/web_applications/proto/web_app_install_state.pb.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_constants.h"
#include "chrome/browser/web_applications/web_app_helpers.h"
#include "chrome/browser/web_applications/web_app_icon_generator.h"
#include "chrome/browser/web_applications/web_app_icon_manager.h"
#include "chrome/browser/web_applications/web_app_id_constants.h"
#include "chrome/browser/web_applications/web_app_install_info.h"
#include "chrome/browser/web_applications/web_app_install_manager.h"
#include "chrome/browser/web_applications/web_app_install_utils.h"
#include "chrome/browser/web_applications/web_app_origin_association_manager.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_registry_update.h"
#include "chrome/browser/web_applications/web_app_sync_bridge.h"
#include "chrome/browser/web_applications/web_app_translation_manager.h"
#include "chrome/browser/web_applications/web_app_ui_manager.h"
#include "chrome/browser/web_applications/web_app_utils.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/sync/protocol/web_app_specifics.pb.h"
#include "components/webapps/browser/uninstall_result_code.h"
#include "components/webapps/common/web_app_id.h"
#include "content/public/browser/browser_thread.h"
#include "third_party/skia/include/core/SkColor.h"
#include "url/origin.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ash/system_web_apps/types/system_web_app_data.h"
#endif
namespace web_app {
namespace {
bool ShouldInstallOverwriteUserDisplayMode(
webapps::WebappInstallSource source) { … }
#if BUILDFLAG(IS_CHROMEOS)
void ApplyUserDisplayModeSyncMitigations(
const WebAppInstallFinalizer::FinalizeOptions& options,
WebApp& web_app) {
CHECK(web_app.sync_proto().has_user_display_mode_cros(),
base::NotFatalUntil::M125);
if (options.install_surface == webapps::WebappInstallSource::SYNC) {
return;
}
if (options.source != WebAppManagement::Type::kSync) {
return;
}
if (web_app.sync_proto().has_user_display_mode_default()) {
return;
}
sync_pb::WebAppSpecifics sync_proto = web_app.sync_proto();
switch (web_app.sync_proto().user_display_mode_cros()) {
case sync_pb::WebAppSpecifics_UserDisplayMode_BROWSER:
if (!base::FeatureList::IsEnabled(
kUserDisplayModeSyncBrowserMitigation)) {
return;
}
sync_proto.set_user_display_mode_default(
sync_pb::WebAppSpecifics_UserDisplayMode_BROWSER);
break;
case sync_pb::WebAppSpecifics_UserDisplayMode_STANDALONE: {
if (!base::FeatureList::IsEnabled(
kUserDisplayModeSyncStandaloneMitigation)) {
return;
}
bool is_standalone_averse_app = web_app.app_id() == kGoogleDocsAppId ||
web_app.app_id() == kGoogleSheetsAppId ||
web_app.app_id() == kGoogleSlidesAppId;
if (!is_standalone_averse_app) {
break;
}
sync_proto.set_user_display_mode_default(
sync_pb::WebAppSpecifics_UserDisplayMode_BROWSER);
break;
}
case sync_pb::WebAppSpecifics_UserDisplayMode_TABBED:
return;
case sync_pb::WebAppSpecifics_UserDisplayMode_UNSPECIFIED:
return;
}
web_app.SetSyncProto(std::move(sync_proto));
}
#endif
}
WebAppInstallFinalizer::FinalizeOptions::IwaOptions::IwaOptions(
IsolatedWebAppStorageLocation location,
std::optional<IsolatedWebAppIntegrityBlockData> integrity_block_data)
: … { … }
WebAppInstallFinalizer::FinalizeOptions::IwaOptions::~IwaOptions() = default;
WebAppInstallFinalizer::FinalizeOptions::IwaOptions::IwaOptions(
const IwaOptions&) = default;
WebAppInstallFinalizer::FinalizeOptions::FinalizeOptions(
webapps::WebappInstallSource install_surface)
: … { … }
WebAppInstallFinalizer::FinalizeOptions::~FinalizeOptions() = default;
WebAppInstallFinalizer::FinalizeOptions::FinalizeOptions(
const FinalizeOptions&) = default;
WebAppInstallFinalizer::WebAppInstallFinalizer(Profile* profile)
: … { … }
WebAppInstallFinalizer::~WebAppInstallFinalizer() = default;
void WebAppInstallFinalizer::FinalizeInstall(
const WebAppInstallInfo& web_app_info,
const FinalizeOptions& options,
InstallFinalizedCallback callback) { … }
void WebAppInstallFinalizer::OnOriginAssociationValidated(
WebAppInstallInfo web_app_info,
FinalizeOptions options,
InstallFinalizedCallback callback,
webapps::AppId app_id,
ScopeExtensions validated_scope_extensions) { … }
bool WebAppInstallFinalizer::CanReparentTab(const webapps::AppId& app_id,
bool shortcut_created) const { … }
void WebAppInstallFinalizer::ReparentTab(const webapps::AppId& app_id,
bool shortcut_created,
content::WebContents* web_contents) { … }
void WebAppInstallFinalizer::FinalizeUpdate(
const WebAppInstallInfo& web_app_info,
InstallFinalizedCallback callback) { … }
void WebAppInstallFinalizer::SetProvider(base::PassKey<WebAppProvider>,
WebAppProvider& provider) { … }
void WebAppInstallFinalizer::Start() { … }
void WebAppInstallFinalizer::Shutdown() { … }
void WebAppInstallFinalizer::UpdateIsolationDataAndResetPendingUpdateInfo(
WebApp* web_app,
const IsolatedWebAppStorageLocation& location,
const base::Version& version,
std::optional<IsolatedWebAppIntegrityBlockData> integrity_block_data) { … }
void WebAppInstallFinalizer::SetWebAppManifestFieldsAndWriteData(
const WebAppInstallInfo& web_app_info,
std::unique_ptr<WebApp> web_app,
CommitCallback commit_callback,
bool skip_icon_writes_on_download_failure) { … }
void WebAppInstallFinalizer::WriteTranslations(
const webapps::AppId& app_id,
const base::flat_map<std::string, blink::Manifest::TranslationItem>&
translations,
CommitCallback commit_callback,
bool success) { … }
void WebAppInstallFinalizer::CommitToSyncBridge(std::unique_ptr<WebApp> web_app,
CommitCallback commit_callback,
bool success) { … }
void WebAppInstallFinalizer::OnDatabaseCommitCompletedForInstall(
InstallFinalizedCallback callback,
webapps::AppId app_id,
FinalizeOptions finalize_options,
bool success) { … }
void WebAppInstallFinalizer::OnInstallHooksFinished(
InstallFinalizedCallback callback,
webapps::AppId app_id) { … }
void WebAppInstallFinalizer::NotifyWebAppInstalledWithOsHooks(
webapps::AppId app_id) { … }
bool WebAppInstallFinalizer::ShouldUpdateOsHooks(const webapps::AppId& app_id) { … }
void WebAppInstallFinalizer::OnDatabaseCommitCompletedForUpdate(
InstallFinalizedCallback callback,
webapps::AppId app_id,
std::string old_name,
FileHandlerUpdateAction file_handlers_need_os_update,
const WebAppInstallInfo& web_app_info,
bool success) { … }
void WebAppInstallFinalizer::OnUpdateHooksFinished(
InstallFinalizedCallback callback,
webapps::AppId app_id) { … }
void WebAppInstallFinalizer::WriteExternalConfigMapInfo(
WebApp& web_app,
WebAppManagement::Type source,
bool is_placeholder,
GURL install_url,
std::vector<std::string> additional_policy_ids) { … }
FileHandlerUpdateAction WebAppInstallFinalizer::GetFileHandlerUpdateAction(
const webapps::AppId& app_id,
const WebAppInstallInfo& new_web_app_info) { … }
}