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 , 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 { 47 47 B_MEDIA_NEW_PARAMETER_VALUE, /* N "node", "parameter", "when", */ 48 48 /* "value" */ 49 49 B_MEDIA_NODE_STOPPED, /* N "node", "when" */ 50 B_MEDIA_FLAVORS_CHANGED 50 B_MEDIA_FLAVORS_CHANGED, /* "be:addon_id", "be:new_count", */ 51 51 /* "be:gone_count" */ 52 B_MEDIA_SERVER_STARTED, 53 B_MEDIA_SERVER_QUIT 52 54 }; 53 55 54 56 -
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 { 16 16 namespace dataexchange { 17 17 18 18 19 void InitDataExchange(); 19 void InitServerDataExchange(); 20 void InitRosterDataExchange(const BMessenger& rosterMessenger); 21 22 // BMessage based data exchange with the current BMediaRoster 23 status_t SendToRoster(BMessage* msg); 20 24 21 25 // BMessage based data exchange with the media_server 22 26 status_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: 87 87 88 88 BTimeSource* MakeTimeSourceObject(media_node_id timesource_id); 89 89 90 // Build the connection with the media_server 91 status_t BuildConnections(); 92 90 93 private: 91 94 friend class BMediaRoster; 92 95 }; -
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 { 32 32 MEDIA_ADD_ON_SERVER_PLAY_MEDIA = '_TRU' 33 33 }; 34 34 35 enum { 36 // local media services status notification service 37 MEDIA_ROSTER_REQUEST_NOTIFICATIONS = 2000, 38 MEDIA_ROSTER_CANCEL_NOTIFICATIONS 39 }; 40 35 41 // Raw port based communication 36 42 enum { 37 43 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 { 25 25 26 26 27 27 static BMessenger sMediaServerMessenger; 28 static BMessenger sMediaRosterMessenger; 28 29 static port_id sMediaServerPort; 29 30 static port_id sMediaAddonServerPort; 30 31 … … find_media_addon_server_port() 58 59 59 60 60 61 void 61 Init DataExchange()62 InitServerDataExchange() 62 63 { 63 64 sMediaServerMessenger = BMessenger(B_MEDIA_SERVER_SIGNATURE); 64 65 find_media_server_port(); … … InitDataExchange() 66 67 } 67 68 68 69 70 void 71 InitRosterDataExchange(const BMessenger& rosterMessenger) 72 { 73 sMediaRosterMessenger = rosterMessenger; 74 } 75 76 77 //! BMessage based data exchange with the local BMediaRoster 78 status_t 79 SendToRoster(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 69 91 //! BMessage based data exchange with the media_server 70 92 status_t 71 93 SendToServer(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 " 67 67 #include <Notifications.h> 68 68 #include <ServerInterface.h> 69 69 #include <SharedBufferList.h> 70 #include <TList.h> 70 71 71 72 #include "TimeSourceObjectManager.h" 72 73 … … namespace BPrivate { 75 76 namespace media { 76 77 77 78 79 struct RosterNotification { 80 BMessenger messenger; 81 int32 what; 82 }; 83 84 static bool sServerIsUp = false; 85 static List<RosterNotification> sNotificationList; 86 78 87 class MediaInitializer { 79 88 public: 80 89 MediaInitializer() 81 90 { 82 Init DataExchange();91 InitServerDataExchange(); 83 92 } 84 93 85 94 ~MediaInitializer() … … BMediaRosterEx::BMediaRosterEx(status_t* _error) 105 114 : 106 115 BMediaRoster() 107 116 { 108 InitDataExchange();109 110 117 gDormantNodeManager = new DormantNodeManager; 111 118 gTimeSourceObjectManager = new TimeSourceObjectManager; 112 119 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 132 status_t 133 BMediaRosterEx::BuildConnections() 134 { 135 InitServerDataExchange(); 136 113 137 // register this application with the media server 114 138 server_register_app_request request; 115 139 server_register_app_reply reply; … … BMediaRosterEx::BMediaRosterEx(status_t* _error) 118 142 119 143 status_t status = QueryServer(SERVER_REGISTER_APP, &request, 120 144 sizeof(request), &reply, sizeof(reply)); 145 121 146 if (status != B_OK) 122 *_error =B_MEDIA_SYSTEM_FAILURE;147 return B_MEDIA_SYSTEM_FAILURE; 123 148 else 124 *_error =B_OK;149 return B_OK; 125 150 } 126 151 127 152 … … BMediaRoster::StartWatching(const BMessenger& where) 1870 1895 ERROR("BMediaRoster::StartWatching: messenger invalid!\n"); 1871 1896 return B_BAD_VALUE; 1872 1897 } 1898 1873 1899 return BPrivate::media::notifications::Register(where, media_node::null, 1874 1900 B_MEDIA_WILDCARD); 1875 1901 } … … BMediaRoster::StartWatching(const BMessenger & where, int32 notificationType) 1888 1914 ERROR("BMediaRoster::StartWatching: notificationType invalid!\n"); 1889 1915 return B_BAD_VALUE; 1890 1916 } 1917 1918 // NOTE: we support only explicitly B_MEDIA_SERVER_STARTED/QUIT 1919 // notifications. This should be cleared in documentation. 1920 1891 1921 return BPrivate::media::notifications::Register(where, media_node::null, 1892 1922 notificationType); 1893 1923 } … … BMediaRoster::MessageReceived(BMessage* message) 3253 3283 return; 3254 3284 } 3255 3285 3286 case MEDIA_ROSTER_REQUEST_NOTIFICATIONS: 3287 { 3288 RosterNotification notification; 3289 if (message->FindInt32(NOTIFICATION_PARAM_WHAT, ¬ification.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 ¬ification.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, ¬ification.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 ¬ification.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, ¤t) != 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, ¤t) != 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, ¤t) != 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 3256 3399 case NODE_FINAL_RELEASE: 3257 3400 { 3258 3401 // this function is called by a BMediaNode to delete … … BMediaRoster::~BMediaRoster() 3322 3465 // Unset the global instance pointer, the destructor is also called 3323 3466 // if a client app calls Lock(); and Quit(); directly. 3324 3467 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"); 3325 3473 } 3326 3474 3327 3475 -
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, 58 58 int32 notification) 59 59 { 60 60 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 61 70 BMessage msg(MEDIA_SERVER_REQUEST_NOTIFICATIONS); 62 71 msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification); 63 72 msg.AddInt32(NOTIFICATION_PARAM_TEAM, BPrivate::current_team()); … … Unregister(const BMessenger& notifyHandler, const media_node& node, 73 82 int32 notification) 74 83 { 75 84 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 76 94 BMessage msg(MEDIA_SERVER_CANCEL_NOTIFICATIONS); 77 95 msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification); 78 96 msg.AddInt32(NOTIFICATION_PARAM_TEAM, BPrivate::current_team()); … … IsValidNotificationRequest(bool node_specific, int32 notification) 295 313 case B_MEDIA_FLAVORS_CHANGED: 296 314 return true; 297 315 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 298 321 // only valid for node specific watching 299 322 case B_MEDIA_PARAMETER_CHANGED: 300 323 case B_MEDIA_FORMAT_CHANGED: