From 1c56f25236ece2904094a8de69a33aa7b8489d78 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sun, 10 Nov 2013 18:36:11 -0500 Subject: [PATCH] HaikuDepot: Fix #10189. - Move InstallPackageAction's _FindPackageByName to PackageAction, so UninstallPackageAction can make use of it as well. - Rename DownloadProgressListener to PackageProgressListener and add hooks for the package manager's DownloadProgressComplete, StartApplyingChanges and ApplyingChangesDone events. - InstallPackageAction implements DownloadProgressComplete in order to gather all dependent packages that were downloaded as part of the installation request. These are then set to active, or reset to available depending on the outcome. Fixes the problem reported in #10189. - UninstallPackageAction now implements the aforementioned ApplyingChanges hooks in order to track all packages to be uninstalled as part of the transaction. Upon completion, they are all accordingly marked as Available. Previously the state wasn't correctly reset for any dependent packages that were also removed as a consequence of the requested package's removal. --- src/apps/haiku-depot/PackageAction.cpp | 20 ++++ src/apps/haiku-depot/PackageAction.h | 3 + src/apps/haiku-depot/PackageManager.cpp | 129 ++++++++++++++++++------ src/apps/haiku-depot/PackageManager.h | 25 +++-- 4 files changed, 139 insertions(+), 38 deletions(-) diff --git a/src/apps/haiku-depot/PackageAction.cpp b/src/apps/haiku-depot/PackageAction.cpp index c79390069f..75b8e7bd72 100644 --- a/src/apps/haiku-depot/PackageAction.cpp +++ b/src/apps/haiku-depot/PackageAction.cpp @@ -8,6 +8,7 @@ #include "PackageAction.h" +#include "Model.h" #include "PackageManager.h" @@ -45,3 +46,22 @@ PackageAction::~PackageAction() } +PackageInfoRef +PackageAction::FindPackageByName(const BString& name) +{ + Model* model = GetModel(); + const DepotList& depots = model->Depots(); + // TODO: optimize! + for (int32 i = 0; i < depots.CountItems(); i++) { + const DepotInfo& depot = depots.ItemAtFast(i); + const PackageList& packages = depot.Packages(); + for (int32 j = 0; j < packages.CountItems(); j++) { + PackageInfoRef info = packages.ItemAtFast(j); + if (info->Title() == name) + return info; + } + } + + return PackageInfoRef(); +} + diff --git a/src/apps/haiku-depot/PackageAction.h b/src/apps/haiku-depot/PackageAction.h index 3808947912..95866cdcd9 100644 --- a/src/apps/haiku-depot/PackageAction.h +++ b/src/apps/haiku-depot/PackageAction.h @@ -43,6 +43,9 @@ public: PackageInfoRef Package() const { return fPackage; } +protected: + PackageInfoRef FindPackageByName(const BString& name); + protected: PackageManager* fPackageManager; diff --git a/src/apps/haiku-depot/PackageManager.cpp b/src/apps/haiku-depot/PackageManager.cpp index 7d57581b7b..cc7c83bcbf 100644 --- a/src/apps/haiku-depot/PackageManager.cpp +++ b/src/apps/haiku-depot/PackageManager.cpp @@ -44,19 +44,50 @@ using BPackageKit::BSolverPackage; using BPackageKit::BSolverRepository; -// #pragma mark - DownloadProgressListener +typedef std::set PackageInfoSet; -DownloadProgressListener::~DownloadProgressListener() +// #pragma mark - PackageProgressListener + + +PackageProgressListener::~PackageProgressListener() { } +void +PackageProgressListener::DownloadProgressChanged(const char* packageName, + float progress) +{ +} + + +void +PackageProgressListener::DownloadProgressComplete(const char* packageName) +{ +} + + +void +PackageProgressListener::StartApplyingChanges( + BPackageManager::InstalledRepository& repository) +{ +} + + +void +PackageProgressListener::ApplyingChangesDone( + BPackageManager::InstalledRepository& repository) +{ +} + + + // #pragma mark - InstallPackageAction class InstallPackageAction : public PackageAction, - private DownloadProgressListener { + private PackageProgressListener { public: InstallPackageAction(PackageInfoRef package, Model* model) : @@ -87,17 +118,20 @@ public: ex.Details().String()); return ex.Error(); } catch (BAbortedByUserException ex) { + _SetDownloadedPackagesState(NONE); return B_OK; } catch (BNothingToDoException ex) { return B_OK; } catch (BException ex) { fprintf(stderr, "Exception occurred while installing package " "%s: %s\n", packageName, ex.Message().String()); + _SetDownloadedPackagesState(NONE); return B_ERROR;; } fPackageManager->RemoveProgressListener(this); - ref->SetState(ACTIVATED); + + _SetDownloadedPackagesState(ACTIVATED); return B_OK; } @@ -107,11 +141,11 @@ public: float progress) { bigtime_t now = system_time(); - if (now - fLastDownloadUpdate > 250000) { + if (now - fLastDownloadUpdate > 250000 || progress == 1.0) { BString tempName(packageName); tempName.Truncate(tempName.FindFirst('-')); // strip version suffix off package filename - PackageInfoRef ref(_FindPackageByName(tempName)); + PackageInfoRef ref(FindPackageByName(tempName)); if (ref.Get() != NULL) { ref->SetDownloadProgress(progress); fLastDownloadUpdate = now; @@ -119,35 +153,38 @@ public: } } + virtual void DownloadProgressComplete(const char* packageName) + { + BString tempName(packageName); + tempName.Truncate(tempName.FindFirst('-')); + // strip version suffix off package filename + PackageInfoRef ref(FindPackageByName(tempName)); + if (ref.Get() != NULL) { + ref->SetDownloadProgress(1.0); + fDownloadedPackages.insert(ref); + } + } private: - PackageInfoRef _FindPackageByName(const BString& name) + void _SetDownloadedPackagesState(PackageState state) { - Model* model = GetModel(); - const DepotList& depots = model->Depots(); - // TODO: optimize! - for (int32 i = 0; i < depots.CountItems(); i++) { - const DepotInfo& depot = depots.ItemAtFast(i); - const PackageList& packages = depot.Packages(); - for (int32 j = 0; j < packages.CountItems(); j++) { - PackageInfoRef info = packages.ItemAtFast(j); - if (info->Title() == name) - return info; - } + for (PackageInfoSet::iterator it = fDownloadedPackages.begin(); + it != fDownloadedPackages.end(); ++it) { + (*it)->SetState(state); } - - return PackageInfoRef(); } private: bigtime_t fLastDownloadUpdate; + PackageInfoSet fDownloadedPackages; }; // #pragma mark - UninstallPackageAction -class UninstallPackageAction : public PackageAction { +class UninstallPackageAction : public PackageAction, + private PackageProgressListener { public: UninstallPackageAction(PackageInfoRef package, Model* model) : @@ -165,6 +202,7 @@ public: fPackageManager->Init(BPackageManager::B_ADD_INSTALLED_REPOSITORIES); PackageInfoRef ref(Package()); fPackageManager->SetCurrentActionPackage(ref, false); + fPackageManager->AddProgressListener(this); const char* packageName = ref->Title().String(); try { fPackageManager->Uninstall(&packageName, 1); @@ -183,10 +221,36 @@ public: return B_ERROR; } + fPackageManager->RemoveProgressListener(this); + ref->SetState(NONE); return B_OK; } + + void StartApplyingChanges( + BPackageManager::InstalledRepository& repository) + + { + BPackageManager::InstalledRepository::PackageList& packages + = repository.PackagesToDeactivate(); + for (int32 i = 0; i < packages.CountItems(); i++) { + PackageInfoRef ref(FindPackageByName(packages.ItemAt(i) + ->Name())); + if (ref.Get() != NULL) + fRemovedPackages.Add(ref); + } + } + + void ApplyingChangesDone( + BPackageManager::InstalledRepository& repository) + { + for (int32 i = 0; i < fRemovedPackages.CountItems(); i++) + fRemovedPackages.ItemAt(i)->SetState(NONE); + } + +private: + PackageList fRemovedPackages; }; @@ -298,16 +362,16 @@ PackageManager::DownloadPackage(const BString& fileURL, void -PackageManager::AddProgressListener(DownloadProgressListener* listener) +PackageManager::AddProgressListener(PackageProgressListener* listener) { - fDownloadProgressListeners.AddItem(listener); + fPackageProgressListeners.AddItem(listener); } void -PackageManager::RemoveProgressListener(DownloadProgressListener* listener) +PackageManager::RemoveProgressListener(PackageProgressListener* listener) { - fDownloadProgressListeners.RemoveItem(listener); + fPackageProgressListeners.RemoveItem(listener); } @@ -375,8 +439,8 @@ void PackageManager::ProgressPackageDownloadActive(const char* packageName, float completionPercentage) { - for (int32 i = 0; i < fDownloadProgressListeners.CountItems(); i++) { - fDownloadProgressListeners.ItemAt(i)->DownloadProgressChanged( + for (int32 i = 0; i < fPackageProgressListeners.CountItems(); i++) { + fPackageProgressListeners.ItemAt(i)->DownloadProgressChanged( packageName, completionPercentage); } } @@ -385,7 +449,10 @@ PackageManager::ProgressPackageDownloadActive(const char* packageName, void PackageManager::ProgressPackageDownloadComplete(const char* packageName) { - // TODO: implement + for (int32 i = 0; i < fPackageProgressListeners.CountItems(); i++) { + fPackageProgressListeners.ItemAt(i)->DownloadProgressComplete( + packageName); + } } @@ -406,7 +473,8 @@ PackageManager::ProgressPackageChecksumComplete(const char* title) void PackageManager::ProgressStartApplyingChanges(InstalledRepository& repository) { - // TODO: implement + for (int32 i = 0; i < fPackageProgressListeners.CountItems(); i++) + fPackageProgressListeners.ItemAt(i)->StartApplyingChanges(repository); } @@ -421,7 +489,8 @@ PackageManager::ProgressTransactionCommitted(InstalledRepository& repository, void PackageManager::ProgressApplyingChangesDone(InstalledRepository& repository) { - // TODO: implement + for (int32 i = 0; i < fPackageProgressListeners.CountItems(); i++) + fPackageProgressListeners.ItemAt(i)->ApplyingChangesDone(repository); } diff --git a/src/apps/haiku-depot/PackageManager.h b/src/apps/haiku-depot/PackageManager.h index ea162bbd46..d9035ea471 100644 --- a/src/apps/haiku-depot/PackageManager.h +++ b/src/apps/haiku-depot/PackageManager.h @@ -36,17 +36,26 @@ using BPackageKit::BPrivate::BDaemonClient; using BPackageKit::BManager::BPrivate::BPackageManager; -class DownloadProgressListener { +class PackageProgressListener { public: - virtual ~DownloadProgressListener(); + virtual ~PackageProgressListener(); virtual void DownloadProgressChanged( const char* packageName, - float progress) = 0; + float progress); + virtual void DownloadProgressComplete( + const char* packageName); + + virtual void StartApplyingChanges( + BPackageManager::InstalledRepository& + repository); + virtual void ApplyingChangesDone( + BPackageManager::InstalledRepository& + repository); }; -typedef BObjectList DownloadProgressListenerList; +typedef BObjectList PackageProgressListenerList; class PackageManager : public BPackageManager, @@ -71,9 +80,9 @@ public: const BString& checksum); void AddProgressListener( - DownloadProgressListener* listener); + PackageProgressListener* listener); void RemoveProgressListener( - DownloadProgressListener* listener); + PackageProgressListener* listener); private: // UserInteractionHandler @@ -122,8 +131,8 @@ private: BPackageKit::BSolverPackage* fCurrentUninstallPackage; - DownloadProgressListenerList - fDownloadProgressListeners; + PackageProgressListenerList + fPackageProgressListeners; }; #endif // PACKAGE_MANAGER_H