changed media kit internal messaging and notification support

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1338 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper
2002-10-02 01:04:48 +00:00
parent 398e73f23b
commit f492510482
17 changed files with 639 additions and 545 deletions
+81
View File
@@ -0,0 +1,81 @@
/*
* Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _DATA_EXCHANGE_H
#define _DATA_EXCHANGE_H
#include <MediaDefs.h>
#include <MediaNode.h>
#include <MediaAddOn.h>
#include <Entry.h>
namespace BPrivate {
namespace media {
namespace dataexchange {
struct reply_data;
struct request_data;
// BMessage based data exchange with the media_server
status_t SendToServer(BMessage *msg);
status_t QueryServer(BMessage *request, BMessage *reply);
// BMessage based data exchange with the media_addon_server
status_t SendToAddonServer(BMessage *msg);
// Raw data based data exchange with the media_server
status_t SendToServer(int32 msgcode, void *msg, int size);
status_t QueryServer(int32 msgcode, const request_data *request, int requestsize, reply_data *reply, int replysize);
// Raw data based data exchange with the media_addon_server
status_t SendToAddonServer(int32 msgcode, void *msg, int size);
status_t QueryAddonServer(int32 msgcode, const request_data *request, int requestsize, reply_data *reply, int replysize);
// Raw data based data exchange with the media_server
status_t SendToPort(port_id sendport, int32 msgcode, void *msg, int size);
status_t QueryPort(port_id requestport, int32 msgcode, const request_data *request, int requestsize, reply_data *reply, int replysize);
// The base struct used for all raw requests
struct request_data
{
port_id reply_port;
void SendReply(reply_data *reply, int replysize) const;
};
// The base struct used for all raw replys
struct reply_data
{
status_t result;
};
}; // dataexchange
}; // media
}; // BPrivate
using namespace BPrivate::media::dataexchange;
enum {
// BMediaRoster notification service
MEDIA_SERVER_REQUEST_NOTIFICATIONS = 1000,
MEDIA_SERVER_CANCEL_NOTIFICATIONS,
MEDIA_SERVER_SEND_NOTIFICATIONS
};
struct request_addonserver_instantiate_dormant_node : public request_data
{
dormant_node_info info;
};
struct reply_addonserver_instantiate_dormant_node : public reply_data
{
media_node node;
};
#endif // _DATA_EXCHANGE_H
@@ -1,79 +0,0 @@
/*
* Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _NOTIFICATION_MANAGER_H
#define _NOTIFICATION_MANAGER_H
namespace BPrivate {
namespace media {
class NotificationManager
{
public:
enum notification_type_mask
{
notification_no_mask = 0,
notification_node_created = (1 << 0),
notification_node_deleted = (1 << 1),
notification_connection_made = (1 << 2),
notification_connection_broken = (1 << 3),
notification_buffer_created = (1 << 4),
notification_buffer_deleted = (1 << 5),
notification_transport_state = (1 << 6),
notification_parameter_changed = (1 << 7),
notification_format_change = (1 << 8),
notification_web_changed = (1 << 9),
notification_default_changed = (1 << 10),
notification_new_parameter_value= (1 << 11),
notification_node_stopped = (1 << 12),
notification_flavors_changed = (1 << 13),
notification_error = (1 << 31), // XXX, um well... always allow error notifications? Handled in the server
notification_basic = (notification_node_created | notification_node_deleted | notification_connection_made | notification_connection_broken),
notification_wildcard = (0xffffffff - notification_error) // exclude error, it is handled in the server
};
public:
NotificationManager();
~NotificationManager();
status_t Register(const BMessenger &notifyHandler, const media_node &node, notification_type_mask mask);
status_t Unregister(const BMessenger &notifyHandler, const media_node &node, notification_type_mask mask);
status_t ReportError(const media_node &node, BMediaNode::node_error what, const BMessage * info);
void NodesCreated(const media_node_id *ids, int32 count);
void NodesDeleted(const media_node_id *ids, int32 count);
void ConnectionMade(const media_input &input, const media_output &output, const media_format &format);
void ConnectionBroken(const media_source &source, const media_destination &destination);
void BuffersCreated(); // XXX fix
void BuffersDeleted(const media_buffer_id *ids, int32 count);
// XXX header file lists: B_MEDIA_TRANSPORT_STATE, /* "state", "location", "realtime" */
void FormatChanged(const media_source &source, const media_destination &destination, const media_format &format);
status_t ParameterChanged(const media_node &node, int32 parameterid);
void WebChanged(const media_node &node); // XXX fix
// XXX header file lists: B_MEDIA_DEFAULT_CHANGED /* "default", "node" -- handled by BMediaRoster */
status_t NewParameterValue(const media_node &node, int32 parameterid, bigtime_t when, const void *param, size_t paramsize);
void FlavorsChanged(media_addon_id addonis, int32 newcount, int32 gonecount);
void NodeStopped(const media_node &node, bigtime_t when); // XXX fix
static bool IsValidNotificationType(int32 notificationType);
static notification_type_mask NotificationType2Mask(int32 notificationType);
private:
status_t SendMessageToMediaServer(BMessage *msg);
private:
BMessenger *fMessenger;
};
}; // namespace media
}; // namespace BPrivate
#define NOTIFICATION_PARAM_WHAT "be:media:internal:what"
#define NOTIFICATION_PARAM_MASK "be:media:internal:mask"
extern BPrivate::media::NotificationManager *_NotificationManager;
#endif // _NOTIFICATION_MANAGER_H
+87
View File
@@ -0,0 +1,87 @@
/*
* Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _NOTIFICATIONS_H
#define _NOTIFICATIONS_H
namespace BPrivate {
namespace media {
namespace notifications {
/*
* This are the possible notifications that can be watched.
* The notifications marked with "N" are only send when the
* media_node specific BMediaRoster::StartWatching() is used
* and the notification belongs to the watched node.
*
* In addition, anyone watching a specific node will also receive
* error notifications generated by BMediaNode::ReportError()
*
* B_MEDIA_WILDCARD used to match any notification in Start/StopWatching
* B_MEDIA_NODE_CREATED "media_node_id" (multiple items)
* B_MEDIA_NODE_DELETED "media_node_id" (multiple items)
* B_MEDIA_CONNECTION_MADE "output", "input", "format"
* B_MEDIA_CONNECTION_BROKEN "source", "destination"
* B_MEDIA_BUFFER_CREATED "clone_info" -- handled by BMediaRoster
* B_MEDIA_BUFFER_DELETED "media_buffer_id" -- handled by BMediaRoster
* B_MEDIA_TRANSPORT_STATE "state", "location", "realtime"
* B_MEDIA_PARAMETER_CHANGED N "node", "parameter"
* B_MEDIA_FORMAT_CHANGED N "source", "destination", "format"
* B_MEDIA_WEB_CHANGED N "node"
* B_MEDIA_DEFAULT_CHANGED "default", "node" -- handled by BMediaRoster
* B_MEDIA_NEW_PARAMETER_VALUE N "node", "parameter", "when", "value"
* B_MEDIA_NODE_STOPPED N "node", "when"
* B_MEDIA_FLAVORS_CHANGED "be:addon_id", "be:new_count", "be:gone_count"
*/
// used for BMediaRoster::StartWatching() parameter validation
bool IsValidNotificationRequest(bool node_specific, int32 notification);
// called by BMediaRoster::StartWatching()
status_t Register(const BMessenger &notifyHandler, const media_node &node, int32 notification);
// called by BMediaRoster::StopWatching()
status_t Unregister(const BMessenger &notifyHandler, const media_node &node, int32 notification);
// called by BMediaNode::ReportError()
status_t ReportError(const media_node &node, BMediaNode::node_error what, const BMessage * info);
void NodesCreated(const media_node_id *ids, int32 count);
void NodesDeleted(const media_node_id *ids, int32 count);
void ConnectionMade(const media_input &input, const media_output &output, const media_format &format);
void ConnectionBroken(const media_source &source, const media_destination &destination);
void BuffersCreated(area_info *areas, int32 count);
void BuffersDeleted(const media_buffer_id *ids, int32 count);
// called by BMediaNode::NodeStopped()
void NodeStopped(const media_node &node, bigtime_t when);
// called by BControllable::BroadcastChangedParameter()
status_t ParameterChanged(const media_node &node, int32 parameterid);
// called by BControllable::SetParameterWeb()
void WebChanged(const media_node &node);
// called by BControllable::BroadcastNewParameterValue()
status_t NewParameterValue(const media_node &node, int32 parameterid, bigtime_t when, const void *param, size_t paramsize);
// called by the media_addon_server AFTER a flavor change has been
// handled. NOT CALLED by BMediaAddOn::NotifyFlavorChange()
void FlavorsChanged(media_addon_id addonid, int32 newcount, int32 gonecount);
void FormatChanged(const media_source &source, const media_destination &destination, const media_format &format);
// XXX missing: B_MEDIA_TRANSPORT_STATE /* "state", "location", "realtime" */
// XXX missing: B_MEDIA_DEFAULT_CHANGED /* "default", "node" */
}; // namespace notifications
}; // namespace media
}; // namespace BPrivate
#define NOTIFICATION_PARAM_WHAT "be:media:internal:what"
#define NOTIFICATION_PARAM_TEAM "be:media:internal:team"
#define NOTIFICATION_PARAM_MESSENGER "be:media:internal:messenger"
#endif // _NOTIFICATIONS_H
+3 -3
View File
@@ -177,7 +177,7 @@ BBuffer::BBuffer(const buffer_clone_info & info) :
BMessage request(MEDIA_SERVER_GET_SHARED_BUFFER_AREA);
BMessage reply;
if (MediaKitPrivate::QueryServer(&request, &reply) != B_OK)
if (QueryServer(&request, &reply) != B_OK)
return;
id = reply.FindInt32("area");
@@ -204,7 +204,7 @@ BBuffer::BBuffer(const buffer_clone_info & info) :
// until the last buffer has been unregistered
// the area_id of the cached area is passed back to us, and we clone it.
if (MediaKitPrivate::QueryServer(&create, &response) != B_OK)
if (QueryServer(&create, &response) != B_OK)
return;
// the response from media server contains enough information
@@ -245,7 +245,7 @@ BBuffer::~BBuffer()
// when the last clone of this buffer is gone,
// media_server will also remove it's cached area
MediaKitPrivate::QueryServer(&unregister, &response);
QueryServer(&unregister, &response);
delete_area(fArea);
}
+1 -1
View File
@@ -37,7 +37,7 @@ BBufferGroup::InitBufferGroup()
BMessage request(MEDIA_SERVER_GET_SHARED_BUFFER_AREA);
BMessage reply;
fInitError = MediaKitPrivate::QueryServer(&request, &reply);
fInitError = QueryServer(&request, &reply);
if (fInitError != B_OK)
return fInitError;
+5 -3
View File
@@ -5,7 +5,7 @@
***********************************************************************/
#include <Controllable.h>
#include "debug.h"
#include "NotificationManager.h"
#include "Notifications.h"
/*************************************************************
* protected BControllable
@@ -60,6 +60,8 @@ status_t
BControllable::SetParameterWeb(BParameterWeb *web)
{
UNIMPLEMENTED();
BPrivate::media::notifications::WebChanged(Node());
return B_ERROR;
}
@@ -80,7 +82,7 @@ status_t
BControllable::BroadcastChangedParameter(int32 id)
{
CALLED();
return _NotificationManager->ParameterChanged(Node(), id);
return BPrivate::media::notifications::ParameterChanged(Node(), id);
}
@@ -91,7 +93,7 @@ BControllable::BroadcastNewParameterValue(bigtime_t when,
size_t valueSize)
{
CALLED();
return _NotificationManager->NewParameterValue(Node(), id, when, newValue, valueSize);
return BPrivate::media::notifications::NewParameterValue(Node(), id, when, newValue, valueSize);
}
+82
View File
@@ -0,0 +1,82 @@
/*
* Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include <OS.h>
#include "DataExchange.h"
namespace BPrivate {
namespace media {
team_id team;
namespace dataexchange {
void
request_data::SendReply(reply_data *reply, int replysize) const
{
}
// BMessage based data exchange with the media_server
status_t SendToServer(BMessage *msg)
{
return B_OK;
}
status_t QueryServer(BMessage *request, BMessage *reply)
{
return B_OK;
}
// BMessage based data exchange with the media_addon_server
status_t SendToAddonServer(BMessage *msg)
{
return B_OK;
}
// Raw data based data exchange with the media_server
status_t SendToServer(int32 msgcode, void *msg, int size)
{
return B_OK;
}
status_t QueryServer(int32 msgcode, const request_data *request, int requestsize, reply_data *reply, int replysize)
{
return B_OK;
}
// Raw data based data exchange with the media_addon_server
status_t SendToAddonServer(int32 msgcode, void *msg, int size)
{
return B_OK;
}
status_t QueryAddonServer(int32 msgcode, const request_data *request, int requestsize, reply_data *reply, int replysize)
{
return B_OK;
}
// Raw data based data exchange with the media_server
status_t SendToPort(port_id sendport, int32 msgcode, void *msg, int size)
{
return B_OK;
}
status_t QueryPort(port_id requestport, int32 msgcode, const request_data *request, int requestsize, reply_data *reply, int replysize)
{
return B_OK;
}
}; // dataexchange
}; // media
}; // BPrivate
+2 -1
View File
@@ -42,9 +42,10 @@ SharedLibrary media :
TimeSource.cpp
# Internal Functionality
DataExchange.cpp
PortPool.cpp
DormantNodeManager.cpp
NotificationManager.cpp
Notifications.cpp
SystemTimeSource.cpp
BufferIdCache.cpp
SharedBufferList.cpp
+20 -3
View File
@@ -14,7 +14,7 @@
#include "SystemTimeSource.h"
#include "debug.h"
#include "ServerInterface.h"
#include "NotificationManager.h"
#include "Notifications.h"
// don't rename this one, it's used and exported for binary compatibility
int32 BMediaNode::_m_changeTag = 0;
@@ -214,9 +214,26 @@ BMediaNode::ReportError(node_error what,
const BMessage *info)
{
CALLED();
// sanity check the what value
switch (what) {
case BMediaNode::B_NODE_FAILED_START:
case BMediaNode::B_NODE_FAILED_STOP:
case BMediaNode::B_NODE_FAILED_SEEK:
case BMediaNode::B_NODE_FAILED_SET_RUN_MODE:
case BMediaNode::B_NODE_FAILED_TIME_WARP:
case BMediaNode::B_NODE_FAILED_PREROLL:
case BMediaNode::B_NODE_FAILED_SET_TIME_SOURCE_FOR:
case BMediaNode::B_NODE_IN_DISTRESS:
break;
default:
TRACE("BMediaNode::ReportError: invalid what!\n");
return B_BAD_VALUE;
}
// Transmits the error code specified by what to anyone
// that's receiving notifications from this node
return _NotificationManager->ReportError(Node(), what, info);
return BPrivate::media::notifications::ReportError(Node(), what, info);
}
@@ -228,7 +245,7 @@ BMediaNode::NodeStopped(bigtime_t whenPerformance)
// finished handling a stop request.
// notify anyone who is listening for stop notifications!
_NotificationManager->NodeStopped(Node(), whenPerformance);
BPrivate::media::notifications::NodeStopped(Node(), whenPerformance);
// XXX If your node is a BBufferProducer, downstream consumers
// XXX will be notified that your node stopped (automatically, no less)
+29 -75
View File
@@ -16,11 +16,15 @@
#include "debug.h"
#include "PortPool.h"
#include "ServerInterface.h"
#include "DataExchange.h"
#include "DormantNodeManager.h"
#include "NotificationManager.h"
#include "Notifications.h"
static BMessenger *ServerMessenger = 0;
static team_id team;
using namespace BPrivate::media;
namespace BPrivate { namespace media {
extern team_id team;
}; };
// the BMediaRoster destructor is private,
// but _DefaultDeleter is a friend class of
@@ -31,48 +35,15 @@ public:
void Delete() { delete BMediaRoster::_sDefault; }
};
_DefaultDeleter _deleter;
namespace MediaKitPrivate
{
class RosterSingleton
{
public:
RosterSingleton()
{
thread_info info;
get_thread_info(find_thread(NULL), &info);
team = info.team;
ServerMessenger = new BMessenger(NEW_MEDIA_SERVER_SIGNATURE);
}
~RosterSingleton()
{
_DefaultDeleter deleter;
deleter.Delete(); // deletes BMediaRoster::_sDefault
delete ServerMessenger;
}
};
RosterSingleton singleton;
status_t GetNode(node_type type, media_node * out_node, int32 * out_input_id = NULL, BString * out_input_name = NULL);
status_t SetNode(node_type type, const media_node *node, const dormant_node_info *info = NULL, const media_input *input = NULL);
status_t QueryServer(BMessage *query, BMessage *reply)
{
status_t status;
status = ServerMessenger->SendMessage(query,reply);
if (status != B_OK || reply->what != B_OK) {
TRACE("QueryServer failed! status = 0x%08lx\n",status);
TRACE("Query:\n");
query->PrintToStream();
TRACE("Reply:\n");
reply->PrintToStream();
}
return status;
}
status_t GetNode(node_type type, media_node * out_node, int32 * out_input_id, BString * out_input_name)
{
if (out_node == NULL)
@@ -154,7 +125,7 @@ BMediaRoster::GetVideoInput(media_node * out_node)
return MediaKitPrivate::GetNode(VIDEO_INPUT, out_node);
}
status_t
BMediaRoster::GetAudioInput(media_node * out_node)
{
@@ -837,8 +808,7 @@ BMediaRoster::StartWatching(const BMessenger & where)
TRACE("BMediaRoster::StartWatching: messenger invalid!\n");
return B_BAD_VALUE;
}
return _NotificationManager->Register(where, media_node::null,
BPrivate::media::NotificationManager::notification_basic);
return BPrivate::media::notifications::Register(where, media_node::null, B_MEDIA_WILDCARD);
}
@@ -851,12 +821,11 @@ BMediaRoster::StartWatching(const BMessenger & where,
TRACE("BMediaRoster::StartWatching: messenger invalid!\n");
return B_BAD_VALUE;
}
if (!BPrivate::media::NotificationManager::IsValidNotificationType(notificationType)) {
if (false == BPrivate::media::notifications::IsValidNotificationRequest(false, notificationType)) {
TRACE("BMediaRoster::StartWatching: notificationType invalid!\n");
return B_BAD_VALUE;
}
return _NotificationManager->Register(where, media_node::null,
BPrivate::media::NotificationManager::NotificationType2Mask(notificationType));
return BPrivate::media::notifications::Register(where, media_node::null, notificationType);
}
@@ -874,12 +843,11 @@ BMediaRoster::StartWatching(const BMessenger & where,
TRACE("BMediaRoster::StartWatching: node invalid!\n");
return B_MEDIA_BAD_NODE;
}
if (!BPrivate::media::NotificationManager::IsValidNotificationType(notificationType)) {
if (false == BPrivate::media::notifications::IsValidNotificationRequest(true, notificationType)) {
TRACE("BMediaRoster::StartWatching: notificationType invalid!\n");
return B_BAD_VALUE;
}
return _NotificationManager->Register(where, node,
BPrivate::media::NotificationManager::NotificationType2Mask(notificationType));
return BPrivate::media::notifications::Register(where, node, notificationType);
}
@@ -888,8 +856,7 @@ BMediaRoster::StopWatching(const BMessenger & where)
{
CALLED();
// messenger may already be invalid, so we don't check this
return _NotificationManager->Unregister(where, media_node::null,
BPrivate::media::NotificationManager::notification_basic);
return BPrivate::media::notifications::Unregister(where, media_node::null, B_MEDIA_WILDCARD);
}
@@ -899,12 +866,11 @@ BMediaRoster::StopWatching(const BMessenger & where,
{
CALLED();
// messenger may already be invalid, so we don't check this
if (!BPrivate::media::NotificationManager::IsValidNotificationType(notificationType)) {
if (false == BPrivate::media::notifications::IsValidNotificationRequest(false, notificationType)) {
TRACE("BMediaRoster::StopWatching: notificationType invalid!\n");
return B_BAD_VALUE;
}
return _NotificationManager->Unregister(where, media_node::null,
BPrivate::media::NotificationManager::NotificationType2Mask(notificationType));
return BPrivate::media::notifications::Unregister(where, media_node::null, notificationType);
}
@@ -919,12 +885,11 @@ BMediaRoster::StopWatching(const BMessenger & where,
TRACE("BMediaRoster::StopWatching: node invalid!\n");
return B_MEDIA_BAD_NODE;
}
if (!BPrivate::media::NotificationManager::IsValidNotificationType(notificationType)) {
if (false == BPrivate::media::notifications::IsValidNotificationRequest(true, notificationType)) {
TRACE("BMediaRoster::StopWatching: notificationType invalid!\n");
return B_BAD_VALUE;
}
return _NotificationManager->Unregister(where, node,
BPrivate::media::NotificationManager::NotificationType2Mask(notificationType));
return BPrivate::media::notifications::Unregister(where, node, notificationType);
}
@@ -1106,27 +1071,16 @@ BMediaRoster::InstantiateDormantNode(const dormant_node_info & in_info,
// forward this request into the media_addon_server,
// which in turn will call InstantiateDormantNode()
// to create it there localy
xfer_addonserver_instantiate_dormant_node msg;
xfer_addonserver_instantiate_dormant_node_reply reply;
port_id port;
request_addonserver_instantiate_dormant_node request;
reply_addonserver_instantiate_dormant_node reply;
status_t rv;
int32 code;
port = find_port("media_addon_server port");
if (port <= B_OK)
return B_ERROR;
msg.info = in_info;
msg.reply_port = _PortPool->GetPort();
rv = write_port(port, ADDONSERVER_INSTANTIATE_DORMANT_NODE, &msg, sizeof(msg));
if (rv != B_OK) {
_PortPool->PutPort(msg.reply_port);
return rv;
request.info = in_info;
rv = QueryAddonServer(ADDONSERVER_INSTANTIATE_DORMANT_NODE, &request, sizeof(request), &reply, sizeof(reply));
if (rv == B_OK) {
*out_node = reply.node;
}
rv = read_port(msg.reply_port, &code, &reply, sizeof(reply));
_PortPool->PutPort(msg.reply_port);
if (rv < B_OK)
return rv;
*out_node = reply.node;
return reply.result;
return rv;
}
// XXX SOMETHING IS VERY WRONG HERE
@@ -1492,7 +1446,7 @@ BMediaRoster::~BMediaRoster()
BMessage msg(MEDIA_SERVER_UNREGISTER_APP);
BMessage reply;
msg.AddInt32("team",team);
ServerMessenger->SendMessage(&msg,&reply);
QueryServer(&msg, &reply);
}
@@ -1529,7 +1483,7 @@ BMediaRoster::BMediaRoster() :
BMessage msg(MEDIA_SERVER_REGISTER_APP);
BMessage reply;
msg.AddInt32("team",team);
ServerMessenger->SendMessage(&msg,&reply);
QueryServer(&msg,&reply);
}
/* static */ status_t
-336
View File
@@ -1,336 +0,0 @@
/*
* Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
/* This is a interface class for media kit notifications.
* It is private to the media kit which uses it to pass
* notifications up to the media_server which will broadcast
* them.
*/
#include <Messenger.h>
#include <MediaNode.h>
#include "debug.h"
#include "PortPool.h"
#include "ServerInterface.h"
#include "NotificationManager.h"
static BPrivate::media::NotificationManager manager;
BPrivate::media::NotificationManager *_NotificationManager = &manager;
namespace BPrivate {
namespace media {
NotificationManager::NotificationManager()
: fMessenger(new BMessenger())
{
CALLED();
}
NotificationManager::~NotificationManager()
{
CALLED();
delete fMessenger;
}
status_t
NotificationManager::Register(const BMessenger &notifyHandler, const media_node &node, notification_type_mask mask)
{
CALLED();
BMessage msg(MEDIA_SERVER_REQUEST_NOTIFICATIONS);
return SendMessageToMediaServer(&msg);
}
status_t
NotificationManager::Unregister(const BMessenger &notifyHandler, const media_node &node, notification_type_mask mask)
{
CALLED();
BMessage msg(MEDIA_SERVER_CANCEL_NOTIFICATIONS);
return SendMessageToMediaServer(&msg);
}
status_t
NotificationManager::ReportError(const media_node &node, BMediaNode::node_error what, const BMessage * info)
{
/* Transmits the error code specified by whichError to anyone that's receiving notifications from
* this node. If info isn't NULL, it's used as a model message for the error notification message.
* The message field "be:node_id" will contain the node ID.
*/
CALLED();
// sanity check the what value
switch (what) {
case BMediaNode::B_NODE_FAILED_START:
case BMediaNode::B_NODE_FAILED_STOP:
case BMediaNode::B_NODE_FAILED_SEEK:
case BMediaNode::B_NODE_FAILED_SET_RUN_MODE:
case BMediaNode::B_NODE_FAILED_TIME_WARP:
case BMediaNode::B_NODE_FAILED_PREROLL:
case BMediaNode::B_NODE_FAILED_SET_TIME_SOURCE_FOR:
case BMediaNode::B_NODE_IN_DISTRESS:
break;
default:
TRACE("BMediaNode::ReportError (NotificationManager::ReportError): invalid what!\n");
return B_BAD_VALUE;
}
BMessage msg;
if (info)
msg = *info;
msg.what = MEDIA_SERVER_SEND_NOTIFICATIONS;
msg.AddInt32(NOTIFICATION_PARAM_WHAT, what);
msg.AddInt32(NOTIFICATION_PARAM_MASK, notification_error);
return SendMessageToMediaServer(&msg);
}
void
NotificationManager::NodesCreated(const media_node_id *ids, int32 count)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_CREATED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_NODE_CREATED));
SendMessageToMediaServer(&msg);
}
void
NotificationManager::NodesDeleted(const media_node_id *ids, int32 count)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_DELETED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_NODE_DELETED));
SendMessageToMediaServer(&msg);
}
void
NotificationManager::ConnectionMade(const media_input &input, const media_output &output, const media_format &format)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_CONNECTION_MADE);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_CONNECTION_MADE));
SendMessageToMediaServer(&msg);
}
void
NotificationManager::ConnectionBroken(const media_source &source, const media_destination &destination)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_CONNECTION_BROKEN);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_CONNECTION_BROKEN));
SendMessageToMediaServer(&msg);
}
void
NotificationManager::BuffersCreated() // XXX fix
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_BUFFER_CREATED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_BUFFER_CREATED));
SendMessageToMediaServer(&msg);
}
void
NotificationManager::BuffersDeleted(const media_buffer_id *ids, int32 count)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_BUFFER_DELETED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_BUFFER_DELETED));
SendMessageToMediaServer(&msg);
}
void
NotificationManager::FormatChanged(const media_source &source, const media_destination &destination, const media_format &format)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_FORMAT_CHANGED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_FORMAT_CHANGED));
SendMessageToMediaServer(&msg);
}
status_t
NotificationManager::ParameterChanged(const media_node &node, int32 parameterid)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_PARAMETER_CHANGED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_PARAMETER_CHANGED));
return SendMessageToMediaServer(&msg);
}
void
NotificationManager::WebChanged(const media_node &node) // XXX fix
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_WEB_CHANGED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_WEB_CHANGED));
SendMessageToMediaServer(&msg);
}
status_t
NotificationManager::NewParameterValue(const media_node &node, int32 parameterid, bigtime_t when, const void *param, size_t paramsize)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NEW_PARAMETER_VALUE);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_NEW_PARAMETER_VALUE));
return SendMessageToMediaServer(&msg);
}
void
NotificationManager::FlavorsChanged(media_addon_id addonis, int32 newcount, int32 gonecount)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_FLAVORS_CHANGED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_FLAVORS_CHANGED));
SendMessageToMediaServer(&msg);
}
void
NotificationManager::NodeStopped(const media_node &node, bigtime_t when) // XXX fix
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_STOPPED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_NODE_STOPPED));
SendMessageToMediaServer(&msg);
}
status_t
NotificationManager::SendMessageToMediaServer(BMessage *msg)
{
#define TIMEOUT 100000
BMessage reply;
status_t rv;
if (!fMessenger->IsValid()) {
TRACE("NotificationManager::SendMessageToMediaServer: setting new messenger target\n");
*fMessenger = BMessenger(NEW_MEDIA_SERVER_SIGNATURE);
}
rv = fMessenger->SendMessage(msg, &reply, TIMEOUT);
if (rv != B_OK) {
TRACE("NotificationManager::SendMessageToMediaServer: failed to send message\n");
} else {
rv = reply.what;
}
return rv;
}
bool
NotificationManager::IsValidNotificationType(int32 notificationType)
{
switch (notificationType) {
case BMediaNode::B_NODE_FAILED_START:
case BMediaNode::B_NODE_FAILED_STOP:
case BMediaNode::B_NODE_FAILED_SEEK:
case BMediaNode::B_NODE_FAILED_SET_RUN_MODE:
case BMediaNode::B_NODE_FAILED_TIME_WARP:
case BMediaNode::B_NODE_FAILED_PREROLL:
case BMediaNode::B_NODE_FAILED_SET_TIME_SOURCE_FOR:
case BMediaNode::B_NODE_IN_DISTRESS:
debugger("NotificationManager::IsValidNotificationType, encountered BMediaNode Error otification\n");
return false; // XXX we consider registering for this notifications as impossible, you always get them anyway
case B_MEDIA_WILDCARD:
case B_MEDIA_NODE_CREATED:
case B_MEDIA_NODE_DELETED:
case B_MEDIA_CONNECTION_MADE:
case B_MEDIA_CONNECTION_BROKEN:
case B_MEDIA_BUFFER_CREATED:
case B_MEDIA_BUFFER_DELETED:
case B_MEDIA_TRANSPORT_STATE:
case B_MEDIA_PARAMETER_CHANGED:
case B_MEDIA_FORMAT_CHANGED:
case B_MEDIA_WEB_CHANGED:
case B_MEDIA_DEFAULT_CHANGED:
case B_MEDIA_NEW_PARAMETER_VALUE:
case B_MEDIA_NODE_STOPPED:
case B_MEDIA_FLAVORS_CHANGED:
return true;
default:
return false;
}
}
NotificationManager::notification_type_mask
NotificationManager::NotificationType2Mask(int32 notificationType)
{
switch (notificationType) {
case BMediaNode::B_NODE_FAILED_START:
case BMediaNode::B_NODE_FAILED_STOP:
case BMediaNode::B_NODE_FAILED_SEEK:
case BMediaNode::B_NODE_FAILED_SET_RUN_MODE:
case BMediaNode::B_NODE_FAILED_TIME_WARP:
case BMediaNode::B_NODE_FAILED_PREROLL:
case BMediaNode::B_NODE_FAILED_SET_TIME_SOURCE_FOR:
case BMediaNode::B_NODE_IN_DISTRESS:
return notification_error;
case B_MEDIA_WILDCARD:
return notification_wildcard;
case B_MEDIA_NODE_CREATED:
return notification_node_created;
case B_MEDIA_NODE_DELETED:
return notification_node_deleted;
case B_MEDIA_CONNECTION_MADE:
return notification_connection_made;
case B_MEDIA_CONNECTION_BROKEN:
return notification_connection_broken;
case B_MEDIA_BUFFER_CREATED:
return notification_buffer_created;
case B_MEDIA_BUFFER_DELETED:
return notification_buffer_deleted;
case B_MEDIA_TRANSPORT_STATE:
return notification_transport_state;
case B_MEDIA_PARAMETER_CHANGED:
return notification_parameter_changed;
case B_MEDIA_FORMAT_CHANGED:
return notification_format_change;
case B_MEDIA_WEB_CHANGED:
return notification_web_changed;
case B_MEDIA_DEFAULT_CHANGED:
return notification_default_changed;
case B_MEDIA_NEW_PARAMETER_VALUE:
return notification_new_parameter_value;
case B_MEDIA_NODE_STOPPED:
return notification_node_stopped;
case B_MEDIA_FLAVORS_CHANGED:
return notification_flavors_changed;
default:
return notification_no_mask;
}
}
}; // namespace media
}; // namespace BPrivate
+261
View File
@@ -0,0 +1,261 @@
/*
* Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
/* This is a interface class for media kit notifications.
* It is private to the media kit which uses it to pass
* notifications up to the media_server which will broadcast
* them.
*/
/* XXX The BeBook, MediaDefs.h and the BeOS R5 do list
* XXX different strings for the message data fields of
* XXX the notification messages.
*/
#include <Messenger.h>
#include <MediaNode.h>
#include "debug.h"
#include "DataExchange.h"
#include "Notifications.h"
namespace BPrivate {
namespace media {
extern team_id team;
namespace notifications {
status_t
Register(const BMessenger &notifyHandler, const media_node &node, int32 notification)
{
CALLED();
BMessage msg(MEDIA_SERVER_REQUEST_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification);
msg.AddInt32(NOTIFICATION_PARAM_TEAM, team);
msg.AddMessenger(NOTIFICATION_PARAM_MESSENGER, notifyHandler);
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
return BPrivate::media::dataexchange::SendToServer(&msg);
}
status_t
Unregister(const BMessenger &notifyHandler, const media_node &node, int32 notification)
{
CALLED();
BMessage msg(MEDIA_SERVER_CANCEL_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification);
msg.AddInt32(NOTIFICATION_PARAM_TEAM, team);
msg.AddMessenger(NOTIFICATION_PARAM_MESSENGER, notifyHandler);
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
return BPrivate::media::dataexchange::SendToServer(&msg);
}
status_t
ReportError(const media_node &node, BMediaNode::node_error what, const BMessage * info)
{
/* Transmits the error code specified by whichError to anyone that's receiving notifications from
* this node. If info isn't NULL, it's used as a model message for the error notification message.
* The message field "be:node_id" will contain the node ID.
*/
CALLED();
BMessage msg;
if (info)
msg = *info;
msg.what = MEDIA_SERVER_SEND_NOTIFICATIONS;
msg.AddInt32(NOTIFICATION_PARAM_WHAT, what);
msg.AddInt32("be:node_id", node.node);
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
return BPrivate::media::dataexchange::SendToServer(&msg);
}
void
NodesCreated(const media_node_id *ids, int32 count)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_CREATED);
for (int32 i = 0; i < count; i++) {
msg.AddInt32("media_node_id", ids[i]);
}
BPrivate::media::dataexchange::SendToServer(&msg);
}
void
NodesDeleted(const media_node_id *ids, int32 count)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_DELETED);
for (int32 i = 0; i < count; i++) {
msg.AddInt32("media_node_id", ids[i]);
}
BPrivate::media::dataexchange::SendToServer(&msg);
}
void
ConnectionMade(const media_input &input, const media_output &output, const media_format &format)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_CONNECTION_MADE);
msg.AddData("input", B_RAW_TYPE, &input, sizeof(input));
msg.AddData("output", B_RAW_TYPE, &output, sizeof(output));
msg.AddData("format", B_RAW_TYPE, &format, sizeof(format));
BPrivate::media::dataexchange::SendToServer(&msg);
}
void
ConnectionBroken(const media_source &source, const media_destination &destination)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_CONNECTION_BROKEN);
msg.AddData("source", B_RAW_TYPE, &source, sizeof(source));
msg.AddData("destination", B_RAW_TYPE, &destination, sizeof(destination));
BPrivate::media::dataexchange::SendToServer(&msg);
}
void
BuffersCreated(area_info *areas, int32 count)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_BUFFER_CREATED);
for (int32 i = 0; i < count; i++) {
msg.AddData("clone_info", B_RAW_TYPE, &areas[i], sizeof(area_info));
}
BPrivate::media::dataexchange::SendToServer(&msg);
}
void
BuffersDeleted(const media_buffer_id *ids, int32 count)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_BUFFER_DELETED);
for (int32 i = 0; i < count; i++) {
msg.AddInt32("media_buffer_id", ids[i]);
}
BPrivate::media::dataexchange::SendToServer(&msg);
}
void
FormatChanged(const media_source &source, const media_destination &destination, const media_format &format)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_FORMAT_CHANGED);
msg.AddData("source", B_RAW_TYPE, &source, sizeof(source));
msg.AddData("destination", B_RAW_TYPE, &destination, sizeof(destination));
msg.AddData("format", B_RAW_TYPE, &format, sizeof(format));
BPrivate::media::dataexchange::SendToServer(&msg);
}
status_t
ParameterChanged(const media_node &node, int32 parameterid)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_PARAMETER_CHANGED);
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
msg.AddInt32("parameter", parameterid);
return BPrivate::media::dataexchange::SendToServer(&msg);
}
void
WebChanged(const media_node &node)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_WEB_CHANGED);
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
BPrivate::media::dataexchange::SendToServer(&msg);
}
status_t
NewParameterValue(const media_node &node, int32 parameterid, bigtime_t when, const void *param, size_t paramsize)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NEW_PARAMETER_VALUE);
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
msg.AddInt32("parameter", parameterid);
msg.AddInt64("when", when);
msg.AddData("value", B_RAW_TYPE, param, paramsize);
return BPrivate::media::dataexchange::SendToServer(&msg);
}
void
FlavorsChanged(media_addon_id addonid, int32 newcount, int32 gonecount)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_FLAVORS_CHANGED);
msg.AddInt32("be:addon_id", addonid);
msg.AddInt32("be:new_count", newcount);
msg.AddInt32("be:gone_count", gonecount);
BPrivate::media::dataexchange::SendToServer(&msg);
}
void
NodeStopped(const media_node &node, bigtime_t when)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_STOPPED);
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
msg.AddInt64("when", when);
BPrivate::media::dataexchange::SendToServer(&msg);
}
// XXX missing: B_MEDIA_TRANSPORT_STATE /* "state", "location", "realtime" */
// XXX missing: B_MEDIA_DEFAULT_CHANGED /* "default", "node" */
bool
IsValidNotificationRequest(bool node_specific, int32 notification)
{
switch (notification) {
// valid for normal and node specific watching
case B_MEDIA_WILDCARD:
case B_MEDIA_NODE_CREATED:
case B_MEDIA_NODE_DELETED:
case B_MEDIA_CONNECTION_MADE:
case B_MEDIA_CONNECTION_BROKEN:
case B_MEDIA_BUFFER_CREATED:
case B_MEDIA_BUFFER_DELETED:
case B_MEDIA_TRANSPORT_STATE:
case B_MEDIA_DEFAULT_CHANGED:
case B_MEDIA_FLAVORS_CHANGED:
return true;
// only valid for node specific watching
case B_MEDIA_PARAMETER_CHANGED:
case B_MEDIA_FORMAT_CHANGED:
case B_MEDIA_WEB_CHANGED:
case B_MEDIA_NEW_PARAMETER_VALUE:
case B_MEDIA_NODE_STOPPED:
return node_specific;
// everything else is invalid
default:
return false;
}
}
}; // namespace notifications
}; // namespace media
}; // namespace BPrivate
+12
View File
@@ -22,6 +22,18 @@ NodeManager::~NodeManager()
delete fAddonPathMap;
}
/* Add media_node_id of all live nodes to the message
* int32 "media_node_id" (multiple items)
*/
status_t
NodeManager::GetLiveNodes(BMessage *msg)
{
msg->AddInt32("media_node_id", 1);
msg->AddInt32("media_node_id", 2);
msg->AddInt32("media_node_id", 3);
return B_OK;
}
void
NodeManager::RegisterAddon(const entry_ref &ref, media_addon_id *newid)
{
+5
View File
@@ -26,6 +26,11 @@ public:
status_t LoadState();
status_t SaveState();
/* Add media_node_id of all live nodes to the message
* int32 "media_node_id" (multiple items)
*/
status_t GetLiveNodes(BMessage *msg);
void AddDormantFlavorInfo(const dormant_flavor_info &dfi);
void RemoveDormantFlavorInfo(media_addon_id id);
void RegisterAddon(const entry_ref &ref, media_addon_id *newid);
+4 -21
View File
@@ -18,11 +18,6 @@ enum {
MEDIA_SERVER_REGISTER_BUFFER,
MEDIA_SERVER_UNREGISTER_BUFFER,
// BMediaRoster notification service
MEDIA_SERVER_REQUEST_NOTIFICATIONS,
MEDIA_SERVER_CANCEL_NOTIFICATIONS,
MEDIA_SERVER_SEND_NOTIFICATIONS,
// Something else
MEDIA_SERVER_SET_VOLUME,
MEDIA_SERVER_GET_VOLUME,
@@ -588,22 +583,10 @@ struct xfer_consumer_seek_tag_requested_reply
status_t result;
};
struct xfer_addonserver_instantiate_dormant_node
{
dormant_node_info info;
port_id reply_port;
};
struct xfer_addonserver_instantiate_dormant_node_reply
{
media_node node;
status_t result;
};
// implementation contained in libmedia.so (MediaRoster.cpp)
namespace MediaKitPrivate
{
namespace BPrivate { namespace media { namespace dataexchange {
status_t QueryServer(BMessage *query, BMessage *reply);
};
}; }; };
using namespace BPrivate::media::dataexchange;
#endif
+4 -3
View File
@@ -6,6 +6,7 @@
#include <Autolock.h>
#include "NotificationProcessor.h"
#include "ServerInterface.h"
#include "DataExchange.h"
#include "BufferManager.h"
#include "NodeManager.h"
#include "AppManager.h"
@@ -547,9 +548,9 @@ void ServerApp::MessageReceived(BMessage *msg)
case MEDIA_SERVER_GET_SHARED_BUFFER_AREA: GetSharedBufferArea(msg); break;
case MEDIA_SERVER_REGISTER_BUFFER: RegisterBuffer(msg); break;
case MEDIA_SERVER_UNREGISTER_BUFFER: UnregisterBuffer(msg); break;
case MEDIA_SERVER_REQUEST_NOTIFICATIONS: fNotificationProcessor->RequestNotifications(msg); break;
case MEDIA_SERVER_CANCEL_NOTIFICATIONS: fNotificationProcessor->CancelNotifications(msg); break;
case MEDIA_SERVER_SEND_NOTIFICATIONS: fNotificationProcessor->SendNotifications(msg); break;
case MEDIA_SERVER_REQUEST_NOTIFICATIONS: fNotificationProcessor->EnqueueMessage(msg); break;
case MEDIA_SERVER_CANCEL_NOTIFICATIONS: fNotificationProcessor->EnqueueMessage(msg); break;
case MEDIA_SERVER_SEND_NOTIFICATIONS: fNotificationProcessor->EnqueueMessage(msg); break;
case MEDIA_SERVER_GET_NODE_ID: GetNodeID(msg); break;
+43 -20
View File
@@ -15,9 +15,11 @@
#include "debug.h"
#include "TMap.h"
#include "ServerInterface.h"
#include "DataExchange.h"
#include "DormantNodeManager.h"
#include "Notifications.h"
#define USER_ADDON_PATH "/boot/home/Develop/OpenBeOS/current/distro/x86.R1/beos/system/add-ons/media"
#define USER_ADDON_PATH "../add-ons/media"
void DumpFlavorInfo(const flavor_info *info);
@@ -37,7 +39,8 @@ public:
void ScanAddOnFlavors(BMediaAddOn *addon);
Map<ino_t,media_addon_id> *filemap;
Map<ino_t, media_addon_id> *filemap;
Map<media_addon_id, int32> *flavorcountmap;
BMediaRoster *mediaroster;
ino_t DirNodeSystem;
@@ -50,7 +53,8 @@ MediaAddonServer::MediaAddonServer(const char *sig) :
BApplication(sig)
{
mediaroster = BMediaRoster::Roster();
filemap = new Map<ino_t,media_addon_id>;
filemap = new Map<ino_t, media_addon_id>;
flavorcountmap = new Map<media_addon_id, int32>;
control_port = create_port(64,"media_addon_server port");
control_thread = spawn_thread(controlthread,"media_addon_server control",12,this);
resume_thread(control_thread);
@@ -68,6 +72,7 @@ MediaAddonServer::~MediaAddonServer()
_DormantNodeManager->UnregisterAddon(id);
delete filemap;
delete flavorcountmap;
}
void
@@ -76,10 +81,10 @@ MediaAddonServer::HandleMessage(int32 code, void *data, size_t size)
switch (code) {
case ADDONSERVER_INSTANTIATE_DORMANT_NODE:
{
const xfer_addonserver_instantiate_dormant_node *msg = (const xfer_addonserver_instantiate_dormant_node *)data;
xfer_addonserver_instantiate_dormant_node_reply reply;
const request_addonserver_instantiate_dormant_node *msg = (const request_addonserver_instantiate_dormant_node *)data;
reply_addonserver_instantiate_dormant_node reply;
reply.result = mediaroster->InstantiateDormantNode(msg->info, &reply.node);
write_port(msg->reply_port, 0, &reply, sizeof(reply));
msg->SendReply(&reply, sizeof(reply));
break;
}
@@ -140,10 +145,13 @@ MediaAddonServer::ReadyToRun()
void
MediaAddonServer::ScanAddOnFlavors(BMediaAddOn *addon)
{
int flavorcount;
media_addon_id purge_id;
int32 *flavorcount;
int32 oldflavorcount;
int32 newflavorcount;
media_addon_id addon_id;
port_id port;
status_t rv;
bool b;
ASSERT(addon);
ASSERT(addon->AddonID() > 0);
@@ -156,13 +164,21 @@ MediaAddonServer::ScanAddOnFlavors(BMediaAddOn *addon)
return;
}
// the server should remove previously registered "dormant_flavor_info"s
purge_id = addon->AddonID();
// cache the media_addon_id in a local variable to avoid
// calling BMediaAddOn::AddonID() too often
addon_id = addon->AddonID();
// update the cached flavor count, get oldflavorcount and newflavorcount
b = flavorcountmap->GetPointer(addon->AddonID(), &flavorcount);
ASSERT(b);
oldflavorcount = *flavorcount;
newflavorcount = addon->CountFlavors();
*flavorcount = newflavorcount;
printf("%d old flavors, %d new flavors\n", oldflavorcount, newflavorcount);
flavorcount = addon->CountFlavors();
printf("%d flavors:\n",flavorcount);
for (int i = 0; i < flavorcount; i++) {
// during the first update (i == 0), the server removes old dormant_flavor_infos
for (int i = 0; i < newflavorcount; i++) {
const flavor_info *info;
printf("flavor %d:\n",i);
if (B_OK != addon->GetFlavorAt(i, &info)) {
@@ -174,7 +190,7 @@ MediaAddonServer::ScanAddOnFlavors(BMediaAddOn *addon)
dormant_flavor_info dfi;
dfi = *info;
dfi.node_info.addon = addon->AddonID();
dfi.node_info.addon = addon_id;
dfi.node_info.flavor_id = info->internal_id;
strncpy(dfi.node_info.name, info->name, B_MEDIA_NAME_LENGTH - 1);
dfi.node_info.name[B_MEDIA_NAME_LENGTH - 1] = 0;
@@ -187,7 +203,11 @@ MediaAddonServer::ScanAddOnFlavors(BMediaAddOn *addon)
msgsize = flattensize + sizeof(xfer_server_register_dormant_node);
msg = (xfer_server_register_dormant_node *) malloc(msgsize);
msg->purge_id = purge_id;
// the server should remove previously registered "dormant_flavor_info"s
// during the first update, but after the first iteration, we don't want
// the server to anymore remove old dormant_flavor_infos;
msg->purge_id = (i == 0) ? addon_id : 0;
msg->dfi_type = dfi.TypeCode();
msg->dfi_size = flattensize;
dfi.Flatten(&(msg->dfi),flattensize);
@@ -198,11 +218,12 @@ MediaAddonServer::ScanAddOnFlavors(BMediaAddOn *addon)
}
free(msg);
// after the first iteration, we don't want the server to anymore remove our dfis;
if (purge_id != 0)
purge_id = 0;
}
// XXX parameter list is (media_addon_id addonid, int32 newcount, int32 gonecount)
// XXX we currently pretend that all old flavors have been removed, this could
// XXX probably be done in a smarter way
BPrivate::media::notifications::FlavorsChanged(addon_id, newflavorcount, oldflavorcount);
}
void
@@ -230,6 +251,7 @@ MediaAddonServer::AddOnAdded(const char *path, ino_t file_node)
printf("MediaAddonServer::AddOnAdded: loading finished, id %d\n",(int)id);
filemap->Insert(file_node, id);
flavorcountmap->Insert(id, 0);
ScanAddOnFlavors(addon);
@@ -293,6 +315,7 @@ MediaAddonServer::AddOnRemoved(ino_t file_node)
return;
}
filemap->Remove(file_node);
flavorcountmap->Remove(id);
_DormantNodeManager->UnregisterAddon(id);
}