HaikuDepot: Clean up some aspects of package handling.

- A package can potentially be installed in more than one location. As
  such, track all of them on PackageInfo (not yet exposed/used).

- Rather than attempting to use location, check the package's flags to
  see if it's a system package. If so, disallow deinstallation. Not quite
  complete yet though, as we still needs to also resolve the deps of any
  system package, and likewise disallow removal of those.
This commit is contained in:
Rene Gollent 2013-10-06 18:11:39 -04:00
parent 09729f54ff
commit fe18453425
4 changed files with 72 additions and 52 deletions

View File

@ -55,7 +55,6 @@ using BManager::BPrivate::BFatalErrorException;
typedef std::map<BString, PackageInfoRef> PackageInfoMap;
typedef std::map<BString, BObjectList<PackageInfo> > PackageLocationMap;
typedef std::map<BString, DepotInfo> DepotInfoMap;
@ -414,7 +413,6 @@ MainWindow::_RefreshPackageList()
if (packages.IsEmpty())
return;
PackageLocationMap packageLocations;
PackageInfoMap foundPackages;
// if a given package is installed locally, we will potentially
// get back multiple entries, one for each local installation
@ -422,8 +420,16 @@ MainWindow::_RefreshPackageList()
// is available in. The above map is used to ensure that in such
// cases we consolidate the information, rather than displaying
// duplicates
PackageInfoMap remotePackages;
// any package that we find in a remote repository goes in this map.
// this is later used to discern which packages came from a local
// installation only, as those must be handled a bit differently
// upon uninstallation, since we'd no longer be able to pull them
// down remotely.
PackageInfoMap systemPackages;
// any packages flagged as a system package are added to this map.
// such packages cannot be uninstalled, nor can any of their deps.
for (int32 i = 0; i < packages.CountItems(); i++) {
BSolverPackage* package = packages.ItemAt(i);
const BPackageInfo& repoPackageInfo = package->Info();
@ -445,7 +451,8 @@ MainWindow::_RefreshPackageList()
repoPackageInfo.Version().ToString(),
PublisherInfo(BitmapRef(), publisherName,
"", publisherURL), repoPackageInfo.Summary(),
repoPackageInfo.Description(), ""),
repoPackageInfo.Description(), "",
repoPackageInfo.Flags()),
true);
if (modelInfo.Get() == NULL)
@ -462,20 +469,19 @@ MainWindow::_RefreshPackageList()
depots[repository->Name()].AddPackage(modelInfo);
remotePackages[modelInfo->Title()] = modelInfo;
} else {
const char* installationLocation = NULL;
if (repository == static_cast<const BSolverRepository*>(
manager.SystemRepository())) {
installationLocation = "system";
modelInfo->AddInstallationLocation(
B_PACKAGE_INSTALLATION_LOCATION_SYSTEM);
} else if (repository == static_cast<const BSolverRepository*>(
manager.HomeRepository())) {
installationLocation = "home";
}
if (installationLocation != NULL) {
packageLocations[installationLocation].AddItem(
modelInfo.Get());
modelInfo->AddInstallationLocation(
B_PACKAGE_INSTALLATION_LOCATION_HOME);
}
}
if (modelInfo->IsSystemPackage())
systemPackages[modelInfo->Title()] = modelInfo;
}
BAutolock lock(fModel.Lock());
@ -505,14 +511,11 @@ MainWindow::_RefreshPackageList()
fModel.AddDepot(it->second);
}
for (PackageLocationMap::iterator it = packageLocations.begin();
it != packageLocations.end(); ++it) {
for (int32 i = 0; i < it->second.CountItems(); i++) {
fModel.SetPackageState(it->second.ItemAt(i), ACTIVATED);
// TODO: indicate the specific installation location
// and verify that the package is in fact activated
// by querying the package roster
}
for (PackageInfoMap::iterator it = systemPackages.begin();
it != systemPackages.end(); ++it) {
// TODO: need to resolve deps on all of these and correspondingly
// mark all of those as system packages as well, so we know
// not to show uninstallation as an option.
}
}

View File

@ -1,5 +1,6 @@
/*
* Copyright 2013, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2013, Rene Gollent <rene@gollent.com>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@ -12,6 +13,7 @@
#include <DataIO.h>
#include <IconUtils.h>
#include <MimeType.h>
#include <package/PackageFlags.h>
#include <Resources.h>
#include "support.h"
@ -447,7 +449,8 @@ PackageInfo::PackageInfo()
fUserRatings(),
fScreenshots(),
fState(NONE),
fDownloadProgress(0.0)
fDownloadProgress(0.0),
fFlags(0)
{
}
@ -455,7 +458,7 @@ PackageInfo::PackageInfo()
PackageInfo::PackageInfo(const BitmapRef& icon, const BString& title,
const BString& version, const PublisherInfo& publisher,
const BString& shortDescription, const BString& fullDescription,
const BString& changelog)
const BString& changelog, int32 flags)
:
fIcon(icon),
fTitle(title),
@ -468,7 +471,8 @@ PackageInfo::PackageInfo(const BitmapRef& icon, const BString& title,
fUserRatings(),
fScreenshots(),
fState(NONE),
fDownloadProgress(0.0)
fDownloadProgress(0.0),
fFlags(flags)
{
}
@ -486,7 +490,9 @@ PackageInfo::PackageInfo(const PackageInfo& other)
fUserRatings(other.fUserRatings),
fScreenshots(other.fScreenshots),
fState(other.fState),
fDownloadProgress(other.fDownloadProgress)
fInstallationLocations(other.fInstallationLocations),
fDownloadProgress(other.fDownloadProgress),
fFlags(other.fFlags)
{
}
@ -505,7 +511,9 @@ PackageInfo::operator=(const PackageInfo& other)
fUserRatings = other.fUserRatings;
fScreenshots = other.fScreenshots;
fState = other.fState;
fInstallationLocations = other.fInstallationLocations;
fDownloadProgress = other.fDownloadProgress;
fFlags = other.fFlags;
return *this;
}
@ -524,6 +532,7 @@ PackageInfo::operator==(const PackageInfo& other) const
&& fUserRatings == other.fUserRatings
&& fScreenshots == other.fScreenshots
&& fState == other.fState
&& fFlags == other.fFlags
&& fDownloadProgress == other.fDownloadProgress;
}
@ -535,6 +544,13 @@ PackageInfo::operator!=(const PackageInfo& other) const
}
bool
PackageInfo::IsSystemPackage() const
{
return (fFlags & BPackageKit::B_PACKAGE_FLAG_SYSTEM_PACKAGE) != 0;
}
bool
PackageInfo::AddCategory(const CategoryRef& category)
{
@ -554,10 +570,12 @@ PackageInfo::SetState(PackageState state)
}
float
PackageInfo::DownloadProgress() const
void
PackageInfo::AddInstallationLocation(int32 location)
{
return fDownloadProgress;
fInstallationLocations.insert(location);
SetState(ACTIVATED);
// TODO: determine how to differentiate between installed and active.
}

View File

@ -6,6 +6,8 @@
#define PACKAGE_INFO_H
#include <set>
#include <Referenceable.h>
#include <String.h>
@ -183,7 +185,7 @@ typedef List<CategoryRef, false> CategoryList;
typedef List<PackageInfoListenerRef, false, 2> PackageListenerList;
typedef std::set<int32> PackageInstallationLocationSet;
enum PackageState {
NONE = 0,
@ -203,7 +205,8 @@ public:
const PublisherInfo& publisher,
const BString& shortDescription,
const BString& fullDescription,
const BString& changelog);
const BString& changelog,
int32 packageFlags);
PackageInfo(const PackageInfo& other);
PackageInfo& operator=(const PackageInfo& other);
@ -225,11 +228,21 @@ public:
const BString& Changelog() const
{ return fChangelog; }
int32 Flags() const
{ return fFlags; }
bool IsSystemPackage() const;
PackageState State() const
{ return fState; }
void SetState(PackageState state);
float DownloadProgress() const;
const PackageInstallationLocationSet&
InstallationLocations() const
{ return fInstallationLocations; }
void AddInstallationLocation(int32 location);
float DownloadProgress() const
{ return fDownloadProgress; }
void SetDownloadProgress(float progress);
bool AddCategory(const CategoryRef& category);
@ -265,8 +278,11 @@ private:
UserRatingList fUserRatings;
BitmapList fScreenshots;
PackageState fState;
PackageInstallationLocationSet
fInstallationLocations;
float fDownloadProgress;
PackageListenerList fListeners;
int32 fFlags;
};

View File

@ -227,31 +227,14 @@ PackageManager::GetPackageState(const PackageInfo& package)
PackageActionList
PackageManager::GetPackageActions(PackageInfoRef package, Model* model)
{
Init(B_ADD_INSTALLED_REPOSITORIES | B_ADD_REMOTE_REPOSITORIES);
PackageActionList actionList;
bool installed = false;
bool systemPackage = false;
BSolverPackage* solverPackage = _GetSolverPackage(package);
if (solverPackage == NULL)
if (package->IsSystemPackage())
return actionList;
const BSolverRepository* repository = solverPackage->Repository();
if (repository == static_cast<const BSolverRepository*>(
SystemRepository())) {
installed = true;
// systemPackage = true;
// TODO: Being installed in system doesn't make it a system package.
} else if (repository == static_cast<const BSolverRepository*>(
HomeRepository())) {
installed = true;
}
if (installed) {
if (!systemPackage) {
actionList.Add(PackageActionRef(new UninstallPackageAction(
package, model), true));
}
int32 state = package->State();
if (state == ACTIVATED || state == INSTALLED) {
actionList.Add(PackageActionRef(new UninstallPackageAction(
package, model), true));
} else {
actionList.Add(PackageActionRef(new InstallPackageAction(package,
model), true));