* Added DefaultNotificationService and DefaultUserNotificationService
implementations that can be used by subsystems that want to have a pretty standard service. Only the latter is really complete, though. * The notification manager is now available earlier in the boot process. * Added notifications to teams/ports (only add/remove). * The network notification implementation is now using the DefaultUserNotificationService. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29543 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2007, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2007-2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -10,11 +10,13 @@
|
||||
|
||||
#include <Notifications.h>
|
||||
|
||||
#include <team.h>
|
||||
|
||||
|
||||
NotificationManager NotificationManager::sManager;
|
||||
|
||||
|
||||
// #pragma mark - UserMessagingListener
|
||||
// #pragma mark - NotificationListener
|
||||
|
||||
|
||||
NotificationListener::~NotificationListener()
|
||||
@@ -123,6 +125,316 @@ NotificationService::~NotificationService()
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - default_listener
|
||||
|
||||
|
||||
default_listener::~default_listener()
|
||||
{
|
||||
// Only delete the listener if it's one of ours
|
||||
if (dynamic_cast<UserMessagingListener*>(listener) != NULL) {
|
||||
delete listener;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - NotificationService
|
||||
|
||||
|
||||
DefaultNotificationService::DefaultNotificationService(const char* name)
|
||||
:
|
||||
fName(name)
|
||||
{
|
||||
recursive_lock_init(&fLock, name);
|
||||
NotificationManager::Manager().RegisterService(*this);
|
||||
}
|
||||
|
||||
|
||||
DefaultNotificationService::~DefaultNotificationService()
|
||||
{
|
||||
NotificationManager::Manager().UnregisterService(*this);
|
||||
recursive_lock_destroy(&fLock);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Notifies all registered listeners.
|
||||
\param event The message defining the event
|
||||
\param flags The flags that must be set in listeners to receive this event
|
||||
*/
|
||||
void
|
||||
DefaultNotificationService::Notify(const KMessage& event, uint32 flags)
|
||||
{
|
||||
RecursiveLocker _(fLock);
|
||||
|
||||
DefaultListenerList::Iterator iterator = fListeners.GetIterator();
|
||||
while (default_listener* listener = iterator.Next()) {
|
||||
if ((flags & listener->flags) != 0)
|
||||
listener->listener->EventOccured(*this, &event);
|
||||
}
|
||||
|
||||
iterator = fListeners.GetIterator();
|
||||
while (default_listener* listener = iterator.Next()) {
|
||||
if ((flags & listener->flags) != 0)
|
||||
listener->listener->AllListenersNotified(*this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DefaultNotificationService::AddListener(const KMessage* eventSpecifier,
|
||||
NotificationListener& notificationListener)
|
||||
{
|
||||
if (eventSpecifier == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
uint32 flags;
|
||||
status_t status = _ToFlags(*eventSpecifier, flags);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
default_listener* listener = new(std::nothrow) default_listener;
|
||||
if (listener == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
listener->flags = flags;
|
||||
listener->team = -1;
|
||||
listener->listener = ¬ificationListener;
|
||||
|
||||
RecursiveLocker _(fLock);
|
||||
if (fListeners.IsEmpty())
|
||||
_FirstAdded();
|
||||
fListeners.Add(listener);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DefaultNotificationService::UpdateListener(const KMessage* eventSpecifier,
|
||||
NotificationListener& notificationListener)
|
||||
{
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DefaultNotificationService::RemoveListener(const KMessage* eventSpecifier,
|
||||
NotificationListener& notificationListener)
|
||||
{
|
||||
RecursiveLocker _(fLock);
|
||||
|
||||
DefaultListenerList::Iterator iterator = fListeners.GetIterator();
|
||||
while (default_listener* listener = iterator.Next()) {
|
||||
if (listener->listener == ¬ificationListener) {
|
||||
iterator.Remove();
|
||||
delete listener;
|
||||
|
||||
if (fListeners.IsEmpty())
|
||||
_LastRemoved();
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DefaultNotificationService::_ToFlags(const KMessage& eventSpecifier,
|
||||
uint32& flags)
|
||||
{
|
||||
return eventSpecifier.FindInt32("flags", (int32*)&flags);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DefaultNotificationService::_FirstAdded()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DefaultNotificationService::_LastRemoved()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - DefaultUserNotificationService
|
||||
|
||||
|
||||
DefaultUserNotificationService::DefaultUserNotificationService(const char* name)
|
||||
: DefaultNotificationService(name)
|
||||
{
|
||||
NotificationManager::Manager().AddListener("teams", TEAM_REMOVED, *this);
|
||||
}
|
||||
|
||||
|
||||
DefaultUserNotificationService::~DefaultUserNotificationService()
|
||||
{
|
||||
NotificationManager::Manager().RemoveListener("teams", NULL, *this);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DefaultUserNotificationService::AddListener(const KMessage* eventSpecifier,
|
||||
NotificationListener& listener)
|
||||
{
|
||||
if (eventSpecifier == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
uint32 flags = eventSpecifier->GetInt32("flags", 0);
|
||||
|
||||
return _AddListener(flags, listener);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DefaultUserNotificationService::UpdateListener(const KMessage* eventSpecifier,
|
||||
NotificationListener& notificationListener)
|
||||
{
|
||||
if (eventSpecifier == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
uint32 flags = eventSpecifier->GetInt32("flags", 0);
|
||||
bool addFlags = eventSpecifier->GetBool("add flags", false);
|
||||
|
||||
RecursiveLocker _(fLock);
|
||||
|
||||
DefaultListenerList::Iterator iterator = fListeners.GetIterator();
|
||||
while (default_listener* listener = iterator.Next()) {
|
||||
if (*listener->listener == notificationListener) {
|
||||
if (addFlags)
|
||||
listener->flags |= flags;
|
||||
else
|
||||
listener->flags = flags;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DefaultUserNotificationService::RemoveListener(const KMessage* eventSpecifier,
|
||||
NotificationListener& notificationListener)
|
||||
{
|
||||
RecursiveLocker _(fLock);
|
||||
|
||||
DefaultListenerList::Iterator iterator = fListeners.GetIterator();
|
||||
while (default_listener* listener = iterator.Next()) {
|
||||
if (listener->listener == ¬ificationListener) {
|
||||
iterator.Remove();
|
||||
delete listener;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DefaultUserNotificationService::RemoveUserListeners(port_id port, uint32 token)
|
||||
{
|
||||
UserMessagingListener userListener(fSender, port, token);
|
||||
|
||||
RecursiveLocker _(fLock);
|
||||
|
||||
DefaultListenerList::Iterator iterator = fListeners.GetIterator();
|
||||
while (default_listener* listener = iterator.Next()) {
|
||||
if (*listener->listener == userListener) {
|
||||
iterator.Remove();
|
||||
delete listener;
|
||||
|
||||
if (fListeners.IsEmpty())
|
||||
_LastRemoved();
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DefaultUserNotificationService::UpdateUserListener(uint32 flags, port_id port,
|
||||
uint32 token)
|
||||
{
|
||||
UserMessagingListener userListener(fSender, port, token);
|
||||
|
||||
RecursiveLocker _(fLock);
|
||||
|
||||
DefaultListenerList::Iterator iterator = fListeners.GetIterator();
|
||||
while (default_listener* listener = iterator.Next()) {
|
||||
if (*listener->listener == userListener) {
|
||||
listener->flags |= flags;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
UserMessagingListener* copiedListener
|
||||
= new(std::nothrow) UserMessagingListener(userListener);
|
||||
if (copiedListener == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t status = _AddListener(flags, *copiedListener);
|
||||
if (status != B_OK)
|
||||
delete copiedListener;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DefaultUserNotificationService::EventOccured(NotificationService& service,
|
||||
const KMessage* event)
|
||||
{
|
||||
int32 opcode = event->GetInt32("opcode", -1);
|
||||
team_id team = event->GetInt32("team", -1);
|
||||
|
||||
if (opcode == TEAM_REMOVED && team >= B_OK) {
|
||||
// check if we have any listeners from that team, and remove them
|
||||
RecursiveLocker _(fLock);
|
||||
|
||||
DefaultListenerList::Iterator iterator = fListeners.GetIterator();
|
||||
while (default_listener* listener = iterator.Next()) {
|
||||
if (listener->team == team) {
|
||||
iterator.Remove();
|
||||
delete listener;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DefaultUserNotificationService::AllListenersNotified(
|
||||
NotificationService& service)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DefaultUserNotificationService::_AddListener(uint32 flags,
|
||||
NotificationListener& notificationListener)
|
||||
{
|
||||
default_listener* listener = new(std::nothrow) default_listener;
|
||||
if (listener == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
listener->flags = flags;
|
||||
listener->team = team_get_current_team_id();
|
||||
listener->listener = ¬ificationListener;
|
||||
|
||||
RecursiveLocker _(fLock);
|
||||
if (fListeners.IsEmpty())
|
||||
_FirstAdded();
|
||||
fListeners.Add(listener);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - NotificationManager
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user