From 8acd164f8c6bd3a4d36e49648b7deb676b18e2e0 Mon Sep 17 00:00:00 2001 From: Dario Casalinuovo Date: Wed, 29 Jul 2015 18:03:32 +0200 Subject: [PATCH] Add new version of launch_media_server * Due to the needs to provide a peaceful UX, i moved out the notifications mechanism from the Media preflet and i have integrated it with the launch and shutdown functions of MediaDefs.h. * This implied to introduce a new launch_media_server function similar to the shutdown_media_server allowing to specify a custom notification function too. * Both functions then are reworked to send by default notifications to the Deskbar, this was needed because in a lot of situations the mechanism failed without correctly noticing the user. * The one argument launch_media_server is considered to be deprecated, the default argument is removed to mantain binary compatibility but make new apps to automatically use the new one with just the default arguments. This is needed due to conflicts in overloading. * Improve notifications by indirectly extending localization to old BeOS apps. --- headers/os/media/MediaDefs.h | 14 +++- src/kits/media/Jamfile | 2 +- src/kits/media/MediaDefs.cpp | 150 ++++++++++++++++++++++++++++++++--- 3 files changed, 150 insertions(+), 16 deletions(-) diff --git a/headers/os/media/MediaDefs.h b/headers/os/media/MediaDefs.h index a7fa6d8db6..a92956ebf6 100644 --- a/headers/os/media/MediaDefs.h +++ b/headers/os/media/MediaDefs.h @@ -787,11 +787,21 @@ struct buffer_clone_info; // media_server and it's friends. You can provide a call back hook which // will be called during various steps of the process. This callback should // currently always return TRUE. A 'stage' value of 100 means the process is -// completely finished. +// completely finished. Differently from BeOS the functions automatically +// send notifications to the Deskbar if not differently specified. +// It's also provided a new version of launch_media_server allowing +// to specify a custom callback for notifications. + +// Deprecated +status_t launch_media_server(uint32 flags); + +status_t launch_media_server(bigtime_t timeout = B_INFINITE_TIMEOUT, + bool (*progress)(int stage, const char* message, void* cookie) = NULL, + void* cookie = NULL, uint32 flags = 0); + status_t shutdown_media_server(bigtime_t timeout = B_INFINITE_TIMEOUT, bool (*progress)(int stage, const char* message, void* cookie) = NULL, void* cookie = NULL); -status_t launch_media_server(uint32 flags = 0); // Given an image_id, prepare that image_id for realtime media diff --git a/src/kits/media/Jamfile b/src/kits/media/Jamfile index f8299dbbef..35cf1d556b 100644 --- a/src/kits/media/Jamfile +++ b/src/kits/media/Jamfile @@ -89,7 +89,7 @@ for architectureObject in [ MultiArchSubDirSetup ] { ReaderPlugin.cpp WriterPlugin.cpp : - be [ TargetLibsupc++ ] [ TargetLibstdc++ ] + be localestub [ TargetLibsupc++ ] [ TargetLibstdc++ ] ; } } diff --git a/src/kits/media/MediaDefs.cpp b/src/kits/media/MediaDefs.cpp index 4298a2a114..cd6e95a698 100644 --- a/src/kits/media/MediaDefs.cpp +++ b/src/kits/media/MediaDefs.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2015, Dario Casalinuovo * Copyright 2004, 2006, Jérôme Duval. * Copyright 2003-2004, Andrew Bachmann. * Copyright 2002-2004, 2006 Marcus Overhagen. @@ -7,25 +8,35 @@ */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include -#include -#include -#include -#include - -#include "debug.h" - #include "AddOnManager.h" #include "DataExchange.h" +#include "debug.h" #include "MediaMisc.h" #define META_DATA_MAX_SIZE (16 << 20) #define META_DATA_AREA_MIN_SIZE 32000 +#undef B_TRANSLATION_CONTEXT +#define B_TRANSLATION_CONTEXT "MediaDefs" + // #pragma mark - media_destination @@ -1219,6 +1230,67 @@ const type_code B_CODEC_TYPE_INFO = 0x040807b2; // shutdown_media_server() and launch_media_server() // are provided by libbe.so in BeOS R5 +#define MEDIA_SERVICE_NOTIFICATION_ID "MediaServiceNotificationID" + + +void +notify_system(float progress, const char* message) +{ + BNotification notification(B_PROGRESS_NOTIFICATION); + notification.SetMessageID(MEDIA_SERVICE_NOTIFICATION_ID); + notification.SetProgress(progress); + notification.SetGroup(B_TRANSLATE("Media Service")); + notification.SetContent(message); + + app_info info; + be_app->GetAppInfo(&info); + BBitmap icon(BRect(0, 0, 32, 32), B_RGBA32); + BNode node(&info.ref); + BIconUtils::GetVectorIcon(&node, "BEOS:ICON", &icon); + notification.SetIcon(&icon); + + notification.Send(); +} + + +void +progress_shutdown(int stage, + bool (*progress)(int stage, const char* message, void* cookie), + void* cookie) +{ + // parameter "message" is no longer used. It is kept for compatibility with + // BeOS as this is used as a shutdown_media_server callback. + + PRINT(("stage : %i\n", stage)); + const char* string = "Unknown stage"; + switch (stage) { + case 10: + string = B_TRANSLATE("Stopping media server" B_UTF8_ELLIPSIS); + break; + case 20: + string = B_TRANSLATE("Telling media_addon_server to quit."); + break; + case 40: + string = B_TRANSLATE("Waiting for media_server to quit."); + break; + case 50: + string = B_TRANSLATE("Waiting for media_server to quit."); + break; + case 70: + string = B_TRANSLATE("Cleaning up."); + break; + case 100: + string = B_TRANSLATE("Done shutting down."); + break; + } + + if (progress == NULL) + notify_system(stage, string); + else + progress(stage, string, cookie); +} + + status_t shutdown_media_server(bigtime_t timeout, bool (*progress)(int stage, const char* message, void* cookie), @@ -1233,7 +1305,7 @@ shutdown_media_server(bigtime_t timeout, if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) { BMessenger messenger(B_MEDIA_SERVER_SIGNATURE); - progress(10, "Telling media_server to quit.", cookie); + progress_shutdown(10, progress, cookie); err = messenger.SendMessage(&msg, &reply, 2000000, 2000000); if (err != B_OK) @@ -1246,7 +1318,7 @@ shutdown_media_server(bigtime_t timeout, if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) { BMessenger messenger(B_MEDIA_ADDON_SERVER_SIGNATURE); - progress(20, "Telling media_addon_server to quit.", cookie); + progress_shutdown(20, progress, cookie); err = messenger.SendMessage(&msg, &reply, 2000000, 2000000); if (err != B_OK) @@ -1258,16 +1330,16 @@ shutdown_media_server(bigtime_t timeout, } if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) { - progress(40, "Waiting for media_server to quit.", cookie); + progress_shutdown(40, progress, cookie); snooze(200000); } if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) { - progress(50, "Waiting for media_addon_server to quit.", cookie); + progress_shutdown(50, progress, cookie); snooze(200000); } - progress(70, "Cleaning Up.", cookie); + progress_shutdown(70, progress, cookie); snooze(1000000); if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) { @@ -1278,31 +1350,79 @@ shutdown_media_server(bigtime_t timeout, kill_team(be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE)); } - progress(100, "Done Shutting Down.", cookie); + progress_shutdown(100, progress, cookie); snooze(1000000); return B_OK; } +void +progress_startup(int stage, + bool (*progress)(int stage, const char* message, void* cookie), + void* cookie) +{ + // parameter "message" is no longer used. It is kept for compatibility with + // BeOS as this is used as a shutdown_media_server callback. + + PRINT(("stage : %i\n", stage)); + const char* string = "Unknown stage"; + switch (stage) { + case 10: + string = B_TRANSLATE("Stopping media server" B_UTF8_ELLIPSIS); + break; + case 20: + string = B_TRANSLATE("Telling media_addon_server to quit."); + break; + case 50: + string = B_TRANSLATE("Starting media_services."); + break; + case 90: + string = B_TRANSLATE("Error occurred starting media services."); + break; + case 100: + string = B_TRANSLATE("Ready for use."); + break; + } + + if (progress == NULL) + notify_system(stage, string); + else + progress(stage, string, cookie); +} + + status_t launch_media_server(uint32 flags) +{ + return launch_media_server(0, NULL, NULL, flags); +} + + +status_t +launch_media_server(bigtime_t timeout, + bool (*progress)(int stage, const char* message, void* cookie), + void* cookie, uint32 flags) { if (BMediaRoster::IsRunning()) return B_ALREADY_RUNNING; // The media_server crashed if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) { + progress_startup(10, progress, cookie); kill_team(be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE)); snooze(1000000); } // The media_addon_server crashed if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) { + progress_startup(20, progress, cookie); kill_team(be_roster->TeamFor(B_MEDIA_SERVER_SIGNATURE)); snooze(1000000); } + progress_startup(50, progress, cookie); + status_t err = be_roster->Launch(B_MEDIA_SERVER_SIGNATURE); if (err != B_OK) return err; @@ -1318,10 +1438,14 @@ launch_media_server(uint32 flags) if (messenger.IsValid()) { messenger.SendMessage(&msg, &reply, 2000000, 2000000); err = B_OK; + progress_startup(100, progress, cookie); break; } } + if (err != B_OK) + progress_startup(90, progress, cookie); + return err; }