15c9672edSIngo Weinhold/*
25c9672edSIngo Weinhold * Copyright 2014, Ingo Weinhold, ingo_weinhold@gmx.de.
35c9672edSIngo Weinhold * Distributed under the terms of the MIT License.
45c9672edSIngo Weinhold */
55c9672edSIngo Weinhold
65c9672edSIngo Weinhold
75c9672edSIngo Weinhold#include "PackageWatchingManager.h"
85c9672edSIngo Weinhold
95c9672edSIngo Weinhold#include <new>
105c9672edSIngo Weinhold
115c9672edSIngo Weinhold#include <package/PackageRoster.h>
125c9672edSIngo Weinhold
135c9672edSIngo Weinhold#include <RegistrarDefs.h>
145c9672edSIngo Weinhold
155c9672edSIngo Weinhold#include "Debug.h"
165c9672edSIngo Weinhold#include "EventMaskWatcher.h"
175c9672edSIngo Weinhold
185c9672edSIngo Weinhold
195c9672edSIngo Weinholdusing namespace BPackageKit;
205c9672edSIngo Weinholdusing namespace BPrivate;
215c9672edSIngo Weinhold
225c9672edSIngo Weinhold
235c9672edSIngo WeinholdPackageWatchingManager::PackageWatchingManager()
245c9672edSIngo Weinhold{
255c9672edSIngo Weinhold}
265c9672edSIngo Weinhold
275c9672edSIngo Weinhold
285c9672edSIngo WeinholdPackageWatchingManager::~PackageWatchingManager()
295c9672edSIngo Weinhold{
305c9672edSIngo Weinhold}
315c9672edSIngo Weinhold
325c9672edSIngo Weinhold
335c9672edSIngo Weinholdvoid
345c9672edSIngo WeinholdPackageWatchingManager::HandleStartStopWatching(BMessage* request)
355c9672edSIngo Weinhold{
365c9672edSIngo Weinhold	status_t error = request->what == B_REG_PACKAGE_START_WATCHING
375c9672edSIngo Weinhold		? _AddWatcher(request) : _RemoveWatcher(request);
385c9672edSIngo Weinhold
395c9672edSIngo Weinhold	if (error == B_OK) {
405c9672edSIngo Weinhold		BMessage reply(B_REG_SUCCESS);
415c9672edSIngo Weinhold		request->SendReply(&reply);
425c9672edSIngo Weinhold	} else {
435c9672edSIngo Weinhold		BMessage reply(B_REG_ERROR);
445c9672edSIngo Weinhold		reply.AddInt32("error", error);
455c9672edSIngo Weinhold		request->SendReply(&reply);
465c9672edSIngo Weinhold	}
475c9672edSIngo Weinhold}
485c9672edSIngo Weinhold
495c9672edSIngo Weinhold
505c9672edSIngo Weinholdvoid
515c9672edSIngo WeinholdPackageWatchingManager::NotifyWatchers(BMessage* message)
525c9672edSIngo Weinhold{
535c9672edSIngo Weinhold	int32 event;
545c9672edSIngo Weinhold	if (message->FindInt32("event", &event) != B_OK) {
555c9672edSIngo Weinhold		WARNING("No event field in notification message\n");
565c9672edSIngo Weinhold		return;
575c9672edSIngo Weinhold	}
585c9672edSIngo Weinhold
595c9672edSIngo Weinhold	uint32 eventMask;
605c9672edSIngo Weinhold	switch (event) {
615c9672edSIngo Weinhold		case B_INSTALLATION_LOCATION_PACKAGES_CHANGED:
625c9672edSIngo Weinhold			eventMask = B_WATCH_PACKAGE_INSTALLATION_LOCATIONS;
635c9672edSIngo Weinhold			break;
645c9672edSIngo Weinhold		default:
655c9672edSIngo Weinhold			WARNING("Invalid event: %" B_PRId32 "\n", event);
665c9672edSIngo Weinhold			return;
675c9672edSIngo Weinhold	}
685c9672edSIngo Weinhold
695c9672edSIngo Weinhold	EventMaskWatcherFilter filter(eventMask);
705c9672edSIngo Weinhold    fWatchingService.NotifyWatchers(message, &filter);
715c9672edSIngo Weinhold}
725c9672edSIngo Weinhold
735c9672edSIngo Weinhold
745c9672edSIngo Weinholdstatus_t
755c9672edSIngo WeinholdPackageWatchingManager::_AddWatcher(const BMessage* request)
765c9672edSIngo Weinhold{
775c9672edSIngo Weinhold	BMessenger target;
785c9672edSIngo Weinhold	uint32 eventMask;
795c9672edSIngo Weinhold	status_t error;
805c9672edSIngo Weinhold	if ((error = request->FindMessenger("target", &target)) != B_OK
815c9672edSIngo Weinhold		|| (error = request->FindUInt32("events", &eventMask)) != B_OK) {
825c9672edSIngo Weinhold		return error;
835c9672edSIngo Weinhold	}
845c9672edSIngo Weinhold
855c9672edSIngo Weinhold	Watcher* watcher = new(std::nothrow) EventMaskWatcher(target, eventMask);
865c9672edSIngo Weinhold	if (watcher == NULL || !fWatchingService.AddWatcher(watcher)) {
875c9672edSIngo Weinhold		delete watcher;
885c9672edSIngo Weinhold		return B_NO_MEMORY;
895c9672edSIngo Weinhold	}
905c9672edSIngo Weinhold
915c9672edSIngo Weinhold	return B_OK;
925c9672edSIngo Weinhold}
935c9672edSIngo Weinhold
945c9672edSIngo Weinhold
955c9672edSIngo Weinholdstatus_t
965c9672edSIngo WeinholdPackageWatchingManager::_RemoveWatcher(const BMessage* request)
975c9672edSIngo Weinhold{
985c9672edSIngo Weinhold	BMessenger target;
995c9672edSIngo Weinhold	status_t error;
1005c9672edSIngo Weinhold	if ((error = request->FindMessenger("target", &target)) != B_OK)
1015c9672edSIngo Weinhold		return error;
1025c9672edSIngo Weinhold
1035c9672edSIngo Weinhold	if (!fWatchingService.RemoveWatcher(target))
1045c9672edSIngo Weinhold		return B_BAD_VALUE;
1055c9672edSIngo Weinhold
1065c9672edSIngo Weinhold	return B_OK;
1075c9672edSIngo Weinhold}
108