From a393c0582935d3eade7d9f3b5b64ab2c91ca5caf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Kr=C3=A4mer?= <24323470+larskraemer@users.noreply.github.com> Date: Fri, 3 Jul 2020 14:48:26 +0200 Subject: [PATCH] Fix auto-switching bug Debug output under ifdef NDEBUG --- src/dbus.cpp | 92 +++++++++++++++++++++++--------------------- src/dbus_helpers.hpp | 56 ++++++++++++++------------- 2 files changed, 77 insertions(+), 71 deletions(-) diff --git a/src/dbus.cpp b/src/dbus.cpp index 26d1ecaf..3937e48c 100644 --- a/src/dbus.cpp +++ b/src/dbus.cpp @@ -48,6 +48,25 @@ std::string format_signal(const dbusmgr::DBusSignal& s) { return ss.str(); } +void parse_song_data(DBusMessageIter_wrap iter, metadata& meta){ + iter.string_map_for_each([&meta](const std::string& key, + DBusMessageIter_wrap it) { + std::string val; + if (it.is_primitive()) { + val = it.get_stringified(); + } else if (it.is_array()) { + it.array_for_each_stringify([&](const std::string& str) { + if (val.empty()) { + val = str; + } else { + val += ", " + str; + } + }); + } + assign_metadata_value(meta, key, val); + }); +} + static void parse_mpris_properties(libdbus_loader& dbus, DBusMessage* msg, std::string& source, metadata& meta) { /** @@ -59,40 +78,16 @@ static void parse_mpris_properties(libdbus_loader& dbus, DBusMessage* msg, * } */ - std::string key, val; auto iter = DBusMessageIter_wrap(msg, &dbus); - - // Should be 'org.mpris.MediaPlayer2.Player' - if (not iter.is_string()) { - std::cerr << "Not a string\n"; // TODO - return; - } - source = iter.get_primitive(); - if (source != "org.mpris.MediaPlayer2.Player") return; iter.next(); if (not iter.is_array()) return; - iter.string_map_for_each([&](std::string& key, DBusMessageIter_wrap it) { + iter.string_map_for_each([&meta](std::string& key, DBusMessageIter_wrap it) { if (key == "Metadata") { - it.string_map_for_each([&](const std::string& key, - DBusMessageIter_wrap it) { - std::string val; - if (it.is_primitive()) { - val = it.get_stringified(); - } else if (it.is_array()) { - it.array_for_each_stringify([&](const std::string& str) { - if (val.empty()) { - val = str; - } else { - val += ", " + str; - } - }); - } - assign_metadata_value(meta, key, val); - }); + parse_song_data(it, meta); } else if (key == "PlaybackStatus") { auto val = it.get_stringified(); assign_metadata_value(meta, key, val); @@ -130,11 +125,9 @@ bool dbus_get_player_property(dbusmgr::dbus_manager& dbus_mgr, metadata& meta, if (not reply) return false; auto iter = reply.iter(); + if (iter.is_array()) { - iter.string_multimap_for_each_stringify( - [&](const std::string& key, const std::string& val) { - assign_metadata_value(meta, key, val); - }); + parse_song_data(iter, meta); } else if (iter.is_primitive()) { assign_metadata_value(meta, prop, iter.get_stringified()); } else { @@ -157,7 +150,7 @@ bool dbus_manager::get_media_player_metadata(metadata& meta, std::string name) { bool dbus_manager::init(const std::string& requested_player) { if (m_inited) return true; - if(not requested_player.empty()){ + if (not requested_player.empty()) { m_requested_player = "org.mpris.MediaPlayer2." + requested_player; } @@ -192,30 +185,37 @@ bool dbus_manager::init(const std::string& requested_player) { bool dbus_manager::select_active_player() { auto old_active_player = m_active_player; m_active_player = ""; - metadata meta{}; - if(not m_requested_player.empty()){ - std::cerr << "Requested player: " << m_requested_player << "\n"; + metadata meta {}; + if (not m_requested_player.empty()) { // If the requested player is available, use it if (m_name_owners.count(m_requested_player) > 0) { m_active_player = m_requested_player; +#ifndef NDEBUG std::cerr << "Selecting requested player: " << m_requested_player - << "\n"; + << "\n"; +#endif get_media_player_metadata(meta, m_active_player); } - } - else { + } else { // If no player is requested, use any player that is currently playing if (m_active_player.empty()) { - for (const auto& entry : m_name_owners) { - const auto& name = std::get<0>(entry); + auto it = std::find_if(m_name_owners.begin(), m_name_owners.end(), [this, &meta](auto& entry){ + auto& name = entry.first; get_media_player_metadata(meta, name); - if (meta.playing) { - m_active_player = name; - std::cerr << "Selecting fallback player: " << name << "\n"; + if(meta.playing) { + return true; } else { meta = {}; + return false; } + }); + + if(it != m_name_owners.end()){ + m_active_player = it->first; +#ifndef NDEBUG + std::cerr << "Selecting fallback player: " << m_active_player << "\n"; +#endif } } } @@ -226,7 +226,9 @@ bool dbus_manager::select_active_player() { } return true; } else { +#ifndef NDEBUG std::cerr << "No active players\n"; +#endif if (not old_active_player.empty()) { onNoPlayer(); } @@ -282,9 +284,11 @@ bool dbus_manager::handle_properties_changed(DBusMessage* msg, #endif if (source != "org.mpris.MediaPlayer2.Player") return false; - if (m_active_player == "") { + if (m_active_player == "" or + (m_requested_player.empty() and not main_metadata.meta.playing)) { select_active_player(); - } else if (m_name_owners[m_active_player] == sender) { + } + else if (m_name_owners[m_active_player] == sender) { onPlayerUpdate(meta); } return true; diff --git a/src/dbus_helpers.hpp b/src/dbus_helpers.hpp index e6422b8b..341f20a3 100644 --- a/src/dbus_helpers.hpp +++ b/src/dbus_helpers.hpp @@ -10,15 +10,16 @@ namespace DBus_helpers { namespace detail { // clang-format off template struct dbus_type_traits{}; -template<> struct dbus_type_traits { const int value = DBUS_TYPE_BYTE; const bool is_fixed = true; }; -template<> struct dbus_type_traits { const int value = DBUS_TYPE_UINT16; const bool is_fixed = true; }; -template<> struct dbus_type_traits { const int value = DBUS_TYPE_UINT32; const bool is_fixed = true; }; -template<> struct dbus_type_traits { const int value = DBUS_TYPE_UINT64; const bool is_fixed = true; }; -template<> struct dbus_type_traits { const int value = DBUS_TYPE_INT16; const bool is_fixed = true; }; -template<> struct dbus_type_traits { const int value = DBUS_TYPE_INT32; const bool is_fixed = true; }; -template<> struct dbus_type_traits { const int value = DBUS_TYPE_INT64; const bool is_fixed = true; }; -template<> struct dbus_type_traits { const int value = DBUS_TYPE_DOUBLE; const bool is_fixed = true; }; -template<> struct dbus_type_traits { const int value = DBUS_TYPE_STRING; const bool is_fixed = false; }; +template<> struct dbus_type_traits { const int value = DBUS_TYPE_BOOLEAN; const bool is_fixed = true; }; +template<> struct dbus_type_traits { const int value = DBUS_TYPE_BYTE; const bool is_fixed = true; }; +template<> struct dbus_type_traits { const int value = DBUS_TYPE_UINT16; const bool is_fixed = true; }; +template<> struct dbus_type_traits { const int value = DBUS_TYPE_UINT32; const bool is_fixed = true; }; +template<> struct dbus_type_traits { const int value = DBUS_TYPE_UINT64; const bool is_fixed = true; }; +template<> struct dbus_type_traits { const int value = DBUS_TYPE_INT16; const bool is_fixed = true; }; +template<> struct dbus_type_traits { const int value = DBUS_TYPE_INT32; const bool is_fixed = true; }; +template<> struct dbus_type_traits { const int value = DBUS_TYPE_INT64; const bool is_fixed = true; }; +template<> struct dbus_type_traits { const int value = DBUS_TYPE_DOUBLE; const bool is_fixed = true; }; +template<> struct dbus_type_traits { const int value = DBUS_TYPE_STRING; const bool is_fixed = false; }; // clang-format on template @@ -50,12 +51,11 @@ class DBusMessageIter_wrap { auto get_unsigned() -> uint64_t; auto get_signed() -> int64_t; auto get_stringified() -> std::string; - // Composites auto get_array_iter() -> DBusMessageIter_wrap; auto get_dict_entry_iter() -> DBusMessageIter_wrap; - // Looping + // Looping template void array_for_each(Callable); template @@ -68,14 +68,7 @@ class DBusMessageIter_wrap { template void string_multimap_for_each_stringify(Callable); - auto next() { - if (not *this) return *this; - m_DBus->message_iter_next(&m_Iter); - // Resolve any variants - m_resolved_iter = resolve_variants(); - m_type = m_DBus->message_iter_get_arg_type(&m_resolved_iter); - return *this; - } + auto next() -> DBusMessageIter_wrap&; private: DBusMessageIter resolve_variants() { @@ -144,7 +137,7 @@ auto DBusMessageIter_wrap::get_primitive() -> T { auto requested_type = detail::dbus_type_identifier; if (requested_type != type()) { std::cerr << "Type mismatch: '" << ((char)requested_type) << "' vs '" - << (char)type() << "'"; + << (char)type() << "'\n"; #ifndef NDEBUG exit(-1); #else @@ -262,13 +255,22 @@ void DBusMessageIter_wrap::string_map_for_each(T action) { template void DBusMessageIter_wrap::string_multimap_for_each_stringify(T action) { string_map_for_each([&action](const std::string& key, DBusMessageIter_wrap it) { - if (it.is_array()) { - it.array_for_each_stringify( - [&](const std::string& val) { action(key, val); }); - } else if (it.is_primitive()) { - action(key, it.get_stringified()); - } - }); + if (it.is_array()) { + it.array_for_each_stringify( + [&](const std::string& val) { action(key, val); }); + } else if (it.is_primitive()) { + action(key, it.get_stringified()); + } + }); +} + +auto DBusMessageIter_wrap::next() -> DBusMessageIter_wrap& { + if (not *this) return *this; + m_DBus->message_iter_next(&m_Iter); + // Resolve any variants + m_resolved_iter = resolve_variants(); + m_type = m_DBus->message_iter_get_arg_type(&m_resolved_iter); + return *this; }