hrev50766 adds 1 changeset to branch 'master'
old head: b2251661bc31a3ece6ca3368e91ba2743cd02a75
new head: 015754479e17acbd369f5e201042222fdfd4c0da
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=015754479e17+%5Eb2251661bc31
----------------------------------------------------------------------------
015754479e17: softwareupdater: Start filling in package kit code
[ Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev50766
Commit: 015754479e17acbd369f5e201042222fdfd4c0da
URL: http://cgit.haiku-os.org/haiku/commit/?id=015754479e17
Author: Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date: Mon Dec 12 20:51:34 2016 UTC
----------------------------------------------------------------------------
5 files changed, 505 insertions(+), 38 deletions(-)
src/apps/softwareupdater/Jamfile | 5 +-
.../softwareupdater/SoftwareUpdaterWindow.cpp | 109 ++++--
src/apps/softwareupdater/SoftwareUpdaterWindow.h | 13 +-
src/apps/softwareupdater/UpdateManager.cpp | 345 +++++++++++++++++++
src/apps/softwareupdater/UpdateManager.h | 71 ++++
----------------------------------------------------------------------------
diff --git a/src/apps/softwareupdater/Jamfile b/src/apps/softwareupdater/Jamfile
index bdea8f0..4fd6d40 100644
--- a/src/apps/softwareupdater/Jamfile
+++ b/src/apps/softwareupdater/Jamfile
@@ -1,11 +1,10 @@
SubDir HAIKU_TOP src apps softwareupdater ;
-UsePrivateHeaders interface shared ;
-
Application SoftwareUpdater :
SoftwareUpdaterApp.cpp
SoftwareUpdaterWindow.cpp
StripeView.cpp
- : be localestub tracker translation [ TargetLibsupc++ ]
+ UpdateManager.cpp
+ : be localestub package translation [ TargetLibsupc++ ]
: SoftwareUpdater.rdef
;
diff --git a/src/apps/softwareupdater/SoftwareUpdaterWindow.cpp
b/src/apps/softwareupdater/SoftwareUpdaterWindow.cpp
index 43c38f2..a1856cd 100644
--- a/src/apps/softwareupdater/SoftwareUpdaterWindow.cpp
+++ b/src/apps/softwareupdater/SoftwareUpdaterWindow.cpp
@@ -12,16 +12,17 @@
#include <stdio.h>
#include <AppDefs.h>
#include <Application.h>
-#include <Button.h>
#include <GroupLayout.h>
#include <GroupLayoutBuilder.h>
#include <NodeInfo.h>
#include <LayoutBuilder.h>
#include <Message.h>
+#include <package/Context.h>
+#include <package/RefreshRepositoryRequest.h>
+#include <package/PackageRoster.h>
#include <Resources.h>
#include <SeparatorView.h>
#include <String.h>
-#include <StringView.h>
#undef B_TRANSLATION_CONTEXT
@@ -32,13 +33,25 @@ const uint32 kMsgUpdate = 'iUPD';
const uint32 kMsgExit = 'iEXT';
+using namespace BPackageKit;
+
+
SoftwareUpdaterWindow::SoftwareUpdaterWindow()
:
BWindow(BRect(0, 0, 0, 300), "Software Update",
B_TITLED_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE),
- fStripeView(NULL)
+// fUpdateManager(NULL),
+ fStripeView(NULL),
+ fHeaderView(NULL),
+ fDetailView(NULL),
+ fUpdateButton(NULL),
+ fCancelButton(NULL)
{
- uint32 updatesAvailable = 45;
+ fUpdateManager = new UpdateManager(
+ BPackageKit::B_PACKAGE_INSTALLATION_LOCATION_HOME);
+ fUpdateManager->SetDebugLevel(10);
+ fUpdateManager->Init(BPackageManager::B_ADD_INSTALLED_REPOSITORIES
+ | BPackageManager::B_ADD_REMOTE_REPOSITORIES);
BBitmap* icon = new BBitmap(BRect(0, 0, 31, 31), 0, B_RGBA32);
team_info teamInfo;
@@ -49,40 +62,23 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
fStripeView = new StripeView(icon);
- BButton* updateButton = new BButton("Update now",
+ BButton* fUpdateButton = new BButton("Update now",
new BMessage(kMsgUpdate));
+ fUpdateButton->Hide();
- BButton* exitButton = new BButton("Cancel",
+ BButton* fCancelButton = new BButton("Cancel",
new BMessage(kMsgExit));
- // Form text based on updates available
- BStringView* headerView;
- BStringView* detailView;
-
- if (updatesAvailable > 0) {
- headerView = new BStringView("header",
- "Software updates are available.", B_WILL_DRAW);
- char detailString[1024];
- snprintf(detailString, 1024, "There are %" B_PRIu32 " updates
available"
- " for your system.", updatesAvailable);
- detailView = new BStringView("detail", detailString,
B_WILL_DRAW);
- updateButton->MakeDefault(true);
- } else {
- headerView = new BStringView("header",
- "Your system is up to date.", B_WILL_DRAW);
- detailView = new BStringView("detail",
- "No updates are available at this time.",
- B_WILL_DRAW);
- updateButton->Hide();
- exitButton->SetLabel("Quit");
- exitButton->MakeDefault(true);
- }
+ fHeaderView = new BStringView("header",
+ "Checking for updates...", B_WILL_DRAW);
+ fDetailView = new BStringView("detail", "Contacting software
repositories"
+ " to check for package updates.", B_WILL_DRAW);
BFont font;
- headerView->GetFont(&font);
+ fHeaderView->GetFont(&font);
font.SetFace(B_BOLD_FACE);
font.SetSize(font.Size() * 1.5);
- headerView->SetFont(&font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE
+ fHeaderView->SetFont(&font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE
| B_FONT_FLAGS);
BLayoutBuilder::Group<>(this, B_HORIZONTAL, 0)
@@ -90,13 +86,13 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
.AddGroup(B_VERTICAL, B_USE_SMALL_SPACING)
.SetInsets(0, B_USE_DEFAULT_SPACING,
B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING)
- .Add(headerView)
- .Add(detailView)
+ .Add(fHeaderView)
+ .Add(fDetailView)
.AddStrut(B_USE_DEFAULT_SPACING)
.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
.AddGlue()
- .Add(exitButton)
- .Add(updateButton)
+ .Add(fCancelButton)
+ .Add(fUpdateButton)
.End()
.End()
.AddGlue()
@@ -104,6 +100,9 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
;
CenterOnScreen();
Show();
+
+ // Refresh our repos and update UI
+ _Refresh();
}
@@ -133,3 +132,45 @@ SoftwareUpdaterWindow::MessageReceived(BMessage* message)
BWindow::MessageReceived(message);
}
}
+
+
+void
+SoftwareUpdaterWindow::_Error(const char* error)
+{
+ fHeaderView->SetText("Error encountered!");
+ fDetailView->SetText(error);
+ fUpdateButton->Hide();
+ fCancelButton->Show();
+}
+
+void
+SoftwareUpdaterWindow::_Refresh()
+{
+ BPackageRoster roster;
+ BStringList repoNames(20);
+
+ status_t result = roster.GetRepositoryNames(repoNames);
+ if (result != B_OK) {
+ _Error("Unable to obtain repository names.");
+ return;
+ }
+
+ for (int i = 0; i < repoNames.CountStrings(); i++) {
+ const BString& repoName = repoNames.StringAt(i);
+ BRepositoryConfig repoConfig;
+ result = roster.GetRepositoryConfig(repoName, &repoConfig);
+ if (result != B_OK) {
+ printf("Skipping '%s' repo due to unknown config\n",
+ repoName.String());
+ continue;
+ }
+ /*
+ BRefreshRepositoryRequest request(context, repoConfig);
+ result = request.Process();
+ if (result != B_OK) {
+ printf("Skipping %s repo due to unreachable repo");
+ continue;
+ }
+ */
+ }
+}
diff --git a/src/apps/softwareupdater/SoftwareUpdaterWindow.h
b/src/apps/softwareupdater/SoftwareUpdaterWindow.h
index fb3d979..a0776b1 100644
--- a/src/apps/softwareupdater/SoftwareUpdaterWindow.h
+++ b/src/apps/softwareupdater/SoftwareUpdaterWindow.h
@@ -9,11 +9,13 @@
#define _SOFTWARE_UPDATER_WINDOW_H
+#include <Button.h>
#include <Roster.h>
-#include <StatusBar.h>
+#include <StringView.h>
#include <Window.h>
#include "StripeView.h"
+#include "UpdateManager.h"
class SoftwareUpdaterWindow : public BWindow {
@@ -25,8 +27,17 @@ public:
void MessageReceived(BMessage*
message);
private:
+ void _Error(const char* error);
+ void _Refresh();
+
+ UpdateManager* fUpdateManager;
StripeView* fStripeView;
app_info* fAppInfo;
+
+ BStringView* fHeaderView;
+ BStringView* fDetailView;
+ BButton* fUpdateButton;
+ BButton* fCancelButton;
};
diff --git a/src/apps/softwareupdater/UpdateManager.cpp
b/src/apps/softwareupdater/UpdateManager.cpp
new file mode 100644
index 0000000..8242a9d
--- /dev/null
+++ b/src/apps/softwareupdater/UpdateManager.cpp
@@ -0,0 +1,345 @@
+/*
+ * Copyright 2013-2015, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ * Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
+ * Rene Gollent <rene@xxxxxxxxxxx>
+ * Ingo Weinhold <ingo_weinhold@xxxxxx>
+ */
+
+
+#include "UpdateManager.h"
+
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <package/CommitTransactionResult.h>
+#include <package/DownloadFileRequest.h>
+#include <package/RefreshRepositoryRequest.h>
+#include <package/solver/SolverPackage.h>
+#include <package/solver/SolverProblem.h>
+#include <package/solver/SolverProblemSolution.h>
+
+
+using namespace BPackageKit;
+
+
+UpdateManager::UpdateManager(BPackageInstallationLocation location)
+ :
+ BPackageManager(location, &fClientInstallationInterface, this),
+ BPackageManager::UserInteractionHandler(),
+ fClientInstallationInterface()
+{
+}
+
+
+UpdateManager::~UpdateManager()
+{
+}
+
+
+void
+UpdateManager::JobFailed(BSupportKit::BJob* job)
+{
+ BString error = job->ErrorString();
+ if (error.Length() > 0) {
+ error.ReplaceAll("\n", "\n*** ");
+ fprintf(stderr, "%s", error.String());
+ }
+}
+
+
+void
+UpdateManager::JobAborted(BSupportKit::BJob* job)
+{
+ //DIE(job->Result(), "aborted");
+}
+
+
+void
+UpdateManager::HandleProblems()
+{
+ int32 problemCount = fSolver->CountProblems();
+ for (int32 i = 0; i < problemCount; i++) {
+ // print problem and possible solutions
+ BSolverProblem* problem = fSolver->ProblemAt(i);
+ printf("problem %" B_PRId32 ": %s\n", i + 1,
+ problem->ToString().String());
+
+ int32 solutionCount = problem->CountSolutions();
+ for (int32 k = 0; k < solutionCount; k++) {
+ const BSolverProblemSolution* solution =
problem->SolutionAt(k);
+ printf(" solution %" B_PRId32 ":\n", k + 1);
+ int32 elementCount = solution->CountElements();
+ for (int32 l = 0; l < elementCount; l++) {
+ const BSolverProblemSolutionElement* element
+ = solution->ElementAt(l);
+ printf(" - %s\n",
element->ToString().String());
+ }
+ }
+
+ // let the user choose a solution
+ printf("Please select a solution, skip the problem for now or
quit.\n");
+ for (;;) {
+ if (solutionCount > 1)
+ printf("select [1...%" B_PRId32 "/s/q]: ",
solutionCount);
+ else
+ printf("select [1/s/q]: ");
+
+ char buffer[32];
+ if (fgets(buffer, sizeof(buffer), stdin) == NULL
+ || strcmp(buffer, "q\n") == 0) {
+ //exit(1);
+ }
+
+ if (strcmp(buffer, "s\n") == 0)
+ break;
+
+ /*
+ char* end;
+ long selected = strtol(buffer, &end, 0);
+ if (end == buffer || *end != '\n' || selected < 1
+ || selected > solutionCount) {
+ printf("*** invalid input\n");
+ continue;
+ }
+
+ status_t error = fSolver->SelectProblemSolution(problem,
+ problem->SolutionAt(selected - 1));
+ if (error != B_OK)
+ DIE(error, "failed to set solution");
+ */
+ break;
+ }
+ }
+}
+
+
+void
+UpdateManager::ConfirmChanges(bool fromMostSpecific)
+{
+ printf("The following changes will be made:\n");
+
+ int32 count = fInstalledRepositories.CountItems();
+ if (fromMostSpecific) {
+ for (int32 i = count - 1; i >= 0; i--)
+ _PrintResult(*fInstalledRepositories.ItemAt(i));
+ } else {
+ for (int32 i = 0; i < count; i++)
+ _PrintResult(*fInstalledRepositories.ItemAt(i));
+ }
+
+ /*
+ if (!fDecisionProvider.YesNoDecisionNeeded(BString(), "Continue?",
"yes",
+ "no", "yes")) {
+ //exit(1);
+ }
+ */
+}
+
+
+void
+UpdateManager::Warn(status_t error, const char* format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+
+ if (error == B_OK)
+ printf("\n");
+ else
+ printf(": %s\n", strerror(error));
+}
+
+
+void
+UpdateManager::ProgressPackageDownloadStarted(const char* packageName)
+{
+ printf("Downloading %s...\n", packageName);
+}
+
+
+void
+UpdateManager::ProgressPackageDownloadActive(const char* packageName,
+ float completionPercentage, off_t bytes, off_t totalBytes)
+{
+ return;
+ /*
+ if (!fInteractive)
+ return;
+
+ static const char* progressChars[] = {
+ "\xE2\x96\x8F",
+ "\xE2\x96\x8E",
+ "\xE2\x96\x8D",
+ "\xE2\x96\x8C",
+ "\xE2\x96\x8B",
+ "\xE2\x96\x8A",
+ "\xE2\x96\x89",
+ "\xE2\x96\x88",
+ };
+
+ int width = 70;
+
+ struct winsize winSize;
+ if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winSize) == 0
+ && winSize.ws_col < 77) {
+ // We need 7 characters for the percent display
+ width = winSize.ws_col - 7;
+ }
+
+ int position;
+ int ipart = (int)(completionPercentage * width);
+ int fpart = (int)(((completionPercentage * width) - ipart) * 8);
+
+ printf("\r"); // return to the beginning of the line
+
+ for (position = 0; position < width; position++) {
+ if (position < ipart) {
+ // This part is fully downloaded, show a full block
+ printf(progressChars[7]);
+ } else if (position > ipart) {
+ // This part is not downloaded, show a space
+ printf(" ");
+ } else {
+ // This part is partially downloaded
+ printf(progressChars[fpart]);
+ }
+ }
+
+ // Also print the progress percentage
+ printf(" %3d%%", (int)(completionPercentage * 100));
+
+ fflush(stdout);
+ */
+}
+
+
+void
+UpdateManager::ProgressPackageDownloadComplete(const char* packageName)
+{
+ // Overwrite the progress bar with whitespace
+ printf("\r");
+ struct winsize w;
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
+ for (int i = 0; i < (w.ws_col); i++)
+ printf(" ");
+ printf("\r\x1b[1A"); // Go to previous line.
+
+ printf("Downloading %s...done.\n", packageName);
+}
+
+
+void
+UpdateManager::ProgressPackageChecksumStarted(const char* title)
+{
+ printf("%s...", title);
+}
+
+
+void
+UpdateManager::ProgressPackageChecksumComplete(const char* title)
+{
+ printf("done.\n");
+}
+
+
+void
+UpdateManager::ProgressStartApplyingChanges(InstalledRepository& repository)
+{
+ printf("[%s] Applying changes ...\n", repository.Name().String());
+}
+
+
+void
+UpdateManager::ProgressTransactionCommitted(InstalledRepository& repository,
+ const BCommitTransactionResult& result)
+{
+ const char* repositoryName = repository.Name().String();
+
+ int32 issueCount = result.CountIssues();
+ for (int32 i = 0; i < issueCount; i++) {
+ const BTransactionIssue* issue = result.IssueAt(i);
+ if (issue->PackageName().IsEmpty()) {
+ printf("[%s] warning: %s\n", repositoryName,
+ issue->ToString().String());
+ } else {
+ printf("[%s] warning: package %s: %s\n", repositoryName,
+ issue->PackageName().String(),
issue->ToString().String());
+ }
+ }
+
+ printf("[%s] Changes applied. Old activation state backed up in
\"%s\"\n",
+ repositoryName, result.OldStateDirectory().String());
+ printf("[%s] Cleaning up ...\n", repositoryName);
+}
+
+
+void
+UpdateManager::ProgressApplyingChangesDone(InstalledRepository& repository)
+{
+ printf("[%s] Done.\n", repository.Name().String());
+}
+
+
+void
+UpdateManager::_PrintResult(InstalledRepository& installationRepository)
+{
+ if (!installationRepository.HasChanges())
+ return;
+
+ printf(" in %s:\n", installationRepository.Name().String());
+
+ PackageList& packagesToActivate
+ = installationRepository.PackagesToActivate();
+ PackageList& packagesToDeactivate
+ = installationRepository.PackagesToDeactivate();
+
+ BStringList upgradedPackages;
+ BStringList upgradedPackageVersions;
+ for (int32 i = 0;
+ BSolverPackage* installPackage = packagesToActivate.ItemAt(i);
+ i++) {
+ for (int32 j = 0;
+ BSolverPackage* uninstallPackage =
packagesToDeactivate.ItemAt(j);
+ j++) {
+ if (installPackage->Info().Name() ==
uninstallPackage->Info().Name()) {
+
upgradedPackages.Add(installPackage->Info().Name());
+
upgradedPackageVersions.Add(uninstallPackage->Info().Version().ToString());
+ break;
+ }
+ }
+ }
+
+ for (int32 i = 0; BSolverPackage* package =
packagesToActivate.ItemAt(i);
+ i++) {
+ BString repository;
+ if (dynamic_cast<MiscLocalRepository*>(package->Repository())
!= NULL)
+ repository = "local file";
+ else
+ repository.SetToFormat("repository %s",
package->Repository()->Name().String());
+
+ int position = upgradedPackages.IndexOf(package->Info().Name());
+ if (position >= 0) {
+ printf(" upgrade package %s-%s to %s from %s\n",
+ package->Info().Name().String(),
+
upgradedPackageVersions.StringAt(position).String(),
+ package->Info().Version().ToString().String(),
+ repository.String());
+ } else {
+ printf(" install package %s-%s from %s\n",
+ package->Info().Name().String(),
+ package->Info().Version().ToString().String(),
+ repository.String());
+ }
+ }
+
+ for (int32 i = 0; BSolverPackage* package =
packagesToDeactivate.ItemAt(i);
+ i++) {
+ if (upgradedPackages.HasString(package->Info().Name()))
+ continue;
+ printf(" uninstall package %s\n",
package->VersionedName().String());
+ }
+}
diff --git a/src/apps/softwareupdater/UpdateManager.h
b/src/apps/softwareupdater/UpdateManager.h
new file mode 100644
index 0000000..efef0bb
--- /dev/null
+++ b/src/apps/softwareupdater/UpdateManager.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2013-2015, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ * Ingo Weinhold <ingo_weinhold@xxxxxx>
+ * Rene Gollent <rene@xxxxxxxxxxx>
+ */
+#ifndef UPDATE_MANAGER_H
+#define UPDATE_MANAGER_H
+
+
+#include <package/DaemonClient.h>
+#include <package/manager/PackageManager.h>
+
+
+//using namespace BPackageKit;
+using BPackageKit::BPrivate::BDaemonClient;
+using BPackageKit::BManager::BPrivate::BPackageManager;
+
+
+class UpdateManager : public BPackageManager,
+ private BPackageManager::UserInteractionHandler {
+public:
+ UpdateManager(
+
BPackageKit::BPackageInstallationLocation location);
+
~UpdateManager();
+
+ virtual void JobFailed(BSupportKit::BJob*
job);
+ virtual void JobAborted(BSupportKit::BJob*
job);
+
+private:
+ // UserInteractionHandler
+ virtual void HandleProblems();
+ virtual void ConfirmChanges(bool
fromMostSpecific);
+
+ virtual void Warn(status_t error, const
char* format, ...);
+
+
+ virtual void ProgressPackageDownloadStarted(
+ const
char* packageName);
+ virtual void ProgressPackageDownloadActive(
+ const
char* packageName,
+ float
completionPercentage,
+ off_t
bytes, off_t totalBytes);
+ virtual void ProgressPackageDownloadComplete(
+ const
char* packageName);
+ virtual void ProgressPackageChecksumStarted(
+ const
char* packageName);
+ virtual void ProgressPackageChecksumComplete(
+ const
char* packageName);
+
+ virtual void ProgressStartApplyingChanges(
+
InstalledRepository& repository);
+ virtual void ProgressTransactionCommitted(
+
InstalledRepository& repository,
+ const
BPackageKit::BCommitTransactionResult& result);
+ virtual void ProgressApplyingChangesDone(
+
InstalledRepository& repository);
+
+private:
+ void
_PrintResult(InstalledRepository&
+
installationRepository);
+
+private:
+ BPackageManager::ClientInstallationInterface
+
fClientInstallationInterface;
+};
+
+
+#endif // UPDATE_MANAGER_H