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.
This commit is contained in:
Dario Casalinuovo 2015-07-29 18:03:32 +02:00
parent e716f48778
commit 8acd164f8c
3 changed files with 150 additions and 16 deletions

View File

@ -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

View File

@ -89,7 +89,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
ReaderPlugin.cpp
WriterPlugin.cpp
:
be [ TargetLibsupc++ ] [ TargetLibstdc++ ]
be localestub [ TargetLibsupc++ ] [ TargetLibstdc++ ]
;
}
}

View File

@ -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 <MediaDefs.h>
#include <Application.h>
#include <Bitmap.h>
#include <Catalog.h>
#include <IconUtils.h>
#include <Locale.h>
#include <MediaNode.h>
#include <MediaRoster.h>
#include <Node.h>
#include <Notification.h>
#include <Roster.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <MediaDefs.h>
#include <MediaNode.h>
#include <MediaRoster.h>
#include <Roster.h>
#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;
}