Ticket #11922: 0010-Add-support-to-BMediaRoster-for-B_MEDIA_SERVER_START.patch

File 0010-Add-support-to-BMediaRoster-for-B_MEDIA_SERVER_START.patch, 12.3 KB (added by Barrett, 9 years ago)
  • headers/os/media/MediaDefs.h

    From 3199ee8d96cd6141db059bd3f93c7e2b4f3f4413 Mon Sep 17 00:00:00 2001
    From: Dario Casalinuovo <b.vitruvio@gmail.com>
    Date: Thu, 9 Apr 2015 15:47:29 +0200
    Subject: [PATCH 10/13] Add support to BMediaRoster for B_MEDIA_SERVER_STARTED
     and B_MEDIA_SERVER_QUIT notifications, this is done by watching to app
     notifications and providing a minimal service to contact the media roster in
     private API. The roster use this service to reconnect to the media_server.
    
    ---
     headers/os/media/MediaDefs.h            |   4 +-
     headers/private/media/DataExchange.h    |   6 +-
     headers/private/media/MediaRosterEx.h   |   3 +
     headers/private/media/ServerInterface.h |   6 ++
     src/kits/media/DataExchange.cpp         |  24 ++++-
     src/kits/media/MediaRoster.cpp          | 158 +++++++++++++++++++++++++++++++-
     src/kits/media/Notifications.cpp        |  23 +++++
     7 files changed, 216 insertions(+), 8 deletions(-)
    
    diff --git a/headers/os/media/MediaDefs.h b/headers/os/media/MediaDefs.h
    index 8cbce1e..a7fa6d8 100644
    a b enum {  
    4747    B_MEDIA_NEW_PARAMETER_VALUE,    /* N "node", "parameter", "when", */
    4848                                    /* "value" */
    4949    B_MEDIA_NODE_STOPPED,           /* N "node", "when" */
    50     B_MEDIA_FLAVORS_CHANGED         /* "be:addon_id", "be:new_count", */
     50    B_MEDIA_FLAVORS_CHANGED,        /* "be:addon_id", "be:new_count", */
    5151                                    /* "be:gone_count" */
     52    B_MEDIA_SERVER_STARTED,
     53    B_MEDIA_SERVER_QUIT
    5254};
    5355
    5456
  • headers/private/media/DataExchange.h

    diff --git a/headers/private/media/DataExchange.h b/headers/private/media/DataExchange.h
    index 0b5b21d..85c50ce 100644
    a b namespace media {  
    1616namespace dataexchange {
    1717
    1818
    19 void InitDataExchange();
     19void InitServerDataExchange();
     20void InitRosterDataExchange(const BMessenger& rosterMessenger);
     21
     22// BMessage based data exchange with the current BMediaRoster
     23status_t SendToRoster(BMessage* msg);
    2024
    2125// BMessage based data exchange with the media_server
    2226status_t SendToServer(BMessage* msg);
  • headers/private/media/MediaRosterEx.h

    diff --git a/headers/private/media/MediaRosterEx.h b/headers/private/media/MediaRosterEx.h
    index 149cfbd..a478791 100644
    a b public:  
    8787
    8888    BTimeSource*        MakeTimeSourceObject(media_node_id timesource_id);
    8989
     90    // Build the connection with the media_server
     91    status_t            BuildConnections();
     92
    9093private:
    9194    friend class BMediaRoster;
    9295};
  • headers/private/media/ServerInterface.h

    diff --git a/headers/private/media/ServerInterface.h b/headers/private/media/ServerInterface.h
    index 46a1329..afb49f9 100644
    a b enum {  
    3232    MEDIA_ADD_ON_SERVER_PLAY_MEDIA = '_TRU'
    3333};
    3434
     35enum {
     36    // local media services status notification service
     37    MEDIA_ROSTER_REQUEST_NOTIFICATIONS = 2000,
     38    MEDIA_ROSTER_CANCEL_NOTIFICATIONS
     39};
     40
    3541// Raw port based communication
    3642enum {
    3743    GENERAL_PURPOSE_WAKEUP = 0, // when no action but wait termination needed
  • src/kits/media/DataExchange.cpp

    diff --git a/src/kits/media/DataExchange.cpp b/src/kits/media/DataExchange.cpp
    index f340ea7..8c33d14 100644
    a b namespace dataexchange {  
    2525
    2626
    2727static BMessenger sMediaServerMessenger;
     28static BMessenger sMediaRosterMessenger;
    2829static port_id sMediaServerPort;
    2930static port_id sMediaAddonServerPort;
    3031
    find_media_addon_server_port()  
    5859
    5960
    6061void
    61 InitDataExchange()
     62InitServerDataExchange()
    6263{
    6364    sMediaServerMessenger = BMessenger(B_MEDIA_SERVER_SIGNATURE);
    6465    find_media_server_port();
    InitDataExchange()  
    6667}
    6768
    6869
     70void
     71InitRosterDataExchange(const BMessenger& rosterMessenger)
     72{
     73    sMediaRosterMessenger = rosterMessenger;
     74}
     75
     76
     77//! BMessage based data exchange with the local BMediaRoster
     78status_t
     79SendToRoster(BMessage* msg)
     80{
     81    status_t status = sMediaRosterMessenger.SendMessage(msg,
     82        static_cast<BHandler*>(NULL), TIMEOUT);
     83    if (status != B_OK) {
     84        ERROR("SendToRoster: SendMessage failed: %s\n", strerror(status));
     85        DEBUG_ONLY(msg->PrintToStream());
     86    }
     87    return status;
     88}
     89
     90
    6991//! BMessage based data exchange with the media_server
    7092status_t
    7193SendToServer(BMessage* msg)
  • src/kits/media/MediaRoster.cpp

    diff --git a/src/kits/media/MediaRoster.cpp b/src/kits/media/MediaRoster.cpp
    index 1acf332..33730a2 100644
    a b char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002-2006 Marcus "  
    6767#include <Notifications.h>
    6868#include <ServerInterface.h>
    6969#include <SharedBufferList.h>
     70#include <TList.h>
    7071
    7172#include "TimeSourceObjectManager.h"
    7273
    namespace BPrivate {  
    7576namespace media {
    7677
    7778
     79struct RosterNotification {
     80    BMessenger  messenger;
     81    int32       what;
     82};
     83
     84static bool sServerIsUp = false;
     85static List<RosterNotification> sNotificationList;
     86
    7887class MediaInitializer {
    7988public:
    8089    MediaInitializer()
    8190    {
    82         InitDataExchange();
     91        InitServerDataExchange();
    8392    }
    8493
    8594    ~MediaInitializer()
    BMediaRosterEx::BMediaRosterEx(status_t* _error)  
    105114    :
    106115    BMediaRoster()
    107116{
    108     InitDataExchange();
    109 
    110117    gDormantNodeManager = new DormantNodeManager;
    111118    gTimeSourceObjectManager = new TimeSourceObjectManager;
    112119
     120    *_error = BuildConnections();
     121
     122    InitRosterDataExchange(BMessenger(this, this));
     123
     124    if (be_roster->StartWatching(BMessenger(this, this),
     125        B_REQUEST_LAUNCHED | B_REQUEST_QUIT) != B_OK)
     126            *_error = B_ERROR;
     127
     128    sServerIsUp = BMediaRoster::IsRunning();
     129}
     130
     131
     132status_t
     133BMediaRosterEx::BuildConnections()
     134{
     135    InitServerDataExchange();
     136
    113137    // register this application with the media server
    114138    server_register_app_request request;
    115139    server_register_app_reply reply;
    BMediaRosterEx::BMediaRosterEx(status_t* _error)  
    118142
    119143    status_t status = QueryServer(SERVER_REGISTER_APP, &request,
    120144        sizeof(request), &reply, sizeof(reply));
     145
    121146    if (status != B_OK)
    122         *_error = B_MEDIA_SYSTEM_FAILURE;
     147        return B_MEDIA_SYSTEM_FAILURE;
    123148    else
    124         *_error = B_OK;
     149        return B_OK;
    125150}
    126151
    127152
    BMediaRoster::StartWatching(const BMessenger& where)  
    18701895        ERROR("BMediaRoster::StartWatching: messenger invalid!\n");
    18711896        return B_BAD_VALUE;
    18721897    }
     1898
    18731899    return BPrivate::media::notifications::Register(where, media_node::null,
    18741900        B_MEDIA_WILDCARD);
    18751901}
    BMediaRoster::StartWatching(const BMessenger & where, int32 notificationType)  
    18881914        ERROR("BMediaRoster::StartWatching: notificationType invalid!\n");
    18891915        return B_BAD_VALUE;
    18901916    }
     1917
     1918    // NOTE: we support only explicitly B_MEDIA_SERVER_STARTED/QUIT
     1919    // notifications. This should be cleared in documentation.
     1920
    18911921    return BPrivate::media::notifications::Register(where, media_node::null,
    18921922        notificationType);
    18931923}
    BMediaRoster::MessageReceived(BMessage* message)  
    32533283            return;
    32543284        }
    32553285
     3286        case MEDIA_ROSTER_REQUEST_NOTIFICATIONS:
     3287        {
     3288            RosterNotification notification;
     3289            if (message->FindInt32(NOTIFICATION_PARAM_WHAT, &notification.what)
     3290                != B_OK) {
     3291                TRACE("BMediaRoster MEDIA_ROSTER_REQUEST_NOTIFICATIONS can't"
     3292                    "find what parameter");
     3293                return;
     3294            }
     3295            if (message->FindMessenger(NOTIFICATION_PARAM_MESSENGER,
     3296                &notification.messenger) != B_OK) {
     3297                TRACE("BMediaRoster MEDIA_ROSTER_REQUEST_NOTIFICATIONS can't"
     3298                    "find messenger");
     3299                return;
     3300            }
     3301            sNotificationList.Insert(notification);
     3302            return;
     3303        }
     3304
     3305        case MEDIA_ROSTER_CANCEL_NOTIFICATIONS:
     3306        {
     3307            RosterNotification notification;
     3308            if (message->FindInt32(NOTIFICATION_PARAM_WHAT, &notification.what)
     3309                != B_OK) {
     3310                TRACE("BMediaRoster MEDIA_ROSTER_CANCEL_NOTIFICATIONS can't"
     3311                    "find what parameter");
     3312                return;
     3313            }
     3314            if (message->FindMessenger(NOTIFICATION_PARAM_MESSENGER,
     3315                &notification.messenger) != B_OK) {
     3316                TRACE("BMediaRoster MEDIA_ROSTER_CANCEL_NOTIFICATIONS can't"
     3317                    "find messenger");
     3318                return;
     3319            }
     3320            for (int32 i = 0; i < sNotificationList.CountItems(); i++) {
     3321                RosterNotification* current;
     3322                if (sNotificationList.Get(i, &current) != true)
     3323                    return;
     3324                if (current->what == notification.what
     3325                    && current->messenger == notification.messenger) {
     3326                    sNotificationList.Remove(i);
     3327                    return;
     3328                }
     3329            }
     3330            return;
     3331        }
     3332
     3333        case B_SOME_APP_LAUNCHED:
     3334        {
     3335            BString mimeSig;
     3336            if (message->FindString("be:signature", &mimeSig) != B_OK)
     3337                return;
     3338            if (mimeSig != B_MEDIA_ADDON_SERVER_SIGNATURE
     3339                    && mimeSig != B_MEDIA_SERVER_SIGNATURE)
     3340                return;
     3341
     3342            TRACE("BMediaRoster::MessageReceived media services are going up.");
     3343
     3344            // Send the notification to our subscribers
     3345            if (BMediaRoster::IsRunning()) {
     3346                sServerIsUp = true;
     3347                // Restore our friendship with the media servers
     3348                if (MediaRosterEx(this)->BuildConnections() != B_OK) {
     3349                    TRACE("BMediaRoster::MessageReceived can't reconnect"
     3350                        "to media_server.");
     3351                }
     3352
     3353                for (int32 i = 0; i < sNotificationList.CountItems(); i++) {
     3354                    RosterNotification* current;
     3355                    if (sNotificationList.Get(i, &current) != true)
     3356                        return;
     3357                    if (current->what == B_MEDIA_SERVER_STARTED) {
     3358                        if (current->messenger.SendMessage(
     3359                            B_MEDIA_SERVER_STARTED) != B_OK) {
     3360                            if(!current->messenger.IsValid())
     3361                                sNotificationList.Remove(i);
     3362                        }
     3363                    }
     3364                }
     3365            }
     3366            return;
     3367        }
     3368
     3369        case B_SOME_APP_QUIT:
     3370        {
     3371            BString mimeSig;
     3372            if (message->FindString("be:signature", &mimeSig) != B_OK)
     3373                return;
     3374            if (mimeSig != B_MEDIA_ADDON_SERVER_SIGNATURE
     3375                    && mimeSig != B_MEDIA_SERVER_SIGNATURE)
     3376                return;
     3377
     3378            TRACE("BMediaRoster::MessageReceived media services are down.");
     3379
     3380            // Send the notification to our subscribers
     3381            if (!BMediaRoster::IsRunning() && sServerIsUp == true) {
     3382                sServerIsUp = false;
     3383                for (int32 i = 0; i < sNotificationList.CountItems(); i++) {
     3384                    RosterNotification* current;
     3385                    if (sNotificationList.Get(i, &current) != true)
     3386                        return;
     3387                    if (current->what == B_MEDIA_SERVER_QUIT) {
     3388                        if (current->messenger.SendMessage(
     3389                            B_MEDIA_SERVER_QUIT) != B_OK) {
     3390                            if(!current->messenger.IsValid())
     3391                                sNotificationList.Remove(i);
     3392                        }
     3393                    }
     3394                }
     3395            }
     3396            return;
     3397        }
     3398
    32563399        case NODE_FINAL_RELEASE:
    32573400        {
    32583401            // this function is called by a BMediaNode to delete
    BMediaRoster::~BMediaRoster()  
    33223465    // Unset the global instance pointer, the destructor is also called
    33233466    // if a client app calls Lock(); and Quit(); directly.
    33243467    sDefaultInstance = NULL;
     3468    if (sNotificationList.CountItems() != 0)
     3469        sNotificationList.MakeEmpty();
     3470
     3471    if (be_roster->StopWatching(BMessenger(this, this)) != B_OK)
     3472            TRACE("Can't unregister roster notifications");
    33253473}
    33263474
    33273475
  • src/kits/media/Notifications.cpp

    diff --git a/src/kits/media/Notifications.cpp b/src/kits/media/Notifications.cpp
    index 1ab1bfa..4fb66be 100644
    a b Register(const BMessenger& notifyHandler, const media_node& node,  
    5858    int32 notification)
    5959{
    6060    CALLED();
     61
     62    if (notification == B_MEDIA_SERVER_STARTED
     63        || notification == B_MEDIA_SERVER_QUIT) {
     64        BMessage msg(MEDIA_ROSTER_REQUEST_NOTIFICATIONS);
     65        msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification);
     66        msg.AddMessenger(NOTIFICATION_PARAM_MESSENGER, notifyHandler);
     67        return BPrivate::media::dataexchange::SendToRoster(&msg);
     68    }
     69
    6170    BMessage msg(MEDIA_SERVER_REQUEST_NOTIFICATIONS);
    6271    msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification);
    6372    msg.AddInt32(NOTIFICATION_PARAM_TEAM, BPrivate::current_team());
    Unregister(const BMessenger& notifyHandler, const media_node& node,  
    7382    int32 notification)
    7483{
    7584    CALLED();
     85
     86    if (notification == B_MEDIA_SERVER_STARTED
     87        || notification == B_MEDIA_SERVER_QUIT) {
     88        BMessage msg(MEDIA_ROSTER_CANCEL_NOTIFICATIONS);
     89        msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification);
     90        msg.AddMessenger(NOTIFICATION_PARAM_MESSENGER, notifyHandler);
     91        return BPrivate::media::dataexchange::SendToRoster(&msg);
     92    }
     93
    7694    BMessage msg(MEDIA_SERVER_CANCEL_NOTIFICATIONS);
    7795    msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification);
    7896    msg.AddInt32(NOTIFICATION_PARAM_TEAM, BPrivate::current_team());
    IsValidNotificationRequest(bool node_specific, int32 notification)  
    295313        case B_MEDIA_FLAVORS_CHANGED:
    296314            return true;
    297315
     316        // invalid if we watch for a specific node
     317        case B_MEDIA_SERVER_STARTED:
     318        case B_MEDIA_SERVER_QUIT:
     319            return !node_specific;
     320
    298321        // only valid for node specific watching
    299322        case B_MEDIA_PARAMETER_CHANGED:
    300323        case B_MEDIA_FORMAT_CHANGED: