Media: Improve both notifications and quit mechanism

* Media is now waiting for media_server to start if the window
  is closed before to finish, this was proposed by stippi.
* Moved out anything related to notifications as they are now
  managed by the media_kit.
* Solved some TODOs and minor issues too.
This commit is contained in:
Dario Casalinuovo
2015-07-29 18:05:04 +02:00
parent 8acd164f8c
commit 7482390ab4
5 changed files with 52 additions and 106 deletions
+1 -1
View File
@@ -20,7 +20,7 @@
Media::Media()
:
BApplication(kApplicationSignature),
BApplication("application/x-vnd.Haiku-Media"),
fIcons(),
fWindow(NULL)
{
-3
View File
@@ -17,9 +17,6 @@
#include <Locale.h>
static const char* kApplicationSignature = "application/x-vnd.Haiku-Media";
class Media : public BApplication {
public:
Media();
+2 -1
View File
@@ -62,7 +62,8 @@ SettingsView::MakeRestartButton()
{
return new BButton("restartButton",
B_TRANSLATE("Restart media services"),
new BMessage(ML_RESTART_MEDIA_SERVER));
new BMessage(ML_RESTART_MEDIA_SERVER),
B_ALIGN_RIGHT);
}
+48 -96
View File
@@ -15,7 +15,6 @@
#include <Alert.h>
#include <Application.h>
#include <Autolock.h>
#include <Bitmap.h>
#include <Button.h>
#include <CardLayout.h>
#include <Catalog.h>
@@ -26,7 +25,6 @@
#include <Locale.h>
#include <MediaRoster.h>
#include <MediaTheme.h>
#include <Notification.h>
#include <Resources.h>
#include <Roster.h>
#include <Screen.h>
@@ -46,7 +44,7 @@
const uint32 ML_SELECTED_NODE = 'MlSN';
const uint32 ML_INIT_MEDIA = 'MlIM';
const uint32 ML_RESTART_THREAD_FINISHED = 'MlRF';
class NodeListItemUpdater : public MediaListItem::Visitor {
@@ -101,13 +99,23 @@ MediaWindow::SmartNode::SetTo(const dormant_node_info* info)
fNode = new media_node();
BMediaRoster* roster = BMediaRoster::Roster();
// TODO: error codes
status_t status = B_OK;
media_node_id node_id;
if (roster->GetInstancesFor(info->addon, info->flavor_id, &node_id) == B_OK)
roster->GetNodeFor(node_id, fNode);
status = roster->GetNodeFor(node_id, fNode);
else
roster->InstantiateDormantNode(*info, fNode, B_FLAVOR_IS_GLOBAL);
roster->StartWatching(fMessenger, *fNode, B_MEDIA_WILDCARD);
status = roster->InstantiateDormantNode(*info, fNode, B_FLAVOR_IS_GLOBAL);
if (status != B_OK) {
fprintf(stderr, "SmartNode::SetTo error with node %" B_PRId32
": %s\n", fNode->node, strerror(status));
}
status = roster->StartWatching(fMessenger, *fNode, B_MEDIA_WILDCARD);
if (status != B_OK) {
fprintf(stderr, "SmartNode::SetTo can't start watching for"
" node %" B_PRId32 "\n", fNode->node);
}
}
@@ -142,10 +150,22 @@ MediaWindow::SmartNode::_FreeNode()
{
if (!IsSet())
return;
// TODO: check error codes
BMediaRoster* roster = BMediaRoster::Roster();
roster->StopWatching(fMessenger, *fNode, B_MEDIA_WILDCARD);
roster->ReleaseNode(*fNode);
if (roster != NULL) {
status_t status = roster->StopWatching(fMessenger,
*fNode, B_MEDIA_WILDCARD);
if (status != B_OK) {
fprintf(stderr, "SmartNode::_FreeNode can't unwatch"
" media services for node %" B_PRId32 "\n", fNode->node);
}
roster->ReleaseNode(*fNode);
if (status != B_OK) {
fprintf(stderr, "SmartNode::_FreeNode can't release"
" node %" B_PRId32 "\n", fNode->node);
}
}
delete fNode;
fNode = NULL;
}
@@ -165,7 +185,7 @@ MediaWindow::MediaWindow(BRect frame)
fVideoInputs(5, true),
fVideoOutputs(5, true),
fInitCheck(B_OK),
fRestartingServices(false)
fRestartThread(-1)
{
_InitWindow();
@@ -283,21 +303,15 @@ MediaWindow::UpdateOutputListItem(MediaListItem::media_type type,
bool
MediaWindow::QuitRequested()
{
if (fRestartingServices == true) {
BString text(B_TRANSLATE("The media services are restarting,"
" interructions to this process might result"
" in media functionalities not correctly running."
" Are you really sure to quit?"));
BAlert* alert = new BAlert(B_TRANSLATE("Warning!"), text,
B_TRANSLATE("Do it"), B_TRANSLATE("No"), NULL,
B_WIDTH_AS_USUAL, B_OFFSET_SPACING, B_WARNING_ALERT);
int32 ret = alert->Go();
if (ret == 1)
return false;
status_t exit = B_OK;
if (fRestartThread > 0) {
wait_for_thread(fRestartThread, &exit);
if (exit != B_OK) {
fprintf(stderr, "MediaWindow::QuitRequested wait_for_thread"
" returned with an error: %s\n", strerror(exit));
}
}
// stop watching the MediaRoster
// Stop watching the MediaRoster
fCurrentNode.SetTo(NULL);
be_app->PostMessage(B_QUIT_REQUESTED);
return true;
@@ -308,18 +322,18 @@ void
MediaWindow::MessageReceived(BMessage* message)
{
switch (message->what) {
case ML_INIT_MEDIA:
_InitMedia(false);
case ML_RESTART_THREAD_FINISHED:
fRestartThread = -1;
break;
case ML_RESTART_MEDIA_SERVER:
{
fRestartingServices = true;
thread_id thread = spawn_thread(&MediaWindow::_RestartMediaServices,
fRestartThread = spawn_thread(&MediaWindow::_RestartMediaServices,
"restart_thread", B_NORMAL_PRIORITY, this);
if (thread < 0)
if (fRestartThread < 0)
fprintf(stderr, "couldn't create restart thread\n");
else
resume_thread(thread);
resume_thread(fRestartThread);
break;
}
case B_MEDIA_WEB_CHANGED:
@@ -340,9 +354,7 @@ MediaWindow::MessageReceived(BMessage* message)
case B_MEDIA_SERVER_STARTED:
{
PRINT_OBJECT(*message);
_Notify(0.75, B_TRANSLATE("Starting media server"
B_UTF8_ELLIPSIS));
_InitMedia(false);
break;
}
default:
@@ -421,8 +433,6 @@ MediaWindow::_InitMedia(bool first)
if (alert->Go() == 0)
return B_ERROR;
_Notify(0, B_TRANSLATE("Starting media server" B_UTF8_ELLIPSIS));
Show();
launch_media_server();
@@ -435,9 +445,6 @@ MediaWindow::_InitMedia(bool first)
&& fListView->ItemAt(0)->IsSelected())
isVideoSelected = false;
if (!first || (first && err) )
_Notify(1, B_TRANSLATE("Ready for use" B_UTF8_ELLIPSIS));
while (fListView->CountItems() > 0)
delete fListView->RemoveItem((int32)0);
_EmptyNodeLists();
@@ -639,65 +646,10 @@ MediaWindow::_RestartMediaServices(void* data)
{
MediaWindow* window = (MediaWindow*)data;
shutdown_media_server(B_INFINITE_TIMEOUT, MediaWindow::_UpdateProgress,
data);
shutdown_media_server();
launch_media_server();
window->fRestartingServices = false;
return window->PostMessage(ML_INIT_MEDIA);
}
bool
MediaWindow::_UpdateProgress(int stage, const char* message, 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 70:
string = B_TRANSLATE("Cleaning up.");
break;
case 100:
string = B_TRANSLATE("Done shutting down.");
break;
}
((MediaWindow*)cookie)->_Notify(stage / 150.0, string);
return true;
}
void
MediaWindow::_Notify(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_roster->GetAppInfo(kApplicationSignature, &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();
return window->PostMessage(ML_RESTART_THREAD_FINISHED);
}
+1 -5
View File
@@ -22,7 +22,6 @@
#include "MediaListItem.h"
#include "MediaViews.h"
#define MEDIA_SERVICE_NOTIFICATION_ID "MediaServiceNotificationID"
#define SETTINGS_FILE "MediaPrefs Settings"
@@ -72,9 +71,6 @@ private:
NodeListItem* _FindNodeListItem(dormant_node_info* info);
static status_t _RestartMediaServices(void* data);
static bool _UpdateProgress(int stage, const char* message,
void* cookie);
void _Notify(float progress, const char* message);
void _ClearParamView();
void _MakeParamView();
@@ -112,7 +108,7 @@ private:
NodeList fVideoOutputs;
status_t fInitCheck;
bool fRestartingServices;
thread_id fRestartThread;
};