Add watching support for installation location package changes
Can be requested/stopped via BPackageRoster::{Start,Stop}Watching(). The notification message has the what code B_PACKAGE_UPDATE and contains fields "event", "location", and "change count".
This commit is contained in:
parent
3f91ba29d9
commit
5c9672edeb
@ -48,6 +48,7 @@ enum {
|
||||
B_MOUSE_UP = '_MUP',
|
||||
B_MOUSE_WHEEL_CHANGED = '_MWC',
|
||||
B_OPEN_IN_WORKSPACE = '_OWS',
|
||||
B_PACKAGE_UPDATE = '_PKU',
|
||||
B_PRINTER_CHANGED = '_PCH',
|
||||
B_PULSE = '_PUL',
|
||||
B_READY_TO_RUN = '_RTR',
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Copyright 2011-2014, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _PACKAGE__PACKAGE_ROSTER_H_
|
||||
@ -34,6 +34,23 @@ class BRepositoryCache;
|
||||
class BRepositoryConfig;
|
||||
|
||||
|
||||
// watchable events
|
||||
enum {
|
||||
B_WATCH_PACKAGE_INSTALLATION_LOCATIONS = 0x0001,
|
||||
// de-/activation of packages in standard installation locations
|
||||
};
|
||||
|
||||
// notification message "event" field values
|
||||
enum {
|
||||
B_INSTALLATION_LOCATION_PACKAGES_CHANGED,
|
||||
// "location": int32
|
||||
// the installation location
|
||||
// (B_PACKAGE_INSTALLATION_LOCATION_{SYSTEM,HOME}
|
||||
// "change count": int64
|
||||
// the installation location change count
|
||||
};
|
||||
|
||||
|
||||
class BPackageRoster {
|
||||
public:
|
||||
BPackageRoster();
|
||||
@ -68,6 +85,10 @@ public:
|
||||
BPackageInstallationLocation location,
|
||||
BPackageInfoSet& packageInfos);
|
||||
|
||||
status_t StartWatching(const BMessenger& target,
|
||||
uint32 eventMask);
|
||||
status_t StopWatching(const BMessenger& target);
|
||||
|
||||
private:
|
||||
status_t _GetRepositoryPath(BPath* path, bool create,
|
||||
directory_which whichDir) const;
|
||||
|
@ -124,6 +124,10 @@ enum {
|
||||
B_REG_DELETE_USER = 'rdus',
|
||||
B_REG_UPDATE_GROUP = 'rugr',
|
||||
B_REG_DELETE_GROUP = 'rdgr',
|
||||
|
||||
// package watching requests
|
||||
B_REG_PACKAGE_START_WATCHING = 'rgPw',
|
||||
B_REG_PACKAGE_STOP_WATCHING = 'rgPx',
|
||||
};
|
||||
|
||||
// B_REG_MIME_SET_PARAM "which" constants
|
||||
|
@ -1,6 +1,7 @@
|
||||
SubDir HAIKU_TOP src kits package ;
|
||||
|
||||
UsePrivateHeaders
|
||||
app
|
||||
kernel
|
||||
shared
|
||||
storage
|
||||
|
@ -31,6 +31,8 @@
|
||||
|
||||
#if defined(__HAIKU__) && !defined(HAIKU_HOST_PLATFORM_HAIKU)
|
||||
# include <package/DaemonClient.h>
|
||||
# include <RegistrarDefs.h>
|
||||
# include <RosterPrivate.h>
|
||||
#endif
|
||||
|
||||
|
||||
@ -225,6 +227,74 @@ BPackageRoster::GetActivePackages(BPackageInstallationLocation location,
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BPackageRoster::StartWatching(const BMessenger& target, uint32 eventMask)
|
||||
{
|
||||
// This method makes sense only on an installed Haiku, but not for the build
|
||||
// tools.
|
||||
#if defined(__HAIKU__) && !defined(HAIKU_HOST_PLATFORM_HAIKU)
|
||||
// compose the registrar request
|
||||
BMessage request(::BPrivate::B_REG_PACKAGE_START_WATCHING);
|
||||
status_t error;
|
||||
if ((error = request.AddMessenger("target", target)) != B_OK
|
||||
|| (error = request.AddUInt32("events", eventMask)) != B_OK) {
|
||||
return error;
|
||||
}
|
||||
|
||||
// send it
|
||||
BMessage reply;
|
||||
error = BRoster::Private().SendTo(&request, &reply, false);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// get result
|
||||
if (reply.what != ::BPrivate::B_REG_SUCCESS) {
|
||||
int32 result;
|
||||
if (reply.FindInt32("error", &result) != B_OK)
|
||||
result = B_ERROR;
|
||||
return (status_t)error;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
#else
|
||||
return B_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BPackageRoster::StopWatching(const BMessenger& target)
|
||||
{
|
||||
// This method makes sense only on an installed Haiku, but not for the build
|
||||
// tools.
|
||||
#if defined(__HAIKU__) && !defined(HAIKU_HOST_PLATFORM_HAIKU)
|
||||
// compose the registrar request
|
||||
BMessage request(::BPrivate::B_REG_PACKAGE_STOP_WATCHING);
|
||||
status_t error = request.AddMessenger("target", target);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// send it
|
||||
BMessage reply;
|
||||
error = BRoster::Private().SendTo(&request, &reply, false);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// get result
|
||||
if (reply.what != ::BPrivate::B_REG_SUCCESS) {
|
||||
int32 result;
|
||||
if (reply.FindInt32("error", &result) != B_OK)
|
||||
result = B_ERROR;
|
||||
return (status_t)error;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
#else
|
||||
return B_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BPackageRoster::_GetRepositoryPath(BPath* path, bool create,
|
||||
directory_which whichDir) const
|
||||
|
@ -22,8 +22,10 @@
|
||||
#include <MessageRunner.h>
|
||||
#include <NodeMonitor.h>
|
||||
#include <Path.h>
|
||||
#include <Roster.h>
|
||||
|
||||
#include <package/CommitTransactionResult.h>
|
||||
#include <package/PackageRoster.h>
|
||||
#include <package/solver/Solver.h>
|
||||
#include <package/solver/SolverPackage.h>
|
||||
#include <package/solver/SolverProblem.h>
|
||||
@ -35,12 +37,14 @@
|
||||
#include <AutoLocker.h>
|
||||
#include <NotOwningEntryRef.h>
|
||||
#include <package/DaemonDefs.h>
|
||||
#include <RosterPrivate.h>
|
||||
|
||||
#include "CommitTransactionHandler.h"
|
||||
#include "Constants.h"
|
||||
#include "DebugSupport.h"
|
||||
#include "Exception.h"
|
||||
#include "PackageFileManager.h"
|
||||
#include "Root.h"
|
||||
#include "VolumeState.h"
|
||||
|
||||
|
||||
@ -1193,6 +1197,19 @@ Volume::_SetLatestState(VolumeState* state, bool isActive)
|
||||
delete fLatestState;
|
||||
fLatestState = state;
|
||||
fChangeCount++;
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
// Send a notification, if this is a system root volume.
|
||||
if (fRoot->IsSystemRoot()) {
|
||||
BMessage message(B_PACKAGE_UPDATE);
|
||||
if (message.AddInt32("event",
|
||||
(int32)B_INSTALLATION_LOCATION_PACKAGES_CHANGED) == B_OK
|
||||
&& message.AddInt32("location", (int32)Location()) == B_OK
|
||||
&& message.AddInt64("change count", fChangeCount) == B_OK) {
|
||||
BRoster::Private().SendTo(&message, NULL, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,6 +27,7 @@ Server registrar
|
||||
MessageRunnerManager.cpp
|
||||
MessagingService.cpp
|
||||
MIMEManager.cpp
|
||||
PackageWatchingManager.cpp
|
||||
PriorityMessageQueue.cpp
|
||||
RecentApps.cpp
|
||||
RecentEntries.cpp
|
||||
|
107
src/servers/registrar/PackageWatchingManager.cpp
Normal file
107
src/servers/registrar/PackageWatchingManager.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2014, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "PackageWatchingManager.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <package/PackageRoster.h>
|
||||
|
||||
#include <RegistrarDefs.h>
|
||||
|
||||
#include "Debug.h"
|
||||
#include "EventMaskWatcher.h"
|
||||
|
||||
|
||||
using namespace BPackageKit;
|
||||
using namespace BPrivate;
|
||||
|
||||
|
||||
PackageWatchingManager::PackageWatchingManager()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PackageWatchingManager::~PackageWatchingManager()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageWatchingManager::HandleStartStopWatching(BMessage* request)
|
||||
{
|
||||
status_t error = request->what == B_REG_PACKAGE_START_WATCHING
|
||||
? _AddWatcher(request) : _RemoveWatcher(request);
|
||||
|
||||
if (error == B_OK) {
|
||||
BMessage reply(B_REG_SUCCESS);
|
||||
request->SendReply(&reply);
|
||||
} else {
|
||||
BMessage reply(B_REG_ERROR);
|
||||
reply.AddInt32("error", error);
|
||||
request->SendReply(&reply);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageWatchingManager::NotifyWatchers(BMessage* message)
|
||||
{
|
||||
int32 event;
|
||||
if (message->FindInt32("event", &event) != B_OK) {
|
||||
WARNING("No event field in notification message\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 eventMask;
|
||||
switch (event) {
|
||||
case B_INSTALLATION_LOCATION_PACKAGES_CHANGED:
|
||||
eventMask = B_WATCH_PACKAGE_INSTALLATION_LOCATIONS;
|
||||
break;
|
||||
default:
|
||||
WARNING("Invalid event: %" B_PRId32 "\n", event);
|
||||
return;
|
||||
}
|
||||
|
||||
EventMaskWatcherFilter filter(eventMask);
|
||||
fWatchingService.NotifyWatchers(message, &filter);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PackageWatchingManager::_AddWatcher(const BMessage* request)
|
||||
{
|
||||
BMessenger target;
|
||||
uint32 eventMask;
|
||||
status_t error;
|
||||
if ((error = request->FindMessenger("target", &target)) != B_OK
|
||||
|| (error = request->FindUInt32("events", &eventMask)) != B_OK) {
|
||||
return error;
|
||||
}
|
||||
|
||||
Watcher* watcher = new(std::nothrow) EventMaskWatcher(target, eventMask);
|
||||
if (watcher == NULL || !fWatchingService.AddWatcher(watcher)) {
|
||||
delete watcher;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PackageWatchingManager::_RemoveWatcher(const BMessage* request)
|
||||
{
|
||||
BMessenger target;
|
||||
status_t error;
|
||||
if ((error = request->FindMessenger("target", &target)) != B_OK)
|
||||
return error;
|
||||
|
||||
if (!fWatchingService.RemoveWatcher(target))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
return B_OK;
|
||||
}
|
29
src/servers/registrar/PackageWatchingManager.h
Normal file
29
src/servers/registrar/PackageWatchingManager.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2014, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef PACKAGE_WATCHING_MANAGER_H
|
||||
#define PACKAGE_WATCHING_MANAGER_H
|
||||
|
||||
|
||||
#include "WatchingService.h"
|
||||
|
||||
|
||||
class PackageWatchingManager {
|
||||
public:
|
||||
PackageWatchingManager();
|
||||
~PackageWatchingManager();
|
||||
|
||||
void HandleStartStopWatching(BMessage* request);
|
||||
void NotifyWatchers(BMessage* message);
|
||||
|
||||
private:
|
||||
status_t _AddWatcher(const BMessage* request);
|
||||
status_t _RemoveWatcher(const BMessage* request);
|
||||
|
||||
private:
|
||||
WatchingService fWatchingService;
|
||||
};
|
||||
|
||||
|
||||
#endif // PACKAGE_WATCHING_MANAGER_H
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2009, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2014, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@ -29,6 +29,7 @@
|
||||
#include "MessageRunnerManager.h"
|
||||
#include "MessagingService.h"
|
||||
#include "MIMEManager.h"
|
||||
#include "PackageWatchingManager.h"
|
||||
#include "ShutdownProcess.h"
|
||||
#include "TRoster.h"
|
||||
|
||||
@ -64,7 +65,8 @@ Registrar::Registrar(status_t *error)
|
||||
fMessageRunnerManager(NULL),
|
||||
fSanityEvent(NULL),
|
||||
fShutdownProcess(NULL),
|
||||
fAuthenticationManager(NULL)
|
||||
fAuthenticationManager(NULL),
|
||||
fPackageWatchingManager(NULL)
|
||||
{
|
||||
FUNCTION_START();
|
||||
|
||||
@ -83,6 +85,7 @@ Registrar::~Registrar()
|
||||
Lock();
|
||||
fEventQueue->Die();
|
||||
delete fAuthenticationManager;
|
||||
delete fPackageWatchingManager;
|
||||
delete fMessageRunnerManager;
|
||||
delete fEventQueue;
|
||||
delete fSanityEvent;
|
||||
@ -166,6 +169,9 @@ Registrar::ReadyToRun()
|
||||
"(that's by design when running under R5): %s\n", strerror(error));
|
||||
}
|
||||
|
||||
// create the package watching manager
|
||||
fPackageWatchingManager = new PackageWatchingManager;
|
||||
|
||||
// create and schedule the sanity message event
|
||||
fSanityEvent = new MessageEvent(system_time() + kRosterSanityEventInterval,
|
||||
this, B_REG_ROSTER_SANITY_EVENT);
|
||||
@ -336,6 +342,15 @@ Registrar::_MessageReceived(BMessage *message)
|
||||
fMessageRunnerManager->HandleGetRunnerInfo(message);
|
||||
break;
|
||||
|
||||
// package watching requests
|
||||
case B_REG_PACKAGE_START_WATCHING:
|
||||
case B_REG_PACKAGE_STOP_WATCHING:
|
||||
fPackageWatchingManager->HandleStartStopWatching(message);
|
||||
break;
|
||||
case B_PACKAGE_UPDATE:
|
||||
fPackageWatchingManager->NotifyWatchers(message);
|
||||
break;
|
||||
|
||||
// internal messages
|
||||
case B_REG_ROSTER_SANITY_EVENT:
|
||||
fRoster->CheckSanity();
|
||||
|
@ -36,6 +36,7 @@ class EventQueue;
|
||||
class MessageEvent;
|
||||
class MessageRunnerManager;
|
||||
class MIMEManager;
|
||||
class PackageWatchingManager;
|
||||
class ShutdownProcess;
|
||||
|
||||
class TRoster;
|
||||
@ -66,6 +67,7 @@ private:
|
||||
MessageEvent *fSanityEvent;
|
||||
ShutdownProcess *fShutdownProcess;
|
||||
AuthenticationManager *fAuthenticationManager;
|
||||
PackageWatchingManager *fPackageWatchingManager;
|
||||
};
|
||||
|
||||
#endif // REGISTRAR_H
|
||||
|
Loading…
Reference in New Issue
Block a user