softwareupdater: Start filling in package kit code

This commit is contained in:
Alexander von Gluck IV
2016-12-12 20:52:46 +00:00
parent b2251661bc
commit 015754479e
5 changed files with 505 additions and 38 deletions
+2 -3
View File
@@ -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
;
@@ -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;
}
*/
}
}
@@ -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;
};
+345
View File
@@ -0,0 +1,345 @@
/*
* Copyright 2013-2015, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler <[email protected]>
* Rene Gollent <[email protected]>
* Ingo Weinhold <[email protected]>
*/
#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());
}
}
+71
View File
@@ -0,0 +1,71 @@
/*
* Copyright 2013-2015, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Ingo Weinhold <[email protected]>
* Rene Gollent <[email protected]>
*/
#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