1*38c62dfbSIngo Weinhold /* 2*38c62dfbSIngo Weinhold * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de. 3*38c62dfbSIngo Weinhold * Distributed under the terms of the MIT License. 4*38c62dfbSIngo Weinhold */ 5*38c62dfbSIngo Weinhold 6*38c62dfbSIngo Weinhold 7*38c62dfbSIngo Weinhold #include "PackageManager.h" 8*38c62dfbSIngo Weinhold 9*38c62dfbSIngo Weinhold #include <Alert.h> 10*38c62dfbSIngo Weinhold #include <Notification.h> 11*38c62dfbSIngo Weinhold #include <package/DownloadFileRequest.h> 12*38c62dfbSIngo Weinhold #include <package/RefreshRepositoryRequest.h> 13*38c62dfbSIngo Weinhold #include <package/solver/SolverPackage.h> 14*38c62dfbSIngo Weinhold #include <package/solver/SolverPackageSpecifierList.h> 15*38c62dfbSIngo Weinhold #include <package/solver/SolverProblem.h> 16*38c62dfbSIngo Weinhold #include <package/solver/SolverProblemSolution.h> 17*38c62dfbSIngo Weinhold 18*38c62dfbSIngo Weinhold #include <package/manager/Exceptions.h> 19*38c62dfbSIngo Weinhold #include <package/manager/RepositoryBuilder.h> 20*38c62dfbSIngo Weinhold #include <Server.h> 21*38c62dfbSIngo Weinhold 22*38c62dfbSIngo Weinhold #include "ProblemWindow.h" 23*38c62dfbSIngo Weinhold #include "Root.h" 24*38c62dfbSIngo Weinhold #include "Volume.h" 25*38c62dfbSIngo Weinhold 26*38c62dfbSIngo Weinhold 27*38c62dfbSIngo Weinhold using BPackageKit::BManager::BPrivate::BAbortedByUserException; 28*38c62dfbSIngo Weinhold using BPackageKit::BManager::BPrivate::BFatalErrorException; 29*38c62dfbSIngo Weinhold using BPackageKit::BManager::BPrivate::BRepositoryBuilder; 30*38c62dfbSIngo Weinhold 31*38c62dfbSIngo Weinhold 32*38c62dfbSIngo Weinhold PackageManager::PackageManager(Root* root, Volume* volume) 33*38c62dfbSIngo Weinhold : 34*38c62dfbSIngo Weinhold BPackageManager(volume->Location()), 35*38c62dfbSIngo Weinhold BPackageManager::UserInteractionHandler(), 36*38c62dfbSIngo Weinhold fRoot(root), 37*38c62dfbSIngo Weinhold fVolume(volume), 38*38c62dfbSIngo Weinhold fContext(*this, *this), 39*38c62dfbSIngo Weinhold fSolverPackages(), 40*38c62dfbSIngo Weinhold fPackagesAddedByUser(), 41*38c62dfbSIngo Weinhold fPackagesRemovedByUser(), 42*38c62dfbSIngo Weinhold fProblemWindow(NULL) 43*38c62dfbSIngo Weinhold { 44*38c62dfbSIngo Weinhold fInstallationInterface = this; 45*38c62dfbSIngo Weinhold fRequestHandler = this; 46*38c62dfbSIngo Weinhold fUserInteractionHandler = this; 47*38c62dfbSIngo Weinhold } 48*38c62dfbSIngo Weinhold 49*38c62dfbSIngo Weinhold 50*38c62dfbSIngo Weinhold PackageManager::~PackageManager() 51*38c62dfbSIngo Weinhold { 52*38c62dfbSIngo Weinhold if (fProblemWindow != NULL) 53*38c62dfbSIngo Weinhold fProblemWindow->PostMessage(B_QUIT_REQUESTED); 54*38c62dfbSIngo Weinhold } 55*38c62dfbSIngo Weinhold 56*38c62dfbSIngo Weinhold 57*38c62dfbSIngo Weinhold void 58*38c62dfbSIngo Weinhold PackageManager::HandleUserChanges() 59*38c62dfbSIngo Weinhold { 60*38c62dfbSIngo Weinhold const PackageSet& packagesToActivate = fVolume->PackagesToBeActivated(); 61*38c62dfbSIngo Weinhold const PackageSet& packagesToDeactivate = fVolume->PackagesToBeDeactivated(); 62*38c62dfbSIngo Weinhold 63*38c62dfbSIngo Weinhold if (packagesToActivate.empty() && packagesToDeactivate.empty()) 64*38c62dfbSIngo Weinhold return; 65*38c62dfbSIngo Weinhold 66*38c62dfbSIngo Weinhold if (packagesToActivate.empty()) { 67*38c62dfbSIngo Weinhold // only packages removed -- use uninstall mode 68*38c62dfbSIngo Weinhold Init(B_ADD_INSTALLED_REPOSITORIES); 69*38c62dfbSIngo Weinhold 70*38c62dfbSIngo Weinhold BSolverPackageSpecifierList packagesToUninstall; 71*38c62dfbSIngo Weinhold for (PackageSet::const_iterator it = packagesToDeactivate.begin(); 72*38c62dfbSIngo Weinhold it != packagesToDeactivate.end(); ++it) { 73*38c62dfbSIngo Weinhold BSolverPackage* solverPackage = _SolverPackageFor(*it); 74*38c62dfbSIngo Weinhold if (solverPackage == NULL) 75*38c62dfbSIngo Weinhold continue; 76*38c62dfbSIngo Weinhold 77*38c62dfbSIngo Weinhold if (!packagesToUninstall.AppendSpecifier(solverPackage)) 78*38c62dfbSIngo Weinhold throw std::bad_alloc(); 79*38c62dfbSIngo Weinhold fPackagesRemovedByUser.insert(solverPackage); 80*38c62dfbSIngo Weinhold } 81*38c62dfbSIngo Weinhold 82*38c62dfbSIngo Weinhold if (fPackagesRemovedByUser.empty()) 83*38c62dfbSIngo Weinhold return; 84*38c62dfbSIngo Weinhold 85*38c62dfbSIngo Weinhold Uninstall(packagesToUninstall); 86*38c62dfbSIngo Weinhold } else { 87*38c62dfbSIngo Weinhold // packages added and (possibly) remove -- manually add/remove those 88*38c62dfbSIngo Weinhold // from the repository and use verify mode 89*38c62dfbSIngo Weinhold Init(B_ADD_INSTALLED_REPOSITORIES | B_ADD_REMOTE_REPOSITORIES 90*38c62dfbSIngo Weinhold | B_REFRESH_REPOSITORIES); 91*38c62dfbSIngo Weinhold 92*38c62dfbSIngo Weinhold // disable and remove uninstalled packages 93*38c62dfbSIngo Weinhold InstalledRepository& repository = InstallationRepository(); 94*38c62dfbSIngo Weinhold for (PackageSet::const_iterator it = packagesToDeactivate.begin(); 95*38c62dfbSIngo Weinhold it != packagesToDeactivate.end(); ++it) { 96*38c62dfbSIngo Weinhold BSolverPackage* solverPackage = _SolverPackageFor(*it); 97*38c62dfbSIngo Weinhold if (solverPackage == NULL) 98*38c62dfbSIngo Weinhold continue; 99*38c62dfbSIngo Weinhold 100*38c62dfbSIngo Weinhold repository.DisablePackage(solverPackage); 101*38c62dfbSIngo Weinhold if (!repository.PackagesToDeactivate().AddItem(solverPackage)) 102*38c62dfbSIngo Weinhold throw std::bad_alloc(); 103*38c62dfbSIngo Weinhold fPackagesRemovedByUser.insert(solverPackage); 104*38c62dfbSIngo Weinhold } 105*38c62dfbSIngo Weinhold 106*38c62dfbSIngo Weinhold // add new packages 107*38c62dfbSIngo Weinhold BRepositoryBuilder repositoryBuilder(repository); 108*38c62dfbSIngo Weinhold for (PackageSet::const_iterator it = packagesToActivate.begin(); 109*38c62dfbSIngo Weinhold it != packagesToActivate.end(); ++it) { 110*38c62dfbSIngo Weinhold Package* package = *it; 111*38c62dfbSIngo Weinhold BSolverPackage* solverPackage; 112*38c62dfbSIngo Weinhold repositoryBuilder.AddPackage(package->Info(), NULL, &solverPackage); 113*38c62dfbSIngo Weinhold fSolverPackages[package] = solverPackage; 114*38c62dfbSIngo Weinhold if (!repository.PackagesToActivate().AddItem(solverPackage)) 115*38c62dfbSIngo Weinhold throw std::bad_alloc(); 116*38c62dfbSIngo Weinhold fPackagesAddedByUser.insert(solverPackage); 117*38c62dfbSIngo Weinhold } 118*38c62dfbSIngo Weinhold 119*38c62dfbSIngo Weinhold if (fPackagesRemovedByUser.empty() && fPackagesAddedByUser.empty()) 120*38c62dfbSIngo Weinhold return; 121*38c62dfbSIngo Weinhold 122*38c62dfbSIngo Weinhold // TODO: When packages are moved out of the packages directory, we can't create 123*38c62dfbSIngo Weinhold // a complete "old-state" directory. 124*38c62dfbSIngo Weinhold 125*38c62dfbSIngo Weinhold VerifyInstallation(); 126*38c62dfbSIngo Weinhold } 127*38c62dfbSIngo Weinhold } 128*38c62dfbSIngo Weinhold 129*38c62dfbSIngo Weinhold 130*38c62dfbSIngo Weinhold void 131*38c62dfbSIngo Weinhold PackageManager::InitInstalledRepository(InstalledRepository& repository) 132*38c62dfbSIngo Weinhold { 133*38c62dfbSIngo Weinhold const char* name = repository.InitialName(); 134*38c62dfbSIngo Weinhold BRepositoryBuilder repositoryBuilder(repository, name); 135*38c62dfbSIngo Weinhold 136*38c62dfbSIngo Weinhold if (Volume* volume = fRoot->GetVolume(repository.Location())) { 137*38c62dfbSIngo Weinhold for (PackageFileNameHashTable::Iterator it 138*38c62dfbSIngo Weinhold = volume->PackagesByFileName().GetIterator(); it.HasNext();) { 139*38c62dfbSIngo Weinhold Package* package = it.Next(); 140*38c62dfbSIngo Weinhold if (package->IsActive()) { 141*38c62dfbSIngo Weinhold BSolverPackage* solverPackage; 142*38c62dfbSIngo Weinhold repositoryBuilder.AddPackage(package->Info(), NULL, 143*38c62dfbSIngo Weinhold &solverPackage); 144*38c62dfbSIngo Weinhold fSolverPackages[package] = solverPackage; 145*38c62dfbSIngo Weinhold } 146*38c62dfbSIngo Weinhold } 147*38c62dfbSIngo Weinhold } 148*38c62dfbSIngo Weinhold } 149*38c62dfbSIngo Weinhold 150*38c62dfbSIngo Weinhold 151*38c62dfbSIngo Weinhold void 152*38c62dfbSIngo Weinhold PackageManager::ResultComputed(InstalledRepository& repository) 153*38c62dfbSIngo Weinhold { 154*38c62dfbSIngo Weinhold // Normalize the result, i.e. remove the packages added by the user which 155*38c62dfbSIngo Weinhold // have been removed again in the problem resolution process, and vice 156*38c62dfbSIngo Weinhold // versa. 157*38c62dfbSIngo Weinhold if (repository.Location() != fVolume->Location()) 158*38c62dfbSIngo Weinhold return; 159*38c62dfbSIngo Weinhold 160*38c62dfbSIngo Weinhold PackageList& packagesToActivate = repository.PackagesToActivate(); 161*38c62dfbSIngo Weinhold PackageList& packagesToDeactivate = repository.PackagesToDeactivate(); 162*38c62dfbSIngo Weinhold 163*38c62dfbSIngo Weinhold for (int32 i = 0; BSolverPackage* package = packagesToDeactivate.ItemAt(i); 164*38c62dfbSIngo Weinhold i++) { 165*38c62dfbSIngo Weinhold if (fPackagesAddedByUser.erase(package) == 0) 166*38c62dfbSIngo Weinhold continue; 167*38c62dfbSIngo Weinhold 168*38c62dfbSIngo Weinhold for (SolverPackageMap::iterator it = fSolverPackages.begin(); 169*38c62dfbSIngo Weinhold it != fSolverPackages.end(); ++it) { 170*38c62dfbSIngo Weinhold if (it->second == package) { 171*38c62dfbSIngo Weinhold fSolverPackages.erase(it); 172*38c62dfbSIngo Weinhold break; 173*38c62dfbSIngo Weinhold } 174*38c62dfbSIngo Weinhold } 175*38c62dfbSIngo Weinhold 176*38c62dfbSIngo Weinhold repository.EnablePackage(package); 177*38c62dfbSIngo Weinhold packagesToDeactivate.RemoveItemAt(i--); 178*38c62dfbSIngo Weinhold packagesToActivate.RemoveItem(package); 179*38c62dfbSIngo Weinhold repository.DeletePackage(package); 180*38c62dfbSIngo Weinhold } 181*38c62dfbSIngo Weinhold 182*38c62dfbSIngo Weinhold for (int32 i = 0; BSolverPackage* package = packagesToActivate.ItemAt(i); 183*38c62dfbSIngo Weinhold i++) { 184*38c62dfbSIngo Weinhold if (fPackagesRemovedByUser.erase(package) == 0) 185*38c62dfbSIngo Weinhold continue; 186*38c62dfbSIngo Weinhold 187*38c62dfbSIngo Weinhold repository.EnablePackage(package); 188*38c62dfbSIngo Weinhold packagesToActivate.RemoveItemAt(i--); 189*38c62dfbSIngo Weinhold packagesToDeactivate.RemoveItem(package); 190*38c62dfbSIngo Weinhold 191*38c62dfbSIngo Weinhold // Note: We keep the package activated, but nonetheless it is gone, 192*38c62dfbSIngo Weinhold // since the user has removed it from the packages directory. So unless 193*38c62dfbSIngo Weinhold // the user moves it back, we won't find it upon next reboot. 194*38c62dfbSIngo Weinhold // TODO: We probable even run into trouble when the user moves in a 195*38c62dfbSIngo Weinhold // replacement afterward. 196*38c62dfbSIngo Weinhold } 197*38c62dfbSIngo Weinhold } 198*38c62dfbSIngo Weinhold 199*38c62dfbSIngo Weinhold 200*38c62dfbSIngo Weinhold status_t 201*38c62dfbSIngo Weinhold PackageManager::PrepareTransaction(Transaction& transaction) 202*38c62dfbSIngo Weinhold { 203*38c62dfbSIngo Weinhold Volume* volume = fRoot->GetVolume(transaction.Repository().Location()); 204*38c62dfbSIngo Weinhold if (volume == NULL) 205*38c62dfbSIngo Weinhold return B_BAD_VALUE; 206*38c62dfbSIngo Weinhold 207*38c62dfbSIngo Weinhold return volume->CreateTransaction(transaction.Repository().Location(), 208*38c62dfbSIngo Weinhold transaction.ActivationTransaction(), 209*38c62dfbSIngo Weinhold transaction.TransactionDirectory()); 210*38c62dfbSIngo Weinhold } 211*38c62dfbSIngo Weinhold 212*38c62dfbSIngo Weinhold 213*38c62dfbSIngo Weinhold status_t 214*38c62dfbSIngo Weinhold PackageManager::CommitTransaction(Transaction& transaction, 215*38c62dfbSIngo Weinhold BDaemonClient::BCommitTransactionResult& _result) 216*38c62dfbSIngo Weinhold { 217*38c62dfbSIngo Weinhold debug_printf("PackageManager::CommitTransaction()\n"); 218*38c62dfbSIngo Weinhold Volume* volume = fRoot->GetVolume(transaction.Repository().Location()); 219*38c62dfbSIngo Weinhold if (volume == NULL) 220*38c62dfbSIngo Weinhold return B_BAD_VALUE; 221*38c62dfbSIngo Weinhold 222*38c62dfbSIngo Weinhold // Get the packages that have already been added to/removed from the 223*38c62dfbSIngo Weinhold // packages directory and thus need to be handled specially by 224*38c62dfbSIngo Weinhold // Volume::CommitTransaction(). 225*38c62dfbSIngo Weinhold PackageSet packagesAlreadyAdded; 226*38c62dfbSIngo Weinhold PackageSet packagesAlreadyRemoved; 227*38c62dfbSIngo Weinhold if (volume == fVolume) { 228*38c62dfbSIngo Weinhold const PackageSet& packagesToActivate = volume->PackagesToBeActivated(); 229*38c62dfbSIngo Weinhold for (PackageSet::const_iterator it = packagesToActivate.begin(); 230*38c62dfbSIngo Weinhold it != packagesToActivate.end(); ++it) { 231*38c62dfbSIngo Weinhold Package* package = *it; 232*38c62dfbSIngo Weinhold if (fPackagesAddedByUser.find(_SolverPackageFor(package)) 233*38c62dfbSIngo Weinhold != fPackagesAddedByUser.end()) { 234*38c62dfbSIngo Weinhold packagesAlreadyAdded.insert(package); 235*38c62dfbSIngo Weinhold } 236*38c62dfbSIngo Weinhold } 237*38c62dfbSIngo Weinhold 238*38c62dfbSIngo Weinhold const PackageSet& packagesToDeactivate 239*38c62dfbSIngo Weinhold = volume->PackagesToBeDeactivated(); 240*38c62dfbSIngo Weinhold for (PackageSet::const_iterator it = packagesToDeactivate.begin(); 241*38c62dfbSIngo Weinhold it != packagesToDeactivate.end(); ++it) { 242*38c62dfbSIngo Weinhold Package* package = *it; 243*38c62dfbSIngo Weinhold if (fPackagesRemovedByUser.find(_SolverPackageFor(package)) 244*38c62dfbSIngo Weinhold != fPackagesRemovedByUser.end()) { 245*38c62dfbSIngo Weinhold packagesAlreadyRemoved.insert(package); 246*38c62dfbSIngo Weinhold } 247*38c62dfbSIngo Weinhold } 248*38c62dfbSIngo Weinhold } 249*38c62dfbSIngo Weinhold debug_printf(" activating %ld (%zu) packages\n", transaction.ActivationTransaction().PackagesToActivate().CountStrings(), packagesAlreadyAdded.size()); 250*38c62dfbSIngo Weinhold debug_printf(" deactivating %ld (%zu) packages\n", transaction.ActivationTransaction().PackagesToDeactivate().CountStrings(), packagesAlreadyRemoved.size()); 251*38c62dfbSIngo Weinhold 252*38c62dfbSIngo Weinhold volume->CommitTransaction(transaction.ActivationTransaction(), 253*38c62dfbSIngo Weinhold packagesAlreadyAdded, packagesAlreadyRemoved, _result); 254*38c62dfbSIngo Weinhold return B_OK; 255*38c62dfbSIngo Weinhold } 256*38c62dfbSIngo Weinhold 257*38c62dfbSIngo Weinhold 258*38c62dfbSIngo Weinhold status_t 259*38c62dfbSIngo Weinhold PackageManager::RefreshRepository(const BRepositoryConfig& repoConfig) 260*38c62dfbSIngo Weinhold { 261*38c62dfbSIngo Weinhold return BRefreshRepositoryRequest(fContext, repoConfig).Process(); 262*38c62dfbSIngo Weinhold } 263*38c62dfbSIngo Weinhold 264*38c62dfbSIngo Weinhold 265*38c62dfbSIngo Weinhold status_t 266*38c62dfbSIngo Weinhold PackageManager::DownloadPackage(const BString& fileURL, 267*38c62dfbSIngo Weinhold const BEntry& targetEntry, const BString& checksum) 268*38c62dfbSIngo Weinhold { 269*38c62dfbSIngo Weinhold return DownloadFileRequest(fContext, fileURL, targetEntry, checksum) 270*38c62dfbSIngo Weinhold .Process(); 271*38c62dfbSIngo Weinhold } 272*38c62dfbSIngo Weinhold 273*38c62dfbSIngo Weinhold 274*38c62dfbSIngo Weinhold void 275*38c62dfbSIngo Weinhold PackageManager::HandleProblems() 276*38c62dfbSIngo Weinhold { 277*38c62dfbSIngo Weinhold _InitGui(); 278*38c62dfbSIngo Weinhold 279*38c62dfbSIngo Weinhold if (fProblemWindow == NULL) 280*38c62dfbSIngo Weinhold fProblemWindow = new ProblemWindow; 281*38c62dfbSIngo Weinhold 282*38c62dfbSIngo Weinhold if (!fProblemWindow->Go(fSolver, fPackagesAddedByUser, 283*38c62dfbSIngo Weinhold fPackagesRemovedByUser)) { 284*38c62dfbSIngo Weinhold throw BAbortedByUserException(); 285*38c62dfbSIngo Weinhold } 286*38c62dfbSIngo Weinhold } 287*38c62dfbSIngo Weinhold 288*38c62dfbSIngo Weinhold 289*38c62dfbSIngo Weinhold void 290*38c62dfbSIngo Weinhold PackageManager::ConfirmChanges(bool fromMostSpecific) 291*38c62dfbSIngo Weinhold { 292*38c62dfbSIngo Weinhold // Check whether there are any changes other than those made by the user. 293*38c62dfbSIngo Weinhold BString alertText( 294*38c62dfbSIngo Weinhold "The following additional package changes have to be made:"); 295*38c62dfbSIngo Weinhold bool hasOtherChanges = false; 296*38c62dfbSIngo Weinhold int32 count = fInstalledRepositories.CountItems(); 297*38c62dfbSIngo Weinhold if (fromMostSpecific) { 298*38c62dfbSIngo Weinhold for (int32 i = count - 1; i >= 0; i--) 299*38c62dfbSIngo Weinhold hasOtherChanges 300*38c62dfbSIngo Weinhold |= _GetResultText(*fInstalledRepositories.ItemAt(i), alertText); 301*38c62dfbSIngo Weinhold } else { 302*38c62dfbSIngo Weinhold for (int32 i = 0; i < count; i++) 303*38c62dfbSIngo Weinhold hasOtherChanges 304*38c62dfbSIngo Weinhold |= _GetResultText(*fInstalledRepositories.ItemAt(i), alertText); 305*38c62dfbSIngo Weinhold } 306*38c62dfbSIngo Weinhold 307*38c62dfbSIngo Weinhold if (!hasOtherChanges) 308*38c62dfbSIngo Weinhold return; 309*38c62dfbSIngo Weinhold 310*38c62dfbSIngo Weinhold // show an alert 311*38c62dfbSIngo Weinhold _InitGui(); 312*38c62dfbSIngo Weinhold BAlert* alert = new BAlert("Package changes", alertText, 313*38c62dfbSIngo Weinhold "Cancel", "Apply changes"); 314*38c62dfbSIngo Weinhold alert->SetShortcut(0, B_ESCAPE); 315*38c62dfbSIngo Weinhold if (alert->Go() == 0) 316*38c62dfbSIngo Weinhold throw BAbortedByUserException(); 317*38c62dfbSIngo Weinhold } 318*38c62dfbSIngo Weinhold 319*38c62dfbSIngo Weinhold 320*38c62dfbSIngo Weinhold void 321*38c62dfbSIngo Weinhold PackageManager::Warn(status_t error, const char* format, ...) 322*38c62dfbSIngo Weinhold { 323*38c62dfbSIngo Weinhold va_list args; 324*38c62dfbSIngo Weinhold va_start(args, format); 325*38c62dfbSIngo Weinhold BString message; 326*38c62dfbSIngo Weinhold message.SetToFormatVarArgs(format, args); 327*38c62dfbSIngo Weinhold va_end(args); 328*38c62dfbSIngo Weinhold 329*38c62dfbSIngo Weinhold if (error != B_OK) 330*38c62dfbSIngo Weinhold message << BString().SetToFormat(": %s", strerror(error)); 331*38c62dfbSIngo Weinhold 332*38c62dfbSIngo Weinhold BNotification notification(B_ERROR_NOTIFICATION); 333*38c62dfbSIngo Weinhold notification.SetTitle("Package Daemon"); 334*38c62dfbSIngo Weinhold notification.SetContent(message); 335*38c62dfbSIngo Weinhold notification.Send(); 336*38c62dfbSIngo Weinhold } 337*38c62dfbSIngo Weinhold 338*38c62dfbSIngo Weinhold 339*38c62dfbSIngo Weinhold void 340*38c62dfbSIngo Weinhold PackageManager::ProgressStartApplyingChanges(InstalledRepository& repository) 341*38c62dfbSIngo Weinhold { 342*38c62dfbSIngo Weinhold } 343*38c62dfbSIngo Weinhold 344*38c62dfbSIngo Weinhold 345*38c62dfbSIngo Weinhold void 346*38c62dfbSIngo Weinhold PackageManager::ProgressTransactionCommitted(InstalledRepository& repository, 347*38c62dfbSIngo Weinhold const char* transactionDirectoryName) 348*38c62dfbSIngo Weinhold { 349*38c62dfbSIngo Weinhold } 350*38c62dfbSIngo Weinhold 351*38c62dfbSIngo Weinhold 352*38c62dfbSIngo Weinhold void 353*38c62dfbSIngo Weinhold PackageManager::ProgressApplyingChangesDone(InstalledRepository& repository) 354*38c62dfbSIngo Weinhold { 355*38c62dfbSIngo Weinhold } 356*38c62dfbSIngo Weinhold 357*38c62dfbSIngo Weinhold 358*38c62dfbSIngo Weinhold bool 359*38c62dfbSIngo Weinhold PackageManager::YesNoDecisionNeeded(const BString& description, 360*38c62dfbSIngo Weinhold const BString& question, const BString& yes, const BString& no, 361*38c62dfbSIngo Weinhold const BString& defaultChoice) 362*38c62dfbSIngo Weinhold { 363*38c62dfbSIngo Weinhold // ATM we need the BDecisionProvider object for the BContext, but we don't 364*38c62dfbSIngo Weinhold // execute any request which actually uses it. 365*38c62dfbSIngo Weinhold return false; 366*38c62dfbSIngo Weinhold } 367*38c62dfbSIngo Weinhold 368*38c62dfbSIngo Weinhold 369*38c62dfbSIngo Weinhold void 370*38c62dfbSIngo Weinhold PackageManager::JobFailed(BJob* job) 371*38c62dfbSIngo Weinhold { 372*38c62dfbSIngo Weinhold // TODO:... 373*38c62dfbSIngo Weinhold } 374*38c62dfbSIngo Weinhold 375*38c62dfbSIngo Weinhold 376*38c62dfbSIngo Weinhold void 377*38c62dfbSIngo Weinhold PackageManager::JobAborted(BJob* job) 378*38c62dfbSIngo Weinhold { 379*38c62dfbSIngo Weinhold // TODO:... 380*38c62dfbSIngo Weinhold } 381*38c62dfbSIngo Weinhold 382*38c62dfbSIngo Weinhold 383*38c62dfbSIngo Weinhold bool 384*38c62dfbSIngo Weinhold PackageManager::_GetResultText(InstalledRepository& repository, 385*38c62dfbSIngo Weinhold BString& _text) 386*38c62dfbSIngo Weinhold { 387*38c62dfbSIngo Weinhold if (!repository.HasChanges()) 388*38c62dfbSIngo Weinhold return false; 389*38c62dfbSIngo Weinhold 390*38c62dfbSIngo Weinhold bool hasOtherChanges = false; 391*38c62dfbSIngo Weinhold bool isTargetLocation 392*38c62dfbSIngo Weinhold = repository.Location() == fVolume->Location(); 393*38c62dfbSIngo Weinhold 394*38c62dfbSIngo Weinhold BString text = BString().SetToFormat("\n in %s:", 395*38c62dfbSIngo Weinhold repository.Name().String()); 396*38c62dfbSIngo Weinhold 397*38c62dfbSIngo Weinhold PackageList& packagesToActivate = repository.PackagesToActivate(); 398*38c62dfbSIngo Weinhold PackageList& packagesToDeactivate = repository.PackagesToDeactivate(); 399*38c62dfbSIngo Weinhold 400*38c62dfbSIngo Weinhold for (int32 i = 0; BSolverPackage* package = packagesToActivate.ItemAt(i); 401*38c62dfbSIngo Weinhold i++) { 402*38c62dfbSIngo Weinhold if (isTargetLocation 403*38c62dfbSIngo Weinhold && fPackagesAddedByUser.find(package) 404*38c62dfbSIngo Weinhold != fPackagesAddedByUser.end()) { 405*38c62dfbSIngo Weinhold continue; 406*38c62dfbSIngo Weinhold } 407*38c62dfbSIngo Weinhold 408*38c62dfbSIngo Weinhold text << BString().SetToFormat( 409*38c62dfbSIngo Weinhold "\n install package %s from repository %s\n", 410*38c62dfbSIngo Weinhold package->Info().FileName().String(), 411*38c62dfbSIngo Weinhold package->Repository()->Name().String()); 412*38c62dfbSIngo Weinhold hasOtherChanges = true; 413*38c62dfbSIngo Weinhold } 414*38c62dfbSIngo Weinhold 415*38c62dfbSIngo Weinhold for (int32 i = 0; BSolverPackage* package = packagesToDeactivate.ItemAt(i); 416*38c62dfbSIngo Weinhold i++) { 417*38c62dfbSIngo Weinhold if (isTargetLocation 418*38c62dfbSIngo Weinhold && fPackagesRemovedByUser.find(package) 419*38c62dfbSIngo Weinhold != fPackagesRemovedByUser.end()) { 420*38c62dfbSIngo Weinhold continue; 421*38c62dfbSIngo Weinhold } 422*38c62dfbSIngo Weinhold 423*38c62dfbSIngo Weinhold text << BString().SetToFormat( 424*38c62dfbSIngo Weinhold "\n uninstall package %s\n", package->VersionedName().String()); 425*38c62dfbSIngo Weinhold hasOtherChanges = true; 426*38c62dfbSIngo Weinhold } 427*38c62dfbSIngo Weinhold 428*38c62dfbSIngo Weinhold if (!hasOtherChanges) 429*38c62dfbSIngo Weinhold return false; 430*38c62dfbSIngo Weinhold 431*38c62dfbSIngo Weinhold _text << text; 432*38c62dfbSIngo Weinhold return true; 433*38c62dfbSIngo Weinhold } 434*38c62dfbSIngo Weinhold 435*38c62dfbSIngo Weinhold 436*38c62dfbSIngo Weinhold BSolverPackage* 437*38c62dfbSIngo Weinhold PackageManager::_SolverPackageFor(Package* package) const 438*38c62dfbSIngo Weinhold { 439*38c62dfbSIngo Weinhold SolverPackageMap::const_iterator it = fSolverPackages.find(package); 440*38c62dfbSIngo Weinhold return it != fSolverPackages.end() ? it->second : NULL; 441*38c62dfbSIngo Weinhold } 442*38c62dfbSIngo Weinhold 443*38c62dfbSIngo Weinhold 444*38c62dfbSIngo Weinhold void 445*38c62dfbSIngo Weinhold PackageManager::_InitGui() 446*38c62dfbSIngo Weinhold { 447*38c62dfbSIngo Weinhold BServer* server = dynamic_cast<BServer*>(be_app); 448*38c62dfbSIngo Weinhold if (server == NULL || server->InitGUIContext() != B_OK) 449*38c62dfbSIngo Weinhold throw BFatalErrorException("failed to initialize the GUI"); 450*38c62dfbSIngo Weinhold } 451