Skip to content

Commit

Permalink
BMediaRoster: Add B_MEDIA_SERVER_STARTED and B_MEDIA_SERVER_QUIT
Browse files Browse the repository at this point in the history
* This is done by watching to registrar notifications
  and providing a minimal service to contact the
  media roster in private API. The roster use this
  service to automatically reconnect to the media_server.
  • Loading branch information
Numerio committed Jul 24, 2015
1 parent e57acc3 commit 32afe10
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 11 deletions.
4 changes: 3 additions & 1 deletion headers/os/media/MediaDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ enum {
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", */
B_MEDIA_FLAVORS_CHANGED, /* "be:addon_id", "be:new_count", */
/* "be:gone_count" */
B_MEDIA_SERVER_STARTED,
B_MEDIA_SERVER_QUIT
};


Expand Down
6 changes: 5 additions & 1 deletion headers/private/media/DataExchange.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ namespace media {
namespace dataexchange {


void InitDataExchange();
void InitServerDataExchange();
void InitRosterDataExchange(const BMessenger& rosterMessenger);

// BMessage based data exchange with the current BMediaRoster
status_t SendToRoster(BMessage* msg);

// BMessage based data exchange with the media_server
status_t SendToServer(BMessage* msg);
Expand Down
2 changes: 2 additions & 0 deletions headers/private/media/MediaRosterEx.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ class BMediaRosterEx : public BMediaRoster

BTimeSource* MakeTimeSourceObject(media_node_id timesource_id);

status_t BuildConnections();

private:
friend class BMediaRoster;
};
Expand Down
6 changes: 6 additions & 0 deletions headers/private/media/ServerInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ enum {
MEDIA_ADD_ON_SERVER_PLAY_MEDIA = '_TRU'
};

enum {
// local media services status notification service
MEDIA_ROSTER_REQUEST_NOTIFICATIONS = 2000,
MEDIA_ROSTER_CANCEL_NOTIFICATIONS
};

// Raw port based communication
enum {
GENERAL_PURPOSE_WAKEUP = 0, // when no action but wait termination needed
Expand Down
24 changes: 23 additions & 1 deletion src/kits/media/DataExchange.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace dataexchange {


static BMessenger sMediaServerMessenger;
static BMessenger sMediaRosterMessenger;
static port_id sMediaServerPort;
static port_id sMediaAddonServerPort;

Expand Down Expand Up @@ -58,14 +59,35 @@ find_media_addon_server_port()


void
InitDataExchange()
InitServerDataExchange()
{
sMediaServerMessenger = BMessenger(B_MEDIA_SERVER_SIGNATURE);
find_media_server_port();
find_media_addon_server_port();
}


void
InitRosterDataExchange(const BMessenger& rosterMessenger)
{
sMediaRosterMessenger = rosterMessenger;
}


//! BMessage based data exchange with the local BMediaRoster
status_t
SendToRoster(BMessage* msg)
{
status_t status = sMediaRosterMessenger.SendMessage(msg,
static_cast<BHandler*>(NULL), TIMEOUT);
if (status != B_OK) {
ERROR("SendToRoster: SendMessage failed: %s\n", strerror(status));
DEBUG_ONLY(msg->PrintToStream());
}
return status;
}


//! BMessage based data exchange with the media_server
status_t
SendToServer(BMessage* msg)
Expand Down
163 changes: 155 additions & 8 deletions src/kits/media/MediaRoster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,15 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002-2006 Marcus "

#include <AppMisc.h>

#include <debug.h>
#include <DataExchange.h>
#include <debug.h>
#include <DormantNodeManager.h>
#include <MediaRosterEx.h>
#include <MediaMisc.h>
#include <MediaRosterEx.h>
#include <Notifications.h>
#include <ServerInterface.h>
#include <SharedBufferList.h>
#include <TList.h>

#include "TimeSourceObjectManager.h"

Expand All @@ -75,6 +76,14 @@ namespace BPrivate {
namespace media {


struct RosterNotification {
BMessenger messenger;
int32 what;
};

static bool sServerIsUp = false;
static List<RosterNotification> sNotificationList;

// This class is provided to ensure the BMediaRoster is quit.
class MediaRosterUndertaker {
public:
Expand All @@ -101,11 +110,25 @@ BMediaRosterEx::BMediaRosterEx(status_t* _error)
:
BMediaRoster()
{
InitDataExchange();

gDormantNodeManager = new DormantNodeManager;
gTimeSourceObjectManager = new TimeSourceObjectManager;

*_error = BuildConnections();

InitRosterDataExchange(BMessenger(this, this));

if (be_roster->StartWatching(BMessenger(this, this),
B_REQUEST_LAUNCHED | B_REQUEST_QUIT) != B_OK)
*_error = B_ERROR;

sServerIsUp = BMediaRoster::IsRunning();
}


status_t
BMediaRosterEx::BuildConnections()
{
InitServerDataExchange();
// register this application with the media server
server_register_app_request request;
server_register_app_reply reply;
Expand All @@ -115,9 +138,9 @@ BMediaRosterEx::BMediaRosterEx(status_t* _error)
status_t status = QueryServer(SERVER_REGISTER_APP, &request,
sizeof(request), &reply, sizeof(reply));
if (status != B_OK)
*_error = B_MEDIA_SYSTEM_FAILURE;
else
*_error = B_OK;
return B_MEDIA_SYSTEM_FAILURE;

return B_OK;
}


Expand Down Expand Up @@ -1902,6 +1925,10 @@ BMediaRoster::StartWatching(const BMessenger & where, int32 notificationType)
ERROR("BMediaRoster::StartWatching: notificationType invalid!\n");
return B_BAD_VALUE;
}

// NOTE: we support only explicitly B_MEDIA_SERVER_STARTED/QUIT
// notifications. This should be cleared in documentation.

return BPrivate::media::notifications::Register(where, media_node::null,
notificationType);
}
Expand Down Expand Up @@ -3308,6 +3335,119 @@ BMediaRoster::MessageReceived(BMessage* message)
return;
}

case MEDIA_ROSTER_REQUEST_NOTIFICATIONS:
{
RosterNotification notification;
if (message->FindInt32(NOTIFICATION_PARAM_WHAT, &notification.what)
!= B_OK) {
TRACE("BMediaRoster MEDIA_ROSTER_REQUEST_NOTIFICATIONS can't"
"find what parameter");
return;
}
if (message->FindMessenger(NOTIFICATION_PARAM_MESSENGER,
&notification.messenger) != B_OK) {
TRACE("BMediaRoster MEDIA_ROSTER_REQUEST_NOTIFICATIONS can't"
"find messenger");
return;
}
sNotificationList.Insert(notification);
return;
}

case MEDIA_ROSTER_CANCEL_NOTIFICATIONS:
{
RosterNotification notification;
if (message->FindInt32(NOTIFICATION_PARAM_WHAT, &notification.what)
!= B_OK) {
TRACE("BMediaRoster MEDIA_ROSTER_CANCEL_NOTIFICATIONS can't"
"find what parameter");
return;
}
if (message->FindMessenger(NOTIFICATION_PARAM_MESSENGER,
&notification.messenger) != B_OK) {
TRACE("BMediaRoster MEDIA_ROSTER_CANCEL_NOTIFICATIONS can't"
"find messenger");
return;
}
for (int32 i = 0; i < sNotificationList.CountItems(); i++) {
RosterNotification* current;
if (sNotificationList.Get(i, &current) != true)
return;
if (current->what == notification.what
&& current->messenger == notification.messenger) {
sNotificationList.Remove(i);
return;
}
}
return;
}

case B_SOME_APP_LAUNCHED:
{
BString mimeSig;
if (message->FindString("be:signature", &mimeSig) != B_OK)
return;
if (mimeSig != B_MEDIA_ADDON_SERVER_SIGNATURE
&& mimeSig != B_MEDIA_SERVER_SIGNATURE)
return;

TRACE("BMediaRoster::MessageReceived media services are going up.");

// Send the notification to our subscribers
if (BMediaRoster::IsRunning()) {
sServerIsUp = true;
// Restore our friendship with the media servers
if (MediaRosterEx(this)->BuildConnections() != B_OK) {
TRACE("BMediaRoster::MessageReceived can't reconnect"
"to media_server.");
}

for (int32 i = 0; i < sNotificationList.CountItems(); i++) {
RosterNotification* current;
if (sNotificationList.Get(i, &current) != true)
return;
if (current->what == B_MEDIA_SERVER_STARTED) {
if (current->messenger.SendMessage(
B_MEDIA_SERVER_STARTED) != B_OK) {
if(!current->messenger.IsValid())
sNotificationList.Remove(i);
}
}
}
}
return;
}

case B_SOME_APP_QUIT:
{
BString mimeSig;
if (message->FindString("be:signature", &mimeSig) != B_OK)
return;
if (mimeSig != B_MEDIA_ADDON_SERVER_SIGNATURE
&& mimeSig != B_MEDIA_SERVER_SIGNATURE)
return;

TRACE("BMediaRoster::MessageReceived media services are down.");

// Send the notification to our subscribers
if (!BMediaRoster::IsRunning() && sServerIsUp == true) {
sServerIsUp = false;
for (int32 i = 0; i < sNotificationList.CountItems(); i++) {
RosterNotification* current;
if (sNotificationList.Get(i, &current) != true)
return;
if (current->what == B_MEDIA_SERVER_QUIT) {
if (current->messenger.SendMessage(
B_MEDIA_SERVER_QUIT) != B_OK) {
if(!current->messenger.IsValid())
sNotificationList.Remove(i);
}
}
}
}
return;
}

case NODE_FINAL_RELEASE:
{
// this function is called by a BMediaNode to delete
Expand Down Expand Up @@ -3338,7 +3478,14 @@ BMediaRoster::MessageReceived(BMessage* message)
bool
BMediaRoster::QuitRequested()
{
UNIMPLEMENTED();
CALLED();

if (be_roster->StopWatching(BMessenger(this, this)) != B_OK)
TRACE("Can't unregister roster notifications");

if (sNotificationList.CountItems() != 0)
sNotificationList.MakeEmpty();

return true;
}

Expand Down
23 changes: 23 additions & 0 deletions src/kits/media/Notifications.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ Register(const BMessenger& notifyHandler, const media_node& node,
int32 notification)
{
CALLED();

if (notification == B_MEDIA_SERVER_STARTED
|| notification == B_MEDIA_SERVER_QUIT) {
BMessage msg(MEDIA_ROSTER_REQUEST_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification);
msg.AddMessenger(NOTIFICATION_PARAM_MESSENGER, notifyHandler);
return BPrivate::media::dataexchange::SendToRoster(&msg);
}

BMessage msg(MEDIA_SERVER_REQUEST_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification);
msg.AddInt32(NOTIFICATION_PARAM_TEAM, BPrivate::current_team());
Expand All @@ -73,6 +82,15 @@ Unregister(const BMessenger& notifyHandler, const media_node& node,
int32 notification)
{
CALLED();

if (notification == B_MEDIA_SERVER_STARTED
|| notification == B_MEDIA_SERVER_QUIT) {
BMessage msg(MEDIA_ROSTER_CANCEL_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification);
msg.AddMessenger(NOTIFICATION_PARAM_MESSENGER, notifyHandler);
return BPrivate::media::dataexchange::SendToRoster(&msg);
}

BMessage msg(MEDIA_SERVER_CANCEL_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification);
msg.AddInt32(NOTIFICATION_PARAM_TEAM, BPrivate::current_team());
Expand Down Expand Up @@ -295,6 +313,11 @@ IsValidNotificationRequest(bool node_specific, int32 notification)
case B_MEDIA_FLAVORS_CHANGED:
return true;

// invalid if we watch for a specific node
case B_MEDIA_SERVER_STARTED:
case B_MEDIA_SERVER_QUIT:
return !node_specific;

// only valid for node specific watching
case B_MEDIA_PARAMETER_CHANGED:
case B_MEDIA_FORMAT_CHANGED:
Expand Down

0 comments on commit 32afe10

Please sign in to comment.