2020-02-03 22:31:44 +00:00
|
|
|
#include <cstdio>
|
|
|
|
#include <iostream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <array>
|
|
|
|
#include "dbus_info.h"
|
2020-04-13 00:02:52 +00:00
|
|
|
#include "string_utils.h"
|
2020-02-03 22:31:44 +00:00
|
|
|
|
|
|
|
using ms = std::chrono::milliseconds;
|
|
|
|
|
2020-05-11 19:01:40 +00:00
|
|
|
struct metadata main_metadata;
|
2020-04-13 00:02:52 +00:00
|
|
|
|
2020-02-03 22:31:44 +00:00
|
|
|
typedef std::vector<std::pair<std::string, std::string>> string_pair_vec;
|
2020-04-13 00:02:52 +00:00
|
|
|
typedef std::unordered_map<std::string, string_pair_vec> string_pair_vec_map;
|
|
|
|
typedef std::unordered_map<std::string, std::string> string_map;
|
2020-02-03 22:31:44 +00:00
|
|
|
|
2020-05-28 17:52:32 +00:00
|
|
|
#define DBUS_TIMEOUT 2000 // ms
|
|
|
|
|
2020-02-03 22:31:44 +00:00
|
|
|
std::string format_signal(const DBusSignal& s)
|
|
|
|
{
|
|
|
|
std::stringstream ss;
|
|
|
|
ss << "type='signal',interface='" << s.intf << "'";
|
|
|
|
ss << ",member='" << s.signal << "'";
|
|
|
|
return ss.str();
|
|
|
|
}
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
static bool check_msg_arg(libdbus_loader& dbus, DBusMessageIter *iter, int type)
|
2020-02-03 22:31:44 +00:00
|
|
|
{
|
|
|
|
int curr_type = DBUS_TYPE_INVALID;
|
2020-04-04 20:47:48 +00:00
|
|
|
if ((curr_type = dbus.message_iter_get_arg_type (iter)) != type) {
|
|
|
|
#ifndef NDEBUG
|
2020-02-03 22:31:44 +00:00
|
|
|
std::cerr << "Argument is not of type '" << (char)type << "' != '" << (char) curr_type << "'" << std::endl;
|
2020-04-04 20:47:48 +00:00
|
|
|
#endif
|
2020-02-03 22:31:44 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
bool get_string_array(libdbus_loader& dbus, DBusMessageIter *iter_, std::vector<std::string>& entries)
|
2020-02-03 22:31:44 +00:00
|
|
|
{
|
|
|
|
DBusMessageIter iter = *iter_;
|
|
|
|
DBusMessageIter subiter;
|
|
|
|
int current_type = DBUS_TYPE_INVALID;
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
current_type = dbus.message_iter_get_arg_type (&iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
if (current_type == DBUS_TYPE_VARIANT) {
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_recurse (&iter, &iter);
|
|
|
|
current_type = dbus.message_iter_get_arg_type (&iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (current_type != DBUS_TYPE_ARRAY) {
|
2020-04-04 20:47:48 +00:00
|
|
|
#ifndef NDEBUG
|
2020-02-03 22:31:44 +00:00
|
|
|
std::cerr << "Not an array: '" << (char)current_type << "'" << std::endl;
|
2020-04-04 20:47:48 +00:00
|
|
|
#endif
|
2020-02-03 22:31:44 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *val = nullptr;
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_recurse (&iter, &subiter);
|
2020-02-03 22:31:44 +00:00
|
|
|
entries.clear();
|
2020-04-04 20:47:48 +00:00
|
|
|
while ((current_type = dbus.message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) {
|
2020-02-03 22:31:44 +00:00
|
|
|
if (current_type == DBUS_TYPE_STRING)
|
|
|
|
{
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_get_basic (&subiter, &val);
|
2020-02-03 22:31:44 +00:00
|
|
|
entries.push_back(val);
|
|
|
|
}
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_next (&subiter);
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
static bool get_variant_string(libdbus_loader& dbus, DBusMessageIter *iter_, std::string &val, bool key_or_value = false)
|
2020-02-03 22:31:44 +00:00
|
|
|
{
|
|
|
|
DBusMessageIter iter = *iter_;
|
|
|
|
char *str = nullptr;
|
2020-04-04 20:47:48 +00:00
|
|
|
int type = dbus.message_iter_get_arg_type (&iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
if (type != DBUS_TYPE_VARIANT && type != DBUS_TYPE_DICT_ENTRY)
|
|
|
|
return false;
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_recurse (&iter, &iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
|
|
|
|
if (key_or_value) {
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_next (&iter);
|
|
|
|
if (!check_msg_arg (dbus, &iter, DBUS_TYPE_VARIANT))
|
2020-02-03 22:31:44 +00:00
|
|
|
return false;
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_recurse (&iter, &iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
if (!check_msg_arg (dbus, &iter, DBUS_TYPE_STRING))
|
2020-02-03 22:31:44 +00:00
|
|
|
return false;
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_get_basic(&iter, &str);
|
2020-02-03 22:31:44 +00:00
|
|
|
val = str;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
static bool get_variant_string(libdbus_loader& dbus, DBusMessage *msg, std::string &val, bool key_or_value = false)
|
2020-02-03 22:31:44 +00:00
|
|
|
{
|
|
|
|
DBusMessageIter iter;
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_init (msg, &iter);
|
|
|
|
return get_variant_string(dbus, &iter, val, key_or_value);
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
static void parse_mpris_metadata(libdbus_loader& dbus, DBusMessageIter *iter_, string_pair_vec& entries)
|
2020-02-03 22:31:44 +00:00
|
|
|
{
|
|
|
|
DBusMessageIter subiter, iter = *iter_;
|
|
|
|
std::string key, val;
|
|
|
|
std::vector<std::string> list;
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
while (dbus.message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID)
|
2020-02-03 22:31:44 +00:00
|
|
|
{
|
2020-04-04 20:47:48 +00:00
|
|
|
//std::cerr << "\ttype: " << (char)dbus.message_iter_get_arg_type(&iter) << std::endl;
|
|
|
|
if (!get_variant_string(dbus, &iter, key))
|
2020-02-03 22:31:44 +00:00
|
|
|
return;
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_recurse (&iter, &subiter);
|
|
|
|
dbus.message_iter_next (&subiter);
|
2020-02-03 22:31:44 +00:00
|
|
|
|
|
|
|
//std::cerr << "\tkey: " << key << std::endl;
|
2020-04-04 20:47:48 +00:00
|
|
|
if (get_variant_string(dbus, &subiter, val)) {
|
2020-02-03 22:31:44 +00:00
|
|
|
//std::cerr << "\t\t" << val << std::endl;
|
|
|
|
entries.push_back({key, val});
|
|
|
|
}
|
2020-04-04 20:47:48 +00:00
|
|
|
else if (get_string_array(dbus, &subiter, list)) {
|
2020-02-03 22:31:44 +00:00
|
|
|
for (auto& s : list) {
|
|
|
|
//std::cerr << "\t\t" << s << std::endl;
|
|
|
|
entries.push_back({key, s});
|
|
|
|
}
|
|
|
|
}
|
2020-04-13 00:02:52 +00:00
|
|
|
dbus.message_iter_next (&iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-13 00:02:52 +00:00
|
|
|
static void parse_mpris_properties(libdbus_loader& dbus, DBusMessage *msg, std::string& source, string_pair_vec_map& entries_map)
|
2020-02-03 22:31:44 +00:00
|
|
|
{
|
|
|
|
const char *val_char = nullptr;
|
|
|
|
DBusMessageIter iter;
|
|
|
|
std::string key, val;
|
|
|
|
|
|
|
|
std::vector<DBusMessageIter> stack;
|
|
|
|
stack.push_back({});
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_init (msg, &stack.back());
|
2020-02-03 22:31:44 +00:00
|
|
|
|
|
|
|
// Should be 'org.mpris.MediaPlayer2.Player'
|
2020-04-04 20:47:48 +00:00
|
|
|
if (!check_msg_arg(dbus, &stack.back(), DBUS_TYPE_STRING))
|
2020-02-03 22:31:44 +00:00
|
|
|
return;
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_get_basic(&stack.back(), &val_char);
|
2020-02-03 22:31:44 +00:00
|
|
|
source = val_char;
|
|
|
|
|
|
|
|
if (source != "org.mpris.MediaPlayer2.Player")
|
|
|
|
return;
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_next (&stack.back());
|
|
|
|
//std::cerr << "type: " << (char)dbus.message_iter_get_arg_type(&stack.back()) << std::endl;
|
|
|
|
if (!check_msg_arg(dbus, &stack.back(), DBUS_TYPE_ARRAY))
|
2020-02-03 22:31:44 +00:00
|
|
|
return;
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_recurse (&stack.back(), &iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
stack.push_back(iter);
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
while (dbus.message_iter_get_arg_type(&stack.back()) != DBUS_TYPE_INVALID)
|
2020-02-03 22:31:44 +00:00
|
|
|
{
|
2020-04-04 20:47:48 +00:00
|
|
|
if (!get_variant_string(dbus, &stack.back(), key)) {
|
|
|
|
dbus.message_iter_next (&stack.back());
|
2020-02-03 22:31:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (key == "Metadata") {
|
|
|
|
#ifndef NDEBUG
|
|
|
|
std::cerr << __func__ << ": Found Metadata!" << std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// dive into Metadata
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_recurse (&stack.back(), &iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
|
|
|
|
// get the array of entries
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_next (&iter);
|
|
|
|
if (!check_msg_arg(dbus, &iter, DBUS_TYPE_VARIANT))
|
2020-02-03 22:31:44 +00:00
|
|
|
continue;
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_recurse (&iter, &iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
if (!check_msg_arg(dbus, &iter, DBUS_TYPE_ARRAY))
|
2020-02-03 22:31:44 +00:00
|
|
|
continue;
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_recurse (&iter, &iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
|
2020-04-13 00:02:52 +00:00
|
|
|
parse_mpris_metadata(dbus, &iter, entries_map["Metadata"]);
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
else if (key == "PlaybackStatus") {
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_recurse (&stack.back(), &iter);
|
|
|
|
dbus.message_iter_next (&iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
if (get_variant_string(dbus, &iter, val))
|
2020-04-13 00:02:52 +00:00
|
|
|
entries_map["PlaybackStatus"].push_back({key, val});
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_next (&stack.back());
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
static void parse_property_changed(libdbus_loader& dbus, DBusMessage *msg, std::string& source, string_pair_vec& entries)
|
2020-02-03 22:31:44 +00:00
|
|
|
{
|
|
|
|
char *name = nullptr;
|
|
|
|
int i;
|
|
|
|
uint64_t u64;
|
|
|
|
double d;
|
|
|
|
|
|
|
|
std::vector<DBusMessageIter> stack;
|
|
|
|
stack.push_back({});
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
2020-04-04 20:47:48 +00:00
|
|
|
std::vector<char> padding;
|
|
|
|
padding.push_back('\0');
|
2020-02-03 22:31:44 +00:00
|
|
|
#endif
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_init (msg, &stack.back());
|
2020-02-03 22:31:44 +00:00
|
|
|
int type, prev_type = 0;
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
type = dbus.message_iter_get_arg_type (&stack.back());
|
2020-02-03 22:31:44 +00:00
|
|
|
if (type != DBUS_TYPE_STRING) {
|
2020-04-04 20:47:48 +00:00
|
|
|
#ifndef NDEBUG
|
2020-02-03 22:31:44 +00:00
|
|
|
std::cerr << __func__ << "First element is not a string" << std::endl;
|
2020-04-04 20:47:48 +00:00
|
|
|
#endif
|
2020-02-03 22:31:44 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_get_basic(&stack.back(), &name);
|
2020-02-03 22:31:44 +00:00
|
|
|
source = name;
|
|
|
|
#ifndef NDEBUG
|
|
|
|
std::cout << name << std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
std::pair<std::string, std::string> kv;
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_next (&stack.back());
|
|
|
|
// the loop should be able parse the whole message if used for generic use-cases
|
|
|
|
while ((type = dbus.message_iter_get_arg_type (&stack.back())) != DBUS_TYPE_INVALID) {
|
2020-02-03 22:31:44 +00:00
|
|
|
#ifndef NDEBUG
|
2020-04-04 20:47:48 +00:00
|
|
|
padding.back() = ' ';
|
|
|
|
padding.resize(stack.size() + 1, ' ');
|
|
|
|
padding.back() = '\0';
|
|
|
|
std::cout << padding.data() << "Type: " << (char)type;
|
2020-02-03 22:31:44 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
if (type == DBUS_TYPE_STRING) {
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_get_basic(&stack.back(), &name);
|
2020-02-03 22:31:44 +00:00
|
|
|
#ifndef NDEBUG
|
|
|
|
std::cout << "=" << name << std::endl;
|
|
|
|
#endif
|
|
|
|
if (prev_type == DBUS_TYPE_DICT_ENTRY) // is key ?
|
|
|
|
kv.first = name;
|
|
|
|
if (prev_type == DBUS_TYPE_VARIANT || prev_type == DBUS_TYPE_ARRAY) { // is value ?
|
|
|
|
kv.second = name;
|
|
|
|
entries.push_back(kv);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (type == DBUS_TYPE_INT32) {
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_get_basic(&stack.back(), &i);
|
2020-02-03 22:31:44 +00:00
|
|
|
#ifndef NDEBUG
|
|
|
|
std::cout << "=" << i << std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if (type == DBUS_TYPE_UINT64) {
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_get_basic(&stack.back(), &u64);
|
2020-02-03 22:31:44 +00:00
|
|
|
#ifndef NDEBUG
|
|
|
|
std::cout << "=" << u64 << std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if (type == DBUS_TYPE_DOUBLE) {
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_get_basic(&stack.back(), &d);
|
2020-02-03 22:31:44 +00:00
|
|
|
#ifndef NDEBUG
|
|
|
|
std::cout << "=" << d << std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if (type == DBUS_TYPE_ARRAY || type == DBUS_TYPE_DICT_ENTRY || type == DBUS_TYPE_VARIANT) {
|
|
|
|
#ifndef NDEBUG
|
|
|
|
std::cout << std::endl;
|
|
|
|
#endif
|
|
|
|
prev_type = type;
|
|
|
|
DBusMessageIter iter;
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_recurse (&stack.back(), &iter);
|
|
|
|
if (dbus.message_iter_get_arg_type (&stack.back()) != DBUS_TYPE_INVALID)
|
2020-02-03 22:31:44 +00:00
|
|
|
stack.push_back(iter);
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
#ifndef NDEBUG
|
|
|
|
std::cout << std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
while(FALSE == dbus.message_iter_next (&stack.back()) && stack.size() > 1) {
|
2020-02-03 22:31:44 +00:00
|
|
|
stack.pop_back();
|
|
|
|
prev_type = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
bool get_dict_string_array(libdbus_loader& dbus, DBusMessage *msg, string_pair_vec& entries)
|
2020-02-03 22:31:44 +00:00
|
|
|
{
|
|
|
|
DBusMessageIter iter, outer_iter;
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_init (msg, &outer_iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
int current_type = DBUS_TYPE_INVALID;
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
current_type = dbus.message_iter_get_arg_type (&outer_iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
|
|
|
|
if (current_type == DBUS_TYPE_VARIANT) {
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_recurse (&outer_iter, &outer_iter);
|
|
|
|
current_type = dbus.message_iter_get_arg_type (&outer_iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (current_type != DBUS_TYPE_ARRAY) {
|
2020-04-04 20:47:48 +00:00
|
|
|
#ifndef NDEBUG
|
2020-02-03 22:31:44 +00:00
|
|
|
std::cerr << "Not an array " << (char)current_type << std::endl;
|
2020-04-04 20:47:48 +00:00
|
|
|
#endif
|
2020-02-03 22:31:44 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *val_key = nullptr, *val_value = nullptr;
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_recurse (&outer_iter, &outer_iter);
|
|
|
|
while ((current_type = dbus.message_iter_get_arg_type (&outer_iter)) != DBUS_TYPE_INVALID) {
|
2020-02-03 22:31:44 +00:00
|
|
|
// printf("type: %d\n", current_type);
|
|
|
|
|
|
|
|
if (current_type == DBUS_TYPE_DICT_ENTRY)
|
|
|
|
{
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_recurse (&outer_iter, &iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
|
|
|
|
// dict entry key
|
2020-04-04 20:47:48 +00:00
|
|
|
//printf("\tentry: {%c, ", dbus.message_iter_get_arg_type (&iter));
|
|
|
|
dbus.message_iter_get_basic (&iter, &val_key);
|
2020-02-03 22:31:44 +00:00
|
|
|
std::string key = val_key;
|
|
|
|
|
|
|
|
// dict entry value
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_next (&iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
if (dbus.message_iter_get_arg_type (&iter) == DBUS_TYPE_VARIANT)
|
|
|
|
dbus.message_iter_recurse (&iter, &iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
if (dbus.message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY) {
|
|
|
|
dbus.message_iter_recurse (&iter, &iter);
|
|
|
|
if (dbus.message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING) {
|
|
|
|
//printf("%c}\n", dbus.message_iter_get_arg_type (&iter));
|
|
|
|
dbus.message_iter_get_basic (&iter, &val_value);
|
2020-02-03 22:31:44 +00:00
|
|
|
entries.push_back({val_key, val_value});
|
|
|
|
}
|
|
|
|
}
|
2020-04-04 20:47:48 +00:00
|
|
|
else if (dbus.message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING) {
|
|
|
|
//printf("%c}\n", dbus.message_iter_get_arg_type (&iter));
|
|
|
|
dbus.message_iter_get_basic (&iter, &val_value);
|
2020-02-03 22:31:44 +00:00
|
|
|
entries.push_back({val_key, val_value});
|
|
|
|
}
|
|
|
|
}
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_iter_next (&outer_iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-04-13 00:02:52 +00:00
|
|
|
static void assign_metadata(metadata& meta, string_pair_vec_map& entries_map)
|
2020-02-03 22:31:44 +00:00
|
|
|
{
|
2020-04-13 00:02:52 +00:00
|
|
|
string_pair_vec_map::const_iterator it;
|
|
|
|
it = entries_map.find("Metadata");
|
|
|
|
if (it != entries_map.end()) {
|
|
|
|
meta.title.clear();
|
|
|
|
meta.artists.clear();
|
|
|
|
meta.album.clear();
|
|
|
|
|
|
|
|
std::lock_guard<std::mutex> lk(meta.mutex);
|
|
|
|
std::vector<std::string> artists;
|
|
|
|
meta.valid = false;
|
|
|
|
for (auto& kv : it->second) {
|
|
|
|
#ifndef NDEBUG
|
|
|
|
std::cerr << kv.first << " = " << kv.second << std::endl;
|
|
|
|
#endif
|
|
|
|
if (kv.first == "xesam:artist")
|
|
|
|
artists.push_back(kv.second);
|
|
|
|
else if (kv.first == "xesam:title")
|
|
|
|
meta.title = kv.second;
|
|
|
|
else if (kv.first == "xesam:album")
|
|
|
|
meta.album = kv.second;
|
|
|
|
else if (kv.first == "mpris:artUrl")
|
|
|
|
meta.artUrl = kv.second;
|
|
|
|
else if (kv.first == "PlaybackStatus")
|
|
|
|
meta.playing = (kv.second == "Playing");
|
|
|
|
}
|
2020-04-04 21:12:01 +00:00
|
|
|
|
2020-04-13 00:02:52 +00:00
|
|
|
// XXX Spotify only sends one artist anyway
|
|
|
|
for (auto p = artists.begin(); p != artists.end(); p++) {
|
|
|
|
meta.artists += *p;
|
|
|
|
if (p != artists.end() - 1)
|
|
|
|
meta.artists += ", ";
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-13 00:02:52 +00:00
|
|
|
it = entries_map.find("PlaybackStatus");
|
|
|
|
if (it != entries_map.end()) {
|
|
|
|
for (auto& kv : it->second) {
|
|
|
|
if (kv.first == "PlaybackStatus")
|
|
|
|
meta.playing = (kv.second == "Playing");
|
|
|
|
}
|
2020-04-04 20:47:48 +00:00
|
|
|
}
|
|
|
|
|
2020-02-03 22:31:44 +00:00
|
|
|
if (meta.artists.size() || !meta.title.empty())
|
2020-05-11 19:01:40 +00:00
|
|
|
meta.valid = true;
|
2020-04-04 20:47:48 +00:00
|
|
|
|
|
|
|
meta.ticker.needs_recalc = true;
|
|
|
|
meta.ticker.pos = 0;
|
|
|
|
meta.ticker.longest = 0;
|
|
|
|
meta.ticker.dir = -1;
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
|
2020-04-13 00:02:52 +00:00
|
|
|
bool dbus_get_name_owner(dbusmgr::dbus_manager& dbus_mgr, std::string& name_owner, const char *name)
|
|
|
|
{
|
|
|
|
auto& dbus = dbus_mgr.dbus();
|
|
|
|
DBusError error;
|
|
|
|
|
|
|
|
DBusMessage * dbus_reply = nullptr;
|
|
|
|
DBusMessage * dbus_msg = nullptr;
|
|
|
|
|
|
|
|
// dbus-send --session --dest=org.freedesktop.DBus --type=method_call --print-reply /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:"org.mpris.MediaPlayer2.spotify"
|
|
|
|
if (nullptr == (dbus_msg = dbus.message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "GetNameOwner"))) {
|
2020-05-28 17:52:32 +00:00
|
|
|
std::cerr << "MANGOHUD: " << __func__ << ": unable to allocate memory for dbus message\n";
|
|
|
|
return false;
|
2020-04-13 00:02:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!dbus.message_append_args (dbus_msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) {
|
|
|
|
dbus.message_unref(dbus_msg);
|
|
|
|
std::cerr << "MANGOHUD: " << __func__ << ": dbus_message_append_args failed\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-05-28 17:52:32 +00:00
|
|
|
dbus.error_init(&error);
|
|
|
|
if (nullptr == (dbus_reply = dbus.connection_send_with_reply_and_block(dbus_mgr.get_conn(), dbus_msg, DBUS_TIMEOUT, &error))) {
|
2020-04-13 00:02:52 +00:00
|
|
|
dbus.message_unref(dbus_msg);
|
|
|
|
std::cerr << "MANGOHUD: " << __func__ << ": "<< error.message << "\n";
|
|
|
|
dbus.error_free(&error);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* val = nullptr;
|
|
|
|
DBusMessageIter iter;
|
|
|
|
dbus.message_iter_init (dbus_reply, &iter);
|
|
|
|
|
|
|
|
if (dbus.message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
dbus.message_iter_get_basic(&iter, &val);
|
|
|
|
if (val)
|
|
|
|
name_owner = val;
|
|
|
|
|
|
|
|
dbus.message_unref(dbus_msg);
|
|
|
|
dbus.message_unref(dbus_reply);
|
|
|
|
dbus.error_free(&error);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-05-22 12:00:35 +00:00
|
|
|
bool dbus_get_player_property(dbusmgr::dbus_manager& dbus_mgr, string_pair_vec& entries, const char * dest, const char * prop)
|
2020-02-03 22:31:44 +00:00
|
|
|
{
|
2020-04-04 20:47:48 +00:00
|
|
|
auto& dbus = dbus_mgr.dbus();
|
2020-02-03 22:31:44 +00:00
|
|
|
DBusError error;
|
|
|
|
|
|
|
|
DBusMessage * dbus_reply = nullptr;
|
|
|
|
DBusMessage * dbus_msg = nullptr;
|
|
|
|
|
|
|
|
// dbus-send --print-reply --session --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'Metadata'
|
2020-04-13 00:02:52 +00:00
|
|
|
if (nullptr == (dbus_msg = dbus.message_new_method_call(dest, "/org/mpris/MediaPlayer2", "org.freedesktop.DBus.Properties", "Get"))) {
|
2020-05-22 12:00:35 +00:00
|
|
|
std::cerr << "MANGOHUD: unable to allocate memory for dbus message" << std::endl;
|
|
|
|
return false;
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
|
2020-05-22 12:00:35 +00:00
|
|
|
static const char *v_STRINGS[] = {
|
2020-02-03 22:31:44 +00:00
|
|
|
"org.mpris.MediaPlayer2.Player",
|
|
|
|
};
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
if (!dbus.message_append_args (dbus_msg, DBUS_TYPE_STRING, &v_STRINGS[0], DBUS_TYPE_STRING, &prop, DBUS_TYPE_INVALID)) {
|
2020-05-22 12:00:35 +00:00
|
|
|
std::cerr << "MANGOHUD: dbus_message_append_args failed" << std::endl;
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_unref(dbus_msg);
|
2020-05-22 12:00:35 +00:00
|
|
|
return false;
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
|
2020-05-28 17:52:32 +00:00
|
|
|
dbus.error_init(&error);
|
|
|
|
if (nullptr == (dbus_reply = dbus.connection_send_with_reply_and_block(dbus_mgr.get_conn(), dbus_msg, DBUS_TIMEOUT, &error))) {
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_unref(dbus_msg);
|
2020-05-22 12:00:35 +00:00
|
|
|
std::cerr << "MANGOHUD: " << error.message << std::endl;
|
|
|
|
dbus.error_free(&error);
|
|
|
|
return false;
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string entry;
|
2020-04-04 20:47:48 +00:00
|
|
|
if (get_dict_string_array(dbus, dbus_reply, entries)) {
|
2020-02-03 22:31:44 +00:00
|
|
|
// nothing
|
2020-04-04 20:47:48 +00:00
|
|
|
} else if (get_variant_string(dbus, dbus_reply, entry)) {
|
2020-02-03 22:31:44 +00:00
|
|
|
entries.push_back({prop, entry});
|
|
|
|
}
|
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
dbus.message_unref(dbus_msg);
|
|
|
|
dbus.message_unref(dbus_reply);
|
|
|
|
dbus.error_free(&error);
|
2020-05-22 12:00:35 +00:00
|
|
|
return true;
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
|
2020-06-30 00:03:28 +00:00
|
|
|
namespace dbusmgr {
|
|
|
|
bool dbus_manager::get_media_player_metadata(metadata& meta, std::string name) {
|
|
|
|
if(name == "") name = m_active_player;
|
|
|
|
if(name == "") return false;
|
2020-02-03 22:31:44 +00:00
|
|
|
meta.artists.clear();
|
2020-04-13 00:02:52 +00:00
|
|
|
string_pair_vec_map entries;
|
2020-06-30 00:03:28 +00:00
|
|
|
if(!dbus_get_player_property(*this, entries["Metadata"], name.c_str(), "Metadata")){
|
2020-05-22 12:00:35 +00:00
|
|
|
return false;
|
2020-06-30 00:03:28 +00:00
|
|
|
}
|
|
|
|
dbus_get_player_property(*this, entries["PlaybackStatus"], name.c_str(), "PlaybackStatus");
|
2020-02-03 22:31:44 +00:00
|
|
|
assign_metadata(meta, entries);
|
2020-05-22 12:00:35 +00:00
|
|
|
return true;
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
|
2020-06-30 00:03:28 +00:00
|
|
|
bool dbus_manager::init(const std::string& requested_player)
|
2020-02-03 22:31:44 +00:00
|
|
|
{
|
2020-04-05 10:48:16 +00:00
|
|
|
if (m_inited)
|
2020-05-22 12:00:35 +00:00
|
|
|
return true;
|
2020-06-30 00:03:28 +00:00
|
|
|
|
|
|
|
m_requested_player = "org.mpris.MediaPlayer2." + requested_player;
|
2020-04-05 10:48:16 +00:00
|
|
|
|
2020-05-22 12:00:35 +00:00
|
|
|
if (!m_dbus_ldr.IsLoaded() && !m_dbus_ldr.Load("libdbus-1.so.3")) {
|
|
|
|
std::cerr << "MANGOHUD: Could not load libdbus-1.so.3\n";
|
|
|
|
return false;
|
|
|
|
}
|
2020-04-04 20:47:48 +00:00
|
|
|
|
|
|
|
m_dbus_ldr.error_init(&m_error);
|
2020-02-03 22:31:44 +00:00
|
|
|
|
2020-04-04 20:47:48 +00:00
|
|
|
m_dbus_ldr.threads_init_default();
|
|
|
|
|
|
|
|
if ( nullptr == (m_dbus_conn = m_dbus_ldr.bus_get(DBUS_BUS_SESSION, &m_error)) ) {
|
2020-05-22 12:00:35 +00:00
|
|
|
std::cerr << "MANGOHUD: " << m_error.message << std::endl;
|
|
|
|
m_dbus_ldr.error_free(&m_error);
|
|
|
|
return false;
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
2020-05-22 12:00:35 +00:00
|
|
|
|
|
|
|
std::cout << "MANGOHUD: Connected to D-Bus as \"" << m_dbus_ldr.bus_get_unique_name(m_dbus_conn) << "\"." << std::endl;
|
2020-02-03 22:31:44 +00:00
|
|
|
|
2020-06-30 00:03:28 +00:00
|
|
|
dbus_list_name_to_owner();
|
2020-02-03 22:31:44 +00:00
|
|
|
connect_to_signals();
|
2020-06-30 00:03:28 +00:00
|
|
|
|
|
|
|
select_active_player();
|
|
|
|
|
2020-02-03 22:31:44 +00:00
|
|
|
m_inited = true;
|
2020-05-22 12:00:35 +00:00
|
|
|
return true;
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
|
2020-06-30 00:03:28 +00:00
|
|
|
bool dbus_manager::select_active_player() {
|
|
|
|
// If the requested player is available, use it
|
|
|
|
if(m_name_owners.count(m_requested_player) > 0) {
|
|
|
|
m_active_player = m_requested_player;
|
|
|
|
std::cerr << "Selecting requested player: " << m_requested_player << "\n";
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Else, use any player that is currently playing..
|
|
|
|
for(const auto& entry : m_name_owners) {
|
|
|
|
const auto& name = std::get<0>(entry);
|
|
|
|
metadata meta;
|
|
|
|
get_media_player_metadata(meta, name);
|
|
|
|
if(meta.playing) {
|
|
|
|
m_active_player = name;
|
|
|
|
std::cerr << "Selecting fallback player: " << name << "\n";
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// No media players are active
|
|
|
|
std::cerr << "No active players\n";
|
|
|
|
m_active_player = "";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-04-10 19:33:27 +00:00
|
|
|
void dbus_manager::deinit()
|
2020-02-03 22:31:44 +00:00
|
|
|
{
|
2020-04-10 19:33:27 +00:00
|
|
|
if (!m_inited)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// unreference system bus connection instead of closing it
|
|
|
|
if (m_dbus_conn) {
|
|
|
|
disconnect_from_signals();
|
|
|
|
m_dbus_ldr.connection_unref(m_dbus_conn);
|
|
|
|
m_dbus_conn = nullptr;
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
2020-04-10 19:33:27 +00:00
|
|
|
m_dbus_ldr.error_free(&m_error);
|
|
|
|
m_inited = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
dbus_manager::~dbus_manager()
|
|
|
|
{
|
|
|
|
deinit();
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void dbus_manager::connect_to_signals()
|
|
|
|
{
|
|
|
|
for (auto kv : m_signals) {
|
|
|
|
auto signal = format_signal(kv);
|
2020-04-04 20:47:48 +00:00
|
|
|
m_dbus_ldr.bus_add_match(m_dbus_conn, signal.c_str(), &m_error);
|
|
|
|
if (m_dbus_ldr.error_is_set(&m_error)) {
|
2020-02-03 22:31:44 +00:00
|
|
|
::perror(m_error.name);
|
|
|
|
::perror(m_error.message);
|
2020-04-04 20:47:48 +00:00
|
|
|
m_dbus_ldr.error_free(&m_error);
|
2020-02-03 22:31:44 +00:00
|
|
|
//return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
start_thread();
|
|
|
|
}
|
|
|
|
|
|
|
|
void dbus_manager::disconnect_from_signals()
|
|
|
|
{
|
|
|
|
for (auto kv : m_signals) {
|
|
|
|
auto signal = format_signal(kv);
|
2020-04-04 20:47:48 +00:00
|
|
|
m_dbus_ldr.bus_remove_match(m_dbus_conn, signal.c_str(), &m_error);
|
|
|
|
if (m_dbus_ldr.error_is_set(&m_error)) {
|
2020-02-03 22:31:44 +00:00
|
|
|
::perror(m_error.name);
|
|
|
|
::perror(m_error.message);
|
2020-04-04 20:47:48 +00:00
|
|
|
m_dbus_ldr.error_free(&m_error);
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
stop_thread();
|
|
|
|
}
|
|
|
|
|
|
|
|
void dbus_manager::add_callback(CBENUM type, callback_func func)
|
|
|
|
{
|
|
|
|
m_callbacks[type] = func;
|
|
|
|
}
|
|
|
|
|
2020-06-30 00:03:28 +00:00
|
|
|
bool dbus_manager::dbus_list_name_to_owner()
|
|
|
|
{
|
|
|
|
auto& dbus = dbus_mgr.dbus();
|
|
|
|
DBusError error;
|
|
|
|
|
|
|
|
std::vector<std::string> names;
|
|
|
|
std::string owner;
|
|
|
|
DBusMessageIter iter;
|
|
|
|
|
|
|
|
DBusMessage * dbus_reply = nullptr;
|
|
|
|
DBusMessage * dbus_msg = nullptr;
|
|
|
|
|
|
|
|
// dbus-send --session --dest=org.freedesktop.DBus --type=method_call --print-reply /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:"org.mpris.MediaPlayer2.spotify"
|
|
|
|
if (nullptr == (dbus_msg = dbus.message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames"))) {
|
|
|
|
std::cerr << "MANGOHUD: " << __func__ << ": unable to allocate memory for dbus message\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
dbus.error_init(&error);
|
|
|
|
if (nullptr == (dbus_reply = dbus.connection_send_with_reply_and_block(dbus_mgr.get_conn(), dbus_msg, DBUS_TIMEOUT, &error))) {
|
|
|
|
dbus.message_unref(dbus_msg);
|
|
|
|
std::cerr << "MANGOHUD: " << __func__ << ": "<< error.message << "\n";
|
|
|
|
dbus.error_free(&error);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
dbus.message_iter_init (dbus_reply, &iter);
|
|
|
|
|
|
|
|
if (!get_string_array(dbus, &iter, names))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for (auto& name : names) {
|
|
|
|
if (!starts_with(name, "org.mpris.MediaPlayer2."))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (dbus_get_name_owner(dbus_mgr, owner, name.c_str())) {
|
|
|
|
m_name_owners[name] = owner;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dbus.message_unref(dbus_msg);
|
|
|
|
dbus.message_unref(dbus_reply);
|
|
|
|
dbus.error_free(&error);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-02-03 22:31:44 +00:00
|
|
|
void dbus_manager::stop_thread()
|
|
|
|
{
|
|
|
|
m_quit = true;
|
|
|
|
if (m_thread.joinable())
|
|
|
|
m_thread.join();
|
|
|
|
}
|
|
|
|
|
|
|
|
void dbus_manager::start_thread()
|
|
|
|
{
|
|
|
|
stop_thread();
|
|
|
|
m_quit = false;
|
2020-06-30 00:03:28 +00:00
|
|
|
m_thread = std::thread(&dbus_manager::dbus_thread, this);
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
|
2020-06-30 00:03:28 +00:00
|
|
|
void dbus_manager::dbus_thread()
|
2020-02-03 22:31:44 +00:00
|
|
|
{
|
2020-04-04 20:47:48 +00:00
|
|
|
(void)parse_property_changed;
|
2020-02-03 22:31:44 +00:00
|
|
|
DBusMessage *msg = nullptr;
|
2020-05-11 19:01:40 +00:00
|
|
|
|
2020-02-03 22:31:44 +00:00
|
|
|
// loop listening for signals being emmitted
|
2020-06-30 00:03:28 +00:00
|
|
|
while (!m_quit) {
|
2020-02-03 22:31:44 +00:00
|
|
|
|
|
|
|
// non blocking read of the next available message
|
2020-06-30 00:03:28 +00:00
|
|
|
if (!m_dbus_ldr.connection_read_write(m_dbus_conn, 0))
|
2020-02-03 22:31:44 +00:00
|
|
|
return; // connection closed
|
|
|
|
|
2020-06-30 00:03:28 +00:00
|
|
|
msg = m_dbus_ldr.connection_pop_message(m_dbus_conn);
|
2020-02-03 22:31:44 +00:00
|
|
|
|
|
|
|
// loop again if we haven't read a message
|
|
|
|
if (nullptr == msg) {
|
2020-06-30 00:03:28 +00:00
|
|
|
std::this_thread::yield();
|
|
|
|
//std::this_thread::sleep_for(ms(10));
|
2020-02-03 22:31:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2020-06-30 00:03:28 +00:00
|
|
|
for (auto& sig : m_signals) {
|
|
|
|
if (m_dbus_ldr.message_is_signal(msg, sig.intf, sig.signal))
|
2020-02-03 22:31:44 +00:00
|
|
|
{
|
|
|
|
|
2020-06-30 00:03:28 +00:00
|
|
|
const char *sender = m_dbus_ldr.message_get_sender(msg);
|
2020-02-03 22:31:44 +00:00
|
|
|
#ifndef NDEBUG
|
2020-04-13 00:02:52 +00:00
|
|
|
std::cerr << __func__ << ": " << sig.intf << "::" << sig.signal << "\n";
|
|
|
|
std::cerr << "Sender: " << sender << "\n";
|
2020-02-03 22:31:44 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
switch (sig.type) {
|
|
|
|
case ST_PROPERTIESCHANGED:
|
|
|
|
{
|
|
|
|
std::string source;
|
2020-04-13 00:02:52 +00:00
|
|
|
string_pair_vec_map entries_map;
|
2020-02-03 22:31:44 +00:00
|
|
|
|
|
|
|
//parse_property_changed(msg, source, entries);
|
2020-06-30 00:03:28 +00:00
|
|
|
parse_mpris_properties(m_dbus_ldr, msg, source, entries_map);
|
2020-02-03 22:31:44 +00:00
|
|
|
#ifndef NDEBUG
|
2020-04-13 00:02:52 +00:00
|
|
|
std::cerr << "Source: " << source << "\n";
|
2020-02-03 22:31:44 +00:00
|
|
|
#endif
|
|
|
|
if (source != "org.mpris.MediaPlayer2.Player")
|
|
|
|
break;
|
2020-04-13 00:02:52 +00:00
|
|
|
|
2020-06-30 00:03:28 +00:00
|
|
|
if(m_active_player == "") {
|
|
|
|
select_active_player();
|
|
|
|
}
|
|
|
|
#ifndef NDEBUG
|
|
|
|
std::cerr << "active_player: " << m_active_player << "\n";
|
|
|
|
std::cerr << "active_player's owner: " << m_name_owners[m_active_player] << "\n";
|
|
|
|
std::cerr << "sender: " << sender << "\n";
|
|
|
|
#endif
|
|
|
|
if (m_name_owners[m_active_player] == sender) {
|
2020-05-11 19:01:40 +00:00
|
|
|
assign_metadata(main_metadata, entries_map);
|
2020-04-13 00:02:52 +00:00
|
|
|
}
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ST_NAMEOWNERCHANGED:
|
|
|
|
{
|
|
|
|
DBusMessageIter iter;
|
2020-06-30 00:03:28 +00:00
|
|
|
m_dbus_ldr.message_iter_init (msg, &iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
std::vector<std::string> str;
|
|
|
|
const char *value = nullptr;
|
|
|
|
|
2020-06-30 00:03:28 +00:00
|
|
|
while (m_dbus_ldr.message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING) {
|
|
|
|
m_dbus_ldr.message_iter_get_basic (&iter, &value);
|
2020-02-03 22:31:44 +00:00
|
|
|
str.push_back(value);
|
2020-06-30 00:03:28 +00:00
|
|
|
m_dbus_ldr.message_iter_next (&iter);
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
|
2020-04-13 00:02:52 +00:00
|
|
|
// register new name
|
2020-02-03 22:31:44 +00:00
|
|
|
if (str.size() == 3
|
2020-04-13 00:02:52 +00:00
|
|
|
&& starts_with(str[0], "org.mpris.MediaPlayer2.")
|
|
|
|
&& !str[2].empty()
|
2020-02-03 22:31:44 +00:00
|
|
|
)
|
|
|
|
{
|
2020-06-30 00:03:28 +00:00
|
|
|
m_name_owners[str[0]] = str[2];
|
|
|
|
if(str[0] == m_requested_player){
|
|
|
|
select_active_player();
|
|
|
|
get_media_player_metadata(main_metadata);
|
|
|
|
}
|
2020-04-13 00:02:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// did a player quit?
|
|
|
|
if (str[2].empty()) {
|
|
|
|
if (str.size() == 3
|
2020-06-30 00:03:28 +00:00
|
|
|
&& str[0] == m_active_player
|
2020-04-13 00:02:52 +00:00
|
|
|
) {
|
2020-05-28 17:52:32 +00:00
|
|
|
main_metadata.clear();
|
2020-06-30 00:03:28 +00:00
|
|
|
m_name_owners.erase(str[0]);
|
|
|
|
select_active_player();
|
|
|
|
get_media_player_metadata(main_metadata);
|
|
|
|
}
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
2020-04-13 00:02:52 +00:00
|
|
|
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// free the message
|
2020-06-30 00:03:28 +00:00
|
|
|
m_dbus_ldr.message_unref(msg);
|
2020-02-03 22:31:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dbus_manager dbus_mgr;
|
2020-05-10 12:11:56 +00:00
|
|
|
}
|