blob: 2147bfb6a57b149135b3b08dd4ac23af89258d1a [file] [log] [blame]
// Copyright 2018 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/web_app_install_manager.h"
#include <iterator>
#include <memory>
#include <utility>
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/observer_list.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/web_applications/install_bounce_metric.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_install_manager_observer.h"
#include "chrome/browser/web_applications/web_app_internals_utils.h"
#include "chrome/browser/web_applications/web_app_utils.h"
#include "chrome/common/chrome_features.h"
#include "components/webapps/browser/installable/installable_metrics.h"
namespace web_app {
namespace {
constexpr char kWebAppInstallManagerName[] = "WebAppInstallManager";
} // namespace
WebAppInstallManager::WebAppInstallManager(Profile* profile)
: profile_(profile) {
if (base::FeatureList::IsEnabled(features::kRecordWebAppDebugInfo)) {
error_log_ = std::make_unique<ErrorLog>();
ReadErrorLog(GetWebAppsRootDirectory(profile_), kWebAppInstallManagerName,
base::BindOnce(&WebAppInstallManager::OnReadErrorLog,
weak_ptr_factory_.GetWeakPtr()));
} else {
ClearErrorLog(GetWebAppsRootDirectory(profile_), kWebAppInstallManagerName,
base::DoNothing());
}
}
WebAppInstallManager::~WebAppInstallManager() {
NotifyWebAppInstallManagerDestroyed();
}
void WebAppInstallManager::Start() {}
void WebAppInstallManager::Shutdown() {}
void WebAppInstallManager::TakeCommandErrorLog(
base::PassKey<WebAppCommandManager>,
base::Value::Dict log) {
if (error_log_)
LogErrorObject(std::move(log));
}
void WebAppInstallManager::MaybeWriteErrorLog() {
DCHECK(error_log_);
if (error_log_writing_in_progress_ || !error_log_updated_)
return;
WriteErrorLog(GetWebAppsRootDirectory(profile_), kWebAppInstallManagerName,
base::Value(error_log_->Clone()),
base::BindOnce(&WebAppInstallManager::OnWriteErrorLog,
weak_ptr_factory_.GetWeakPtr()));
error_log_writing_in_progress_ = true;
error_log_updated_ = false;
}
void WebAppInstallManager::OnWriteErrorLog(Result result) {
error_log_writing_in_progress_ = false;
MaybeWriteErrorLog();
}
void WebAppInstallManager::OnReadErrorLog(Result result,
base::Value error_log) {
DCHECK(error_log_);
if (result != Result::kOk || !error_log.is_list())
return;
ErrorLog early_error_log = std::move(*error_log_);
*error_log_ = std::move(error_log).TakeList();
// Appends the `early_error_log` at the end.
error_log_->reserve(error_log_->size() + early_error_log.size());
for (auto& error : early_error_log) {
error_log_->Append(std::move(error));
}
}
void WebAppInstallManager::LogErrorObject(base::Value::Dict object) {
if (!error_log_)
return;
error_log_->Append(std::move(object));
error_log_updated_ = true;
MaybeWriteErrorLog();
}
void WebAppInstallManager::AddObserver(WebAppInstallManagerObserver* observer) {
observers_.AddObserver(observer);
}
void WebAppInstallManager::RemoveObserver(
WebAppInstallManagerObserver* observer) {
observers_.RemoveObserver(observer);
}
void WebAppInstallManager::NotifyWebAppInstalled(const webapps::AppId& app_id) {
for (WebAppInstallManagerObserver& observer : observers_) {
observer.OnWebAppInstalled(app_id);
}
// TODO(alancutter): Call RecordWebAppInstallation here when we get access to
// the webapps::WebappInstallSource in this event.
}
void WebAppInstallManager::NotifyWebAppInstalledWithOsHooks(
const webapps::AppId& app_id) {
for (WebAppInstallManagerObserver& obs : observers_) {
obs.OnWebAppInstalledWithOsHooks(app_id);
}
}
void WebAppInstallManager::NotifyWebAppSourceRemoved(
const webapps::AppId& app_id) {
for (WebAppInstallManagerObserver& observer : observers_) {
observer.OnWebAppSourceRemoved(app_id);
}
}
void WebAppInstallManager::NotifyWebAppUninstalled(
const webapps::AppId& app_id,
webapps::WebappUninstallSource uninstall_source) {
for (WebAppInstallManagerObserver& observer : observers_) {
observer.OnWebAppUninstalled(app_id, uninstall_source);
}
}
void WebAppInstallManager::NotifyWebAppManifestUpdated(
const webapps::AppId& app_id) {
for (WebAppInstallManagerObserver& observer : observers_) {
observer.OnWebAppManifestUpdated(app_id);
}
}
void WebAppInstallManager::NotifyWebAppWillBeUninstalled(
const webapps::AppId& app_id) {
for (WebAppInstallManagerObserver& observer : observers_) {
observer.OnWebAppWillBeUninstalled(app_id);
}
RecordWebAppUninstallation(profile_->GetPrefs(), app_id);
}
void WebAppInstallManager::NotifyWebAppInstallManagerDestroyed() {
for (WebAppInstallManagerObserver& observer : observers_) {
observer.OnWebAppInstallManagerDestroyed();
}
}
} // namespace web_app