blob: c2d4e41a0ac0c20f826cf937f4cf85c45a3c68b1 [file] [log] [blame]
// Copyright 2013 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/extensions/install_tracker.h"
#include "base/bind.h"
#include "base/observer_list.h"
#include "chrome/browser/extensions/install_tracker_factory.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/pref_names.h"
namespace extensions {
InstallTracker::InstallTracker(content::BrowserContext* browser_context,
extensions::ExtensionPrefs* prefs) {
extension_registry_observation_.Observe(
ExtensionRegistry::Get(browser_context));
// Prefs may be null in tests.
if (prefs) {
pref_change_registrar_.Init(prefs->pref_service());
pref_change_registrar_.Add(
pref_names::kExtensions,
base::BindRepeating(&InstallTracker::OnExtensionPrefChanged,
base::Unretained(this)));
}
}
InstallTracker::~InstallTracker() {
}
// static
InstallTracker* InstallTracker::Get(content::BrowserContext* context) {
return InstallTrackerFactory::GetForBrowserContext(context);
}
void InstallTracker::AddObserver(InstallObserver* observer) {
observers_.AddObserver(observer);
}
void InstallTracker::RemoveObserver(InstallObserver* observer) {
observers_.RemoveObserver(observer);
}
const ActiveInstallData* InstallTracker::GetActiveInstall(
const std::string& extension_id) const {
auto install_data = active_installs_.find(extension_id);
if (install_data == active_installs_.end())
return nullptr;
else
return &(install_data->second);
}
void InstallTracker::AddActiveInstall(const ActiveInstallData& install_data) {
DCHECK(!install_data.extension_id.empty());
DCHECK(active_installs_.find(install_data.extension_id) ==
active_installs_.end());
active_installs_.insert(
std::make_pair(install_data.extension_id, install_data));
}
void InstallTracker::RemoveActiveInstall(const std::string& extension_id) {
active_installs_.erase(extension_id);
}
void InstallTracker::OnBeginExtensionInstall(
const InstallObserver::ExtensionInstallParams& params) {
auto install_data = active_installs_.find(params.extension_id);
if (install_data == active_installs_.end()) {
ActiveInstallData active_install_data(params.extension_id);
active_installs_.insert(
std::make_pair(params.extension_id, active_install_data));
}
for (auto& observer : observers_)
observer.OnBeginExtensionInstall(params);
}
void InstallTracker::OnBeginExtensionDownload(const std::string& extension_id) {
for (auto& observer : observers_)
observer.OnBeginExtensionDownload(extension_id);
}
void InstallTracker::OnDownloadProgress(const std::string& extension_id,
int percent_downloaded) {
auto install_data = active_installs_.find(extension_id);
if (install_data != active_installs_.end()) {
install_data->second.percent_downloaded = percent_downloaded;
} else {
NOTREACHED();
}
for (auto& observer : observers_)
observer.OnDownloadProgress(extension_id, percent_downloaded);
}
void InstallTracker::OnBeginCrxInstall(const std::string& extension_id) {
for (auto& observer : observers_)
observer.OnBeginCrxInstall(extension_id);
}
void InstallTracker::OnFinishCrxInstall(const std::string& extension_id,
bool success) {
for (auto& observer : observers_)
observer.OnFinishCrxInstall(extension_id, success);
}
void InstallTracker::OnInstallFailure(
const std::string& extension_id) {
RemoveActiveInstall(extension_id);
for (auto& observer : observers_)
observer.OnInstallFailure(extension_id);
}
void InstallTracker::Shutdown() {
// Note: tests may call this method prematurely to avoid shutdown ordering
// issues. Make sure observers don't need to handle this awkward complexity by
// clearing them here and making this method idempotent.
for (auto& observer : observers_)
observer.OnShutdown();
observers_.Clear();
pref_change_registrar_.RemoveAll();
}
void InstallTracker::OnExtensionInstalled(
content::BrowserContext* browser_context,
const Extension* extension,
bool is_update) {
RemoveActiveInstall(extension->id());
}
void InstallTracker::OnAppsReordered(
const absl::optional<std::string>& extension_id) {
for (auto& observer : observers_)
observer.OnAppsReordered(extension_id);
}
void InstallTracker::OnExtensionPrefChanged() {
OnAppsReordered(absl::nullopt);
}
} // namespace extensions