#ifndef CHROME_BROWSER_ASH_CROSTINI_CROSTINI_PACKAGE_SERVICE_H_
#define CHROME_BROWSER_ASH_CROSTINI_CROSTINI_PACKAGE_SERVICE_H_
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/ash/crostini/crostini_manager.h"
#include "chrome/browser/ash/crostini/crostini_package_notification.h"
#include "chrome/browser/ash/crostini/crostini_package_operation_status.h"
#include "chrome/browser/ash/crostini/crostini_util.h"
#include "chrome/browser/ash/guest_os/guest_os_registry_service.h"
#include "components/keyed_service/core/keyed_service.h"
#include "storage/browser/file_system/file_system_url.h"
namespace crostini {
class CrostiniPackageService : public KeyedService,
public LinuxPackageOperationProgressObserver,
public PendingAppListUpdatesObserver,
public ash::VmShutdownObserver {
public:
using StateChangeCallback =
base::RepeatingCallback<void(PackageOperationStatus)>;
explicit CrostiniPackageService(Profile* profile);
CrostiniPackageService(const CrostiniPackageService&) = delete;
CrostiniPackageService& operator=(const CrostiniPackageService&) = delete;
~CrostiniPackageService() override;
void SetNotificationStateChangeCallbackForTesting(
StateChangeCallback state_change_callback);
void Shutdown() override;
void NotificationCompleted(CrostiniPackageNotification* notification);
void GetLinuxPackageInfo(
const guest_os::GuestId& container_id,
const storage::FileSystemURL& package_url,
CrostiniManager::GetLinuxPackageInfoCallback callback);
void OnInstallLinuxPackageProgress(const guest_os::GuestId& container_id,
InstallLinuxPackageProgressStatus status,
int progress_percent,
const std::string& error_message) override;
void OnUninstallPackageProgress(const guest_os::GuestId& container_id,
UninstallPackageProgressStatus status,
int progress_percent) override;
void OnPendingAppListUpdates(const guest_os::GuestId& container_id,
int count) override;
void OnVmShutdown(const std::string& vm_name) override;
void QueueInstallLinuxPackage(
const guest_os::GuestId& container_id,
const storage::FileSystemURL& package_url,
CrostiniManager::InstallLinuxPackageCallback callback);
void QueueUninstallApplication(const std::string& app_id);
CrostiniManager::RestartId GetRestartIdForTesting();
private:
struct QueuedInstall;
struct QueuedUninstall;
bool ContainerHasRunningOperation(
const guest_os::GuestId& container_id) const;
bool ContainerHasQueuedOperation(const guest_os::GuestId& container_id) const;
void CreateRunningNotification(
const guest_os::GuestId& container_id,
CrostiniPackageNotification::NotificationType notification_type,
const std::string& app_name);
void CreateQueuedUninstall(const guest_os::GuestId& container_id,
const std::string& app_id,
const std::string& app_name);
void CreateQueuedInstall(
const guest_os::GuestId& container_id,
const std::string& package,
CrostiniManager::InstallLinuxPackageCallback callback);
void UpdatePackageOperationStatus(const guest_os::GuestId& container_id,
PackageOperationStatus status,
int progress_percent,
const std::string& error_message = {});
void OnSharePathForGetLinuxPackageInfo(
const guest_os::GuestId& container_id,
const storage::FileSystemURL& package_url,
const base::FilePath& package_path,
CrostiniManager::GetLinuxPackageInfoCallback callback,
CrostiniResult result);
void OnGetLinuxPackageInfo(
const guest_os::GuestId& container_id,
CrostiniManager::GetLinuxPackageInfoCallback callback,
const LinuxPackageInfo& linux_package_info);
void OnInstallLinuxPackage(
const guest_os::GuestId& container_id,
CrostiniManager::InstallLinuxPackageCallback callback,
CrostiniResult result);
void UninstallApplication(
const guest_os::GuestOsRegistryService::Registration& registration,
const std::string& app_id);
void OnCrostiniRunningForUninstall(const guest_os::GuestId& container_id,
const std::string& desktop_file_id,
CrostiniResult result);
void OnUninstallPackageOwningFile(const guest_os::GuestId& container_id,
CrostiniResult result);
void StartQueuedOperation(const guest_os::GuestId& container_id);
std::string GetUniqueNotificationId();
raw_ptr<Profile> profile_;
std::map<guest_os::GuestId, std::unique_ptr<CrostiniPackageNotification>>
running_notifications_;
std::map<guest_os::GuestId, std::queue<QueuedInstall>> queued_installs_;
std::map<guest_os::GuestId, std::queue<QueuedUninstall>> queued_uninstalls_;
std::vector<std::unique_ptr<CrostiniPackageNotification>>
finished_notifications_;
std::set<guest_os::GuestId> has_pending_app_list_updates_;
StateChangeCallback testing_state_change_callback_;
int next_notification_id_ = 0;
CrostiniManager::RestartId restart_id_for_testing_;
base::WeakPtrFactory<CrostiniPackageService> weak_ptr_factory_{this};
};
}
#endif