blob: 2b2639464836e1e44470ffe22c268013baa705bf [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 "chrome/browser/web_applications/commands/manifest_update_finalize_command.h"
#include <memory>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
#include "chrome/browser/web_applications/commands/web_app_command.h"
#include "chrome/browser/web_applications/locks/app_lock.h"
#include "chrome/browser/web_applications/manifest_update_utils.h"
#include "chrome/browser/web_applications/os_integration/os_integration_manager.h"
#include "chrome/browser/web_applications/web_app_id.h"
#include "chrome/browser/web_applications/web_app_install_finalizer.h"
#include "chrome/browser/web_applications/web_app_install_info.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_sync_bridge.h"
#include "components/keep_alive_registry/scoped_keep_alive.h"
#include "components/webapps/browser/install_result_code.h"
#include "manifest_update_data_fetch_command.h"
namespace web_app {
ManifestUpdateFinalizeCommand::ManifestUpdateFinalizeCommand(
const GURL& url,
const AppId& app_id,
WebAppInstallInfo install_info,
bool app_identity_update_allowed,
ManifestWriteCallback write_callback,
std::unique_ptr<ScopedKeepAlive> keep_alive,
std::unique_ptr<ScopedProfileKeepAlive> profile_keep_alive)
: WebAppCommandTemplate<AppLock>("ManifestUpdateFinalizeCommand"),
lock_description_(std::make_unique<AppLockDescription>(app_id)),
url_(url),
app_id_(app_id),
install_info_(std::move(install_info)),
app_identity_update_allowed_(app_identity_update_allowed),
write_callback_(std::move(write_callback)),
keep_alive_(std::move(keep_alive)),
profile_keep_alive_(std::move(profile_keep_alive)) {}
ManifestUpdateFinalizeCommand::~ManifestUpdateFinalizeCommand() = default;
LockDescription& ManifestUpdateFinalizeCommand::lock_description() const {
return *lock_description_;
}
void ManifestUpdateFinalizeCommand::OnShutdown() {
CompleteCommand(webapps::InstallResultCode::kUpdateTaskFailed,
ManifestUpdateResult::kAppUpdateFailed);
}
base::Value ManifestUpdateFinalizeCommand::ToDebugValue() const {
base::Value::Dict data = debug_log_.Clone();
data.Set("url", url_.spec());
data.Set("app_id", app_id_);
data.Set("stage", base::StreamableToString(stage_));
return base::Value(std::move(data));
}
void ManifestUpdateFinalizeCommand::StartWithLock(
std::unique_ptr<AppLock> lock) {
DCHECK_EQ(stage_, ManifestUpdateStage::kAppWindowsClosed);
lock_ = std::move(lock);
if (!AllowUnpromptedNameUpdate(app_id_, lock_->registrar()) &&
!app_identity_update_allowed_) {
// The app's name must not change due to an automatic update, except for
// default installed apps (that have been vetted).
install_info_.title =
base::UTF8ToUTF16(lock_->registrar().GetAppShortName(app_id_));
}
// Preserve the user's choice of form factor to open the app with.
install_info_.user_display_mode =
lock_->registrar().GetAppUserDisplayMode(app_id_);
stage_ = ManifestUpdateStage::kPendingFinalizerUpdate;
lock_->install_finalizer().FinalizeUpdate(
install_info_,
base::BindOnce(&ManifestUpdateFinalizeCommand::OnInstallationComplete,
AsWeakPtr()));
}
void ManifestUpdateFinalizeCommand::OnInstallationComplete(
const AppId& app_id,
webapps::InstallResultCode code,
OsHooksErrors os_hooks_errors) {
DCHECK_EQ(stage_, ManifestUpdateStage::kPendingFinalizerUpdate);
if (!IsSuccess(code)) {
CompleteCommand(code, ManifestUpdateResult::kAppUpdateFailed);
return;
}
DCHECK_EQ(app_id_, app_id);
DCHECK(
!IsUpdateNeededForManifest(app_id_, install_info_, lock_->registrar()));
DCHECK_EQ(code, webapps::InstallResultCode::kSuccessAlreadyInstalled);
lock_->sync_bridge().SetAppManifestUpdateTime(app_id, base::Time::Now());
CompleteCommand(code, ManifestUpdateResult::kAppUpdated);
}
void ManifestUpdateFinalizeCommand::CompleteCommand(
webapps::InstallResultCode code,
ManifestUpdateResult result) {
debug_log_.Set("installation_code", base::StreamableToString(code));
debug_log_.Set("result", base::StreamableToString(result));
SignalCompletionAndSelfDestruct(
IsSuccess(code) ? CommandResult::kSuccess : CommandResult::kFailure,
base::BindOnce(std::move(write_callback_), url_, app_id_, result));
}
} // namespace web_app