1/*
2 * Copyright 2014, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "PackageWatchingManager.h"
8
9#include <new>
10
11#include <package/PackageRoster.h>
12
13#include <RegistrarDefs.h>
14
15#include "Debug.h"
16#include "EventMaskWatcher.h"
17
18
19using namespace BPackageKit;
20using namespace BPrivate;
21
22
23PackageWatchingManager::PackageWatchingManager()
24{
25}
26
27
28PackageWatchingManager::~PackageWatchingManager()
29{
30}
31
32
33void
34PackageWatchingManager::HandleStartStopWatching(BMessage* request)
35{
36	status_t error = request->what == B_REG_PACKAGE_START_WATCHING
37		? _AddWatcher(request) : _RemoveWatcher(request);
38
39	if (error == B_OK) {
40		BMessage reply(B_REG_SUCCESS);
41		request->SendReply(&reply);
42	} else {
43		BMessage reply(B_REG_ERROR);
44		reply.AddInt32("error", error);
45		request->SendReply(&reply);
46	}
47}
48
49
50void
51PackageWatchingManager::NotifyWatchers(BMessage* message)
52{
53	int32 event;
54	if (message->FindInt32("event", &event) != B_OK) {
55		WARNING("No event field in notification message\n");
56		return;
57	}
58
59	uint32 eventMask;
60	switch (event) {
61		case B_INSTALLATION_LOCATION_PACKAGES_CHANGED:
62			eventMask = B_WATCH_PACKAGE_INSTALLATION_LOCATIONS;
63			break;
64		default:
65			WARNING("Invalid event: %" B_PRId32 "\n", event);
66			return;
67	}
68
69	EventMaskWatcherFilter filter(eventMask);
70    fWatchingService.NotifyWatchers(message, &filter);
71}
72
73
74status_t
75PackageWatchingManager::_AddWatcher(const BMessage* request)
76{
77	BMessenger target;
78	uint32 eventMask;
79	status_t error;
80	if ((error = request->FindMessenger("target", &target)) != B_OK
81		|| (error = request->FindUInt32("events", &eventMask)) != B_OK) {
82		return error;
83	}
84
85	Watcher* watcher = new(std::nothrow) EventMaskWatcher(target, eventMask);
86	if (watcher == NULL || !fWatchingService.AddWatcher(watcher)) {
87		delete watcher;
88		return B_NO_MEMORY;
89	}
90
91	return B_OK;
92}
93
94
95status_t
96PackageWatchingManager::_RemoveWatcher(const BMessage* request)
97{
98	BMessenger target;
99	status_t error;
100	if ((error = request->FindMessenger("target", &target)) != B_OK)
101		return error;
102
103	if (!fWatchingService.RemoveWatcher(target))
104		return B_BAD_VALUE;
105
106	return B_OK;
107}
108