blob: 50f597877b96ca29e7810417664a846536256df3 [file] [log] [blame]
// Copyright 2023 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/install_placeholder_command.h"
#include <memory>
#include <utility>
#include "base/functional/bind.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/web_applications/external_install_options.h"
#include "chrome/browser/web_applications/jobs/uninstall/web_app_uninstall_and_replace_job.h"
#include "chrome/browser/web_applications/locks/shared_web_contents_with_app_lock.h"
#include "chrome/browser/web_applications/web_app_helpers.h"
#include "chrome/browser/web_applications/web_app_install_finalizer.h"
#include "chrome/browser/web_applications/web_contents/web_app_data_retriever.h"
#include "components/webapps/browser/install_result_code.h"
namespace web_app {
InstallPlaceholderCommand::InstallPlaceholderCommand(
Profile* profile,
const ExternalInstallOptions& install_options,
InstallAndReplaceCallback callback)
: WebAppCommandTemplate<SharedWebContentsWithAppLock>(
"InstallPlaceholderCommand"),
profile_(profile),
// For placeholder installs, the install_url is treated as the start_url.
app_id_(GenerateAppIdFromManifestId(
GenerateManifestIdFromStartUrlOnly(install_options.install_url))),
lock_description_(
std::make_unique<SharedWebContentsWithAppLockDescription>(
base::flat_set<webapps::AppId>{app_id_})),
install_options_(install_options),
callback_(std::move(callback)) {}
InstallPlaceholderCommand::~InstallPlaceholderCommand() = default;
void InstallPlaceholderCommand::StartWithLock(
std::unique_ptr<SharedWebContentsWithAppLock> lock) {
lock_ = std::move(lock);
install_placeholder_job_.emplace(
profile_.get(), install_options_,
base::BindOnce(&InstallPlaceholderCommand::OnPlaceholderInstalled,
weak_factory_.GetWeakPtr()),
*lock_);
if (data_retriever_for_testing_) {
install_placeholder_job_->SetDataRetrieverForTesting(
std::move(data_retriever_for_testing_));
}
install_placeholder_job_->Start();
}
const LockDescription& InstallPlaceholderCommand::lock_description() const {
return *lock_description_;
}
base::Value InstallPlaceholderCommand::ToDebugValue() const {
base::Value::Dict dict;
dict.Set("install_placeholder_job",
install_placeholder_job_ ? install_placeholder_job_->ToDebugValue()
: base::Value());
dict.Set("uninstall_and_replace_job",
uninstall_and_replace_job_
? uninstall_and_replace_job_->ToDebugValue()
: base::Value());
return base::Value(std::move(dict));
}
void InstallPlaceholderCommand::OnShutdown() {
Abort(webapps::InstallResultCode::kCancelledOnWebAppProviderShuttingDown);
}
void InstallPlaceholderCommand::SetDataRetrieverForTesting(
std::unique_ptr<WebAppDataRetriever> data_retriever) {
data_retriever_for_testing_ = std::move(data_retriever);
}
void InstallPlaceholderCommand::Abort(webapps::InstallResultCode code) {
webapps::InstallableMetrics::TrackInstallResult(false);
if (!callback_) {
return;
}
SignalCompletionAndSelfDestruct(
(code ==
webapps::InstallResultCode::kCancelledOnWebAppProviderShuttingDown)
? CommandResult::kShutdown
: CommandResult::kFailure,
base::BindOnce(std::move(callback_),
ExternallyManagedAppManager::InstallResult(
code, app_id_,
/*did_uninstall_and_replace=*/false)));
}
void InstallPlaceholderCommand::OnPlaceholderInstalled(
webapps::InstallResultCode code,
webapps::AppId app_id) {
webapps::InstallableMetrics::TrackInstallResult(webapps::IsSuccess(code));
if (!callback_) {
return;
}
if (!webapps::IsSuccess(code)) {
Abort(code);
return;
}
uninstall_and_replace_job_.emplace(
profile_.get(), *lock_, install_options_.uninstall_and_replace, app_id_,
base::BindOnce(&InstallPlaceholderCommand::OnUninstallAndReplaced,
weak_factory_.GetWeakPtr(), code));
uninstall_and_replace_job_->Start();
}
void InstallPlaceholderCommand::OnUninstallAndReplaced(
webapps::InstallResultCode code,
bool did_uninstall_and_replace) {
SignalCompletionAndSelfDestruct(
CommandResult::kSuccess,
base::BindOnce(
std::move(callback_),
ExternallyManagedAppManager::InstallResult(
std::move(code), std::move(app_id_), did_uninstall_and_replace)));
}
} // namespace web_app