diff --git a/docker/MQTTManager/CMakeLists.txt b/docker/MQTTManager/CMakeLists.txt index 6a78036b..8504f034 100644 --- a/docker/MQTTManager/CMakeLists.txt +++ b/docker/MQTTManager/CMakeLists.txt @@ -109,7 +109,7 @@ set_target_properties(MQTTManager_Thermostat PROPERTIES PUBLIC_HEADER ${CMAKE_IN target_include_directories(MQTTManager_Thermostat PUBLIC ${CMAKE_INCLUDE_SRC_DIRECTORY}) target_link_libraries(MQTTManager_Thermostat MQTTManager_HomeAssistantManager MQTTManager_OpenhabManager spdlog::spdlog nlohmann_json::nlohmann_json MQTT_Manager Boost::boost MQTTManager_Entity Protobuf_MQTTManager MQTTManager_CommandManager gtest::gtest) -add_library(MQTTManager_MediaPlayer STATIC ${CMAKE_INCLUDE_SRC_DIRECTORY}/media_player/media_player.cpp ${CMAKE_INCLUDE_SRC_DIRECTORY}/media_player/media_player.hpp ${CMAKE_INCLUDE_SRC_DIRECTORY}/media_player/home_assistant_media_player.hpp ${CMAKE_INCLUDE_SRC_DIRECTORY}/media_player/home_assistant_media_player.cpp ${CMAKE_INCLUDE_SRC_DIRECTORY}/media_player/home_assistant_source_volume.hpp ${CMAKE_INCLUDE_SRC_DIRECTORY}/media_player/home_assistant_source_volume.cpp) +add_library(MQTTManager_MediaPlayer STATIC ${CMAKE_INCLUDE_SRC_DIRECTORY}/media_player/media_player.cpp ${CMAKE_INCLUDE_SRC_DIRECTORY}/media_player/media_player.hpp ${CMAKE_INCLUDE_SRC_DIRECTORY}/media_player/home_assistant_media_player.hpp ${CMAKE_INCLUDE_SRC_DIRECTORY}/media_player/home_assistant_media_player.cpp ${CMAKE_INCLUDE_SRC_DIRECTORY}/media_player/home_assistant_source_volume.hpp ${CMAKE_INCLUDE_SRC_DIRECTORY}/media_player/home_assistant_source_volume.cpp ${CMAKE_INCLUDE_SRC_DIRECTORY}/media_player/home_assistant_source_player.hpp ${CMAKE_INCLUDE_SRC_DIRECTORY}/media_player/home_assistant_source_player.cpp) set_target_properties(MQTTManager_MediaPlayer PROPERTIES PUBLIC_HEADER ${CMAKE_INCLUDE_SRC_DIRECTORY}/media_player/media_player.hpp) target_include_directories(MQTTManager_MediaPlayer PUBLIC ${CMAKE_INCLUDE_SRC_DIRECTORY}) target_link_libraries(MQTTManager_MediaPlayer MQTTManager_HomeAssistantManager MQTTManager_WebHelper spdlog::spdlog nlohmann_json::nlohmann_json MQTT_Manager Boost::boost MQTTManager_Entity Protobuf_MQTTManager MQTTManager_CommandManager gtest::gtest) diff --git a/docker/MQTTManager/include/media_player/home_assistant_media_player.cpp b/docker/MQTTManager/include/media_player/home_assistant_media_player.cpp index b54947e4..d0fdd1a2 100644 --- a/docker/MQTTManager/include/media_player/home_assistant_media_player.cpp +++ b/docker/MQTTManager/include/media_player/home_assistant_media_player.cpp @@ -1,6 +1,7 @@ #include "home_assistant_media_player.hpp" #include "database_manager/database_manager.hpp" #include "entity/entity.hpp" +#include "media_player/home_assistant_source_player.hpp" #include "media_player/home_assistant_source_volume.hpp" #include "media_player/media_player.hpp" #include "protobuf_nspanel_entity.pb.h" @@ -67,7 +68,7 @@ void HomeAssistantMediaPlayer::reload_config() { this->_create_source_volume_strategy(entity_data.value_or(nlohmann::json::object())); // The name or source volume might have changed, unchanged states are not sent again. - this->_update_source_volume_and_send_state(); + this->_update_source_player_and_send_state(); if (home_assistant_name_changed && !this->_home_assistant_name.empty()) { // This will also request the current state from Home Assistant. @@ -113,7 +114,7 @@ void HomeAssistantMediaPlayer::_create_source_volume_strategy(const nlohmann::js } auto strategy = std::shared_ptr(HomeAssistantSourceVolumeStrategy::create(this->_id, entity_data, [this]() { - this->_update_source_volume_and_send_state(); + this->_update_source_player_and_send_state(); })); nlohmann::json player_attributes; @@ -132,11 +133,12 @@ std::shared_ptr HomeAssistantMediaPlayer::_ge return this->_source_volume_strategy; } -void HomeAssistantMediaPlayer::_update_source_volume_and_send_state() { +void HomeAssistantMediaPlayer::_update_source_player_and_send_state() { auto strategy = this->_get_source_volume_strategy(); std::optional source_volume = strategy ? strategy->get_source_volume() : std::nullopt; this->_has_source_volume = source_volume.has_value(); this->_source_volume = source_volume.value_or(0); + this->_set_source_player_sources(strategy ? strategy->get_source_player_sources() : std::nullopt); this->send_state_update_to_nspanel(); } @@ -169,6 +171,7 @@ void HomeAssistantMediaPlayer::home_assistant_event_callback(nlohmann::json data // Entity was removed from Home Assistant. this->_state = NSPanelEntityState_MediaPlayer_PlaybackState_UNKNOWN; this->_set_album_art_source(""); + this->_set_player_sources(MediaPlayerSources()); } else { std::string new_state = new_state_data.contains("state") && new_state_data["state"].is_string() ? new_state_data["state"].get() : ""; if (new_state.compare("playing") == 0) { @@ -213,6 +216,7 @@ void HomeAssistantMediaPlayer::home_assistant_event_callback(nlohmann::json data this->_can_previous_track = supported_features & HomeAssistantMediaPlayer::feature_previous_track; this->_can_set_volume = supported_features & HomeAssistantMediaPlayer::feature_volume_set; this->_can_mute = supported_features & HomeAssistantMediaPlayer::feature_volume_mute; + this->_set_player_sources(HomeAssistantSourcePlayer::sources_from_attributes(attributes)); } std::shared_ptr strategy; @@ -229,7 +233,7 @@ void HomeAssistantMediaPlayer::home_assistant_event_callback(nlohmann::json data return; } - this->_update_source_volume_and_send_state(); + this->_update_source_player_and_send_state(); if (previous_icon_color != this->get_icon_color()) { this->_signal_entity_changed(); } @@ -310,3 +314,14 @@ bool HomeAssistantMediaPlayer::_download_album_art(const std::string &source, st void HomeAssistantMediaPlayer::set_muted(bool muted) { this->_call_service("volume_mute", {{"is_volume_muted", muted}}); } + +void HomeAssistantMediaPlayer::select_player_source(const std::string &source) { + this->_call_service("select_source", {{"source", source}}); +} + +void HomeAssistantMediaPlayer::select_source_player_source(const std::string &source) { + auto strategy = this->_get_source_volume_strategy(); + if (strategy) { + strategy->select_source_player_source(source); + } +} diff --git a/docker/MQTTManager/include/media_player/home_assistant_media_player.hpp b/docker/MQTTManager/include/media_player/home_assistant_media_player.hpp index f5c8a1c7..0b0c3da7 100644 --- a/docker/MQTTManager/include/media_player/home_assistant_media_player.hpp +++ b/docker/MQTTManager/include/media_player/home_assistant_media_player.hpp @@ -23,6 +23,8 @@ class HomeAssistantMediaPlayer : public MediaPlayerEntity { void set_volume(uint8_t volume); void set_source_volume(uint8_t volume); void set_muted(bool muted); + void select_player_source(const std::string &source); + void select_source_player_source(const std::string &source); protected: /** @@ -50,9 +52,9 @@ class HomeAssistantMediaPlayer : public MediaPlayerEntity { std::shared_ptr _get_source_volume_strategy(); /** - * Update source volume from the strategy and send the new state to the NSPanel. + * Update source volume and source player sources from the strategy and send the new state to the NSPanel. */ - void _update_source_volume_and_send_state(); + void _update_source_player_and_send_state(); /** * Call a "media_player" domain service in Home Assistant. diff --git a/docker/MQTTManager/include/media_player/home_assistant_source_player.cpp b/docker/MQTTManager/include/media_player/home_assistant_source_player.cpp new file mode 100644 index 00000000..84c955b0 --- /dev/null +++ b/docker/MQTTManager/include/media_player/home_assistant_source_player.cpp @@ -0,0 +1,168 @@ +#include "media_player/home_assistant_source_player.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +HomeAssistantSourcePlayer::HomeAssistantSourcePlayer(std::string source_entity_attribute, std::function on_change) { + this->_source_entity_attribute = source_entity_attribute; + this->_on_change = on_change; +} + +HomeAssistantSourcePlayer::~HomeAssistantSourcePlayer() { + std::lock_guard lock_guard(this->_mutex); + if (!this->_entity_id.empty()) { + HomeAssistantManager::detach_event_observer(this->_entity_id, boost::bind(&HomeAssistantSourcePlayer::home_assistant_event_callback, this, _1)); + } +} + +void HomeAssistantSourcePlayer::update_from_player_attributes(const nlohmann::json &attributes) { + std::string new_entity_id; + if (attributes.contains(this->_source_entity_attribute) && attributes[this->_source_entity_attribute].is_string()) { + new_entity_id = attributes[this->_source_entity_attribute]; + } + + std::string old_entity_id; + { + std::lock_guard lock_guard(this->_mutex); + if (new_entity_id.compare(this->_entity_id) == 0) { + return; + } + old_entity_id = this->_entity_id; + this->_entity_id = new_entity_id; + // Forget the previous source player straight away, so its sources are never offered for the new one. + this->_volume.reset(); + this->_sources = MediaPlayerSources(); + } + + SPDLOG_DEBUG("Media player source changed from '{}' to '{}'.", old_entity_id, new_entity_id); + if (!old_entity_id.empty()) { + HomeAssistantManager::detach_event_observer(old_entity_id, boost::bind(&HomeAssistantSourcePlayer::home_assistant_event_callback, this, _1)); + } + if (!new_entity_id.empty()) { + // Attaching an observer requests all states from Home Assistant, the current state of the source player will arrive through the event callback. + HomeAssistantManager::attach_event_observer(new_entity_id, boost::bind(&HomeAssistantSourcePlayer::home_assistant_event_callback, this, _1)); + } +} + +std::string HomeAssistantSourcePlayer::get_entity_id() { + std::lock_guard lock_guard(this->_mutex); + return this->_entity_id; +} + +std::optional HomeAssistantSourcePlayer::get_volume() { + std::lock_guard lock_guard(this->_mutex); + return this->_volume; +} + +std::optional HomeAssistantSourcePlayer::get_sources() { + std::lock_guard lock_guard(this->_mutex); + if (this->_entity_id.empty()) { + return std::nullopt; + } + return this->_sources; +} + +void HomeAssistantSourcePlayer::set_volume(uint8_t volume) { + std::string entity_id = this->get_entity_id(); + if (entity_id.empty()) { + SPDLOG_WARN("Received command to set source volume but the media player does not report a source entity."); + return; + } + HomeAssistantSourcePlayer::call_service(entity_id, "volume_set", {{"volume_level", volume / 100.0}}); +} + +void HomeAssistantSourcePlayer::select_source(const std::string &source) { + std::string entity_id = this->get_entity_id(); + if (entity_id.empty()) { + SPDLOG_WARN("Received command to select a source player source but the media player does not report a source entity."); + return; + } + HomeAssistantSourcePlayer::call_service(entity_id, "select_source", {{"source", source}}); +} + +void HomeAssistantSourcePlayer::home_assistant_event_callback(nlohmann::json event_data) { + try { + if (!event_data.contains("event") || !event_data["event"].contains("data")) { + return; + } + nlohmann::json data = event_data["event"]["data"]; + if (!data.contains("entity_id") || !data["entity_id"].is_string()) { + return; + } + + bool changed = false; + { + std::lock_guard lock_guard(this->_mutex); + if (data["entity_id"].get().compare(this->_entity_id) != 0) { + return; // Event for a previous source. + } + + std::optional new_volume = this->_volume; + MediaPlayerSources new_sources; + if (!data.contains("new_state") || data["new_state"].is_null()) { + new_volume.reset(); + } else if (data["new_state"].contains("attributes") && data["new_state"]["attributes"].is_object()) { + const nlohmann::json &attributes = data["new_state"]["attributes"]; + // Home Assistant does not report volume while a media player is off, keep the last known value in that case. + if (attributes.contains("volume_level")) { + new_volume = HomeAssistantSourcePlayer::volume_from_json(attributes["volume_level"]); + } + new_sources = HomeAssistantSourcePlayer::sources_from_attributes(attributes); + } + + changed = new_volume != this->_volume || new_sources != this->_sources; + this->_volume = new_volume; + this->_sources = std::move(new_sources); + } + + if (changed && this->_on_change) { + this->_on_change(); + } + } catch (std::exception &e) { + SPDLOG_ERROR("Caught exception during processing of media player source event. Error: {}", e.what()); + } +} + +MediaPlayerSources HomeAssistantSourcePlayer::sources_from_attributes(const nlohmann::json &attributes) { + MediaPlayerSources sources; + if (attributes.contains("source_list") && attributes["source_list"].is_array()) { + for (const nlohmann::json &source : attributes["source_list"]) { + if (source.is_string()) { + sources.sources.push_back(source); + } + } + } + if (attributes.contains("source") && attributes["source"].is_string()) { + sources.current_source = attributes["source"]; + } + uint32_t supported_features = 0; + if (attributes.contains("supported_features") && attributes["supported_features"].is_number_unsigned()) { + supported_features = attributes["supported_features"]; + } + sources.can_select = (supported_features & HomeAssistantSourcePlayer::feature_select_source) && !sources.sources.empty(); + return sources; +} + +std::optional HomeAssistantSourcePlayer::volume_from_json(const nlohmann::json &volume_level) { + if (!volume_level.is_number()) { + return std::nullopt; + } + return std::lround(std::clamp(volume_level.get(), 0.0, 1.0) * 100); +} + +void HomeAssistantSourcePlayer::call_service(const std::string &entity_id, const std::string &service, nlohmann::json service_data) { + nlohmann::json command = { + {"type", "call_service"}, + {"domain", "media_player"}, + {"target", {{"entity_id", entity_id}}}, + {"service", service}}; + if (!service_data.empty()) { + command["service_data"] = service_data; + } + HomeAssistantManager::send_json(command); +} diff --git a/docker/MQTTManager/include/media_player/home_assistant_source_player.hpp b/docker/MQTTManager/include/media_player/home_assistant_source_player.hpp new file mode 100644 index 00000000..78e8d1c3 --- /dev/null +++ b/docker/MQTTManager/include/media_player/home_assistant_source_player.hpp @@ -0,0 +1,88 @@ +#ifndef MQTT_MANAGER_HOME_ASSISTANT_SOURCE_PLAYER_HPP +#define MQTT_MANAGER_HOME_ASSISTANT_SOURCE_PLAYER_HPP + +#include "media_player/media_player.hpp" +#include +#include +#include +#include +#include +#include + +/** + * Follows the source player feeding a media player in Home Assistant. The media player reports the + * entity ID of its current source player in a state attribute, the source player is itself a media + * player in Home Assistant. + */ +class HomeAssistantSourcePlayer { +public: + /** + * @param source_entity_attribute: Media player state attribute holding the entity ID of the source player. + * @param on_change: Called when the source player changes state without the media player itself changing. + */ + HomeAssistantSourcePlayer(std::string source_entity_attribute, std::function on_change); + ~HomeAssistantSourcePlayer(); + + /** + * Process new state attributes of the media player. Follows the source player when it changes. + */ + void update_from_player_attributes(const nlohmann::json &attributes); + + /** + * Get the entity ID of the current source player, or an empty string if there is none. + */ + std::string get_entity_id(); + + /** + * Get the volume of the source player in 0-100%, if known. + */ + std::optional get_volume(); + + /** + * Get the sources of the source player, or nothing if there is no source player. + */ + std::optional get_sources(); + + /** + * Set the volume of the source player. + * @param volume: Volume in 0-100% + */ + void set_volume(uint8_t volume); + + /** + * Select a source of the source player. + */ + void select_source(const std::string &source); + + void home_assistant_event_callback(nlohmann::json event_data); + + /** + * Read the sources of a media player from its Home Assistant state attributes. + */ + static MediaPlayerSources sources_from_attributes(const nlohmann::json &attributes); + + /** + * Convert a Home Assistant volume level (0.0-1.0) to 0-100%. + * Home Assistant always reports volume_level as 0.0-1.0, whatever the device uses. 0-100 is only used towards the NSPanel. + */ + static std::optional volume_from_json(const nlohmann::json &volume_level); + + /** + * Call a "media_player" domain service in Home Assistant on the given entity. + */ + static void call_service(const std::string &entity_id, const std::string &service, nlohmann::json service_data = nlohmann::json::object()); + + // Media player feature flag from Home Assistant (MediaPlayerEntityFeature). + static constexpr uint32_t feature_select_source = 2048; + +private: + std::string _source_entity_attribute; + std::function _on_change; + + std::mutex _mutex; + std::string _entity_id; + std::optional _volume; + MediaPlayerSources _sources; +}; + +#endif // !MQTT_MANAGER_HOME_ASSISTANT_SOURCE_PLAYER_HPP diff --git a/docker/MQTTManager/include/media_player/home_assistant_source_volume.cpp b/docker/MQTTManager/include/media_player/home_assistant_source_volume.cpp index 0de8c5de..083b479a 100644 --- a/docker/MQTTManager/include/media_player/home_assistant_source_volume.cpp +++ b/docker/MQTTManager/include/media_player/home_assistant_source_volume.cpp @@ -1,8 +1,5 @@ #include "media_player/home_assistant_source_volume.hpp" -#include -#include -#include -#include +#include "media_player/home_assistant_source_player.hpp" #include #include #include @@ -29,7 +26,7 @@ std::unique_ptr HomeAssistantSourceVolumeStra if (source_entity_attribute.empty() || source_volume_attribute.empty()) { SPDLOG_ERROR("Media player {}: source volume strategy 'player_attributes' requires both a source entity attribute and a source volume attribute. Source volume will not be available.", media_player_id); } else { - return std::make_unique(source_entity_attribute, source_volume_attribute); + return std::make_unique(source_entity_attribute, source_volume_attribute, on_change); } } else if (strategy.compare("source_entity") == 0) { if (source_entity_attribute.empty()) { @@ -43,23 +40,6 @@ std::unique_ptr HomeAssistantSourceVolumeStra return std::make_unique(); } -std::optional HomeAssistantSourceVolumeStrategy::_volume_from_json(const nlohmann::json &volume_level) { - if (!volume_level.is_number()) { - return std::nullopt; - } - return std::lround(std::clamp(volume_level.get(), 0.0, 1.0) * 100); -} - -void HomeAssistantSourceVolumeStrategy::_send_volume_set(const std::string &entity_id, uint8_t volume) { - nlohmann::json command = { - {"type", "call_service"}, - {"domain", "media_player"}, - {"target", {{"entity_id", entity_id}}}, - {"service", "volume_set"}, - {"service_data", {{"volume_level", volume / 100.0}}}}; - HomeAssistantManager::send_json(command); -} - // No source volume void NoSourceVolumeStrategy::update_from_player_attributes([[maybe_unused]] const nlohmann::json &attributes) { @@ -73,24 +53,28 @@ void NoSourceVolumeStrategy::set_source_volume([[maybe_unused]] uint8_t volume) SPDLOG_WARN("Received command to set source volume but no source volume strategy is configured."); } +std::optional NoSourceVolumeStrategy::get_source_player_sources() { + return std::nullopt; +} + +void NoSourceVolumeStrategy::select_source_player_source([[maybe_unused]] const std::string &source) { + SPDLOG_WARN("Received command to select a source player source but no source volume strategy is configured."); +} + // Player attributes -PlayerAttributesSourceVolumeStrategy::PlayerAttributesSourceVolumeStrategy(std::string source_entity_attribute, std::string source_volume_attribute) { - this->_source_entity_attribute = source_entity_attribute; +PlayerAttributesSourceVolumeStrategy::PlayerAttributesSourceVolumeStrategy(std::string source_entity_attribute, std::string source_volume_attribute, std::function on_change) : _source_player(source_entity_attribute, on_change) { this->_source_volume_attribute = source_volume_attribute; } void PlayerAttributesSourceVolumeStrategy::update_from_player_attributes(const nlohmann::json &attributes) { + this->_source_player.update_from_player_attributes(attributes); + std::lock_guard lock_guard(this->_mutex); - this->_source_entity_id.clear(); this->_source_volume.reset(); - - if (attributes.contains(this->_source_entity_attribute) && attributes[this->_source_entity_attribute].is_string()) { - this->_source_entity_id = attributes[this->_source_entity_attribute]; - } // Only report a source volume if we also know where to send volume changes. - if (!this->_source_entity_id.empty() && attributes.contains(this->_source_volume_attribute)) { - this->_source_volume = HomeAssistantSourceVolumeStrategy::_volume_from_json(attributes[this->_source_volume_attribute]); + if (!this->_source_player.get_entity_id().empty() && attributes.contains(this->_source_volume_attribute)) { + this->_source_volume = HomeAssistantSourcePlayer::volume_from_json(attributes[this->_source_volume_attribute]); } } @@ -100,110 +84,38 @@ std::optional PlayerAttributesSourceVolumeStrategy::get_source_volume() } void PlayerAttributesSourceVolumeStrategy::set_source_volume(uint8_t volume) { - std::string source_entity_id; - { - std::lock_guard lock_guard(this->_mutex); - source_entity_id = this->_source_entity_id; - } - if (source_entity_id.empty()) { - SPDLOG_WARN("Received command to set source volume but the media player does not report a source entity."); - return; - } - HomeAssistantSourceVolumeStrategy::_send_volume_set(source_entity_id, volume); + this->_source_player.set_volume(volume); } -// Source entity - -SourceEntitySourceVolumeStrategy::SourceEntitySourceVolumeStrategy(std::string source_entity_attribute, std::function on_change) { - this->_source_entity_attribute = source_entity_attribute; - this->_on_change = on_change; +std::optional PlayerAttributesSourceVolumeStrategy::get_source_player_sources() { + return this->_source_player.get_sources(); } -SourceEntitySourceVolumeStrategy::~SourceEntitySourceVolumeStrategy() { - std::lock_guard lock_guard(this->_mutex); - if (!this->_source_entity_id.empty()) { - HomeAssistantManager::detach_event_observer(this->_source_entity_id, boost::bind(&SourceEntitySourceVolumeStrategy::home_assistant_event_callback, this, _1)); - } +void PlayerAttributesSourceVolumeStrategy::select_source_player_source(const std::string &source) { + this->_source_player.select_source(source); } -void SourceEntitySourceVolumeStrategy::update_from_player_attributes(const nlohmann::json &attributes) { - std::string new_source_entity_id; - if (attributes.contains(this->_source_entity_attribute) && attributes[this->_source_entity_attribute].is_string()) { - new_source_entity_id = attributes[this->_source_entity_attribute]; - } +// Source entity - std::string old_source_entity_id; - { - std::lock_guard lock_guard(this->_mutex); - if (new_source_entity_id.compare(this->_source_entity_id) == 0) { - return; - } - old_source_entity_id = this->_source_entity_id; - this->_source_entity_id = new_source_entity_id; - this->_source_volume.reset(); - } +SourceEntitySourceVolumeStrategy::SourceEntitySourceVolumeStrategy(std::string source_entity_attribute, std::function on_change) : _source_player(source_entity_attribute, on_change) { +} - SPDLOG_DEBUG("Media player source changed from '{}' to '{}'.", old_source_entity_id, new_source_entity_id); - if (!old_source_entity_id.empty()) { - HomeAssistantManager::detach_event_observer(old_source_entity_id, boost::bind(&SourceEntitySourceVolumeStrategy::home_assistant_event_callback, this, _1)); - } - if (!new_source_entity_id.empty()) { - // Attaching an observer requests all states from Home Assistant, the current source volume will arrive through the event callback. - HomeAssistantManager::attach_event_observer(new_source_entity_id, boost::bind(&SourceEntitySourceVolumeStrategy::home_assistant_event_callback, this, _1)); - } +void SourceEntitySourceVolumeStrategy::update_from_player_attributes(const nlohmann::json &attributes) { + this->_source_player.update_from_player_attributes(attributes); } std::optional SourceEntitySourceVolumeStrategy::get_source_volume() { - std::lock_guard lock_guard(this->_mutex); - return this->_source_volume; + return this->_source_player.get_volume(); } void SourceEntitySourceVolumeStrategy::set_source_volume(uint8_t volume) { - std::string source_entity_id; - { - std::lock_guard lock_guard(this->_mutex); - source_entity_id = this->_source_entity_id; - } - if (source_entity_id.empty()) { - SPDLOG_WARN("Received command to set source volume but the media player does not report a source entity."); - return; - } - HomeAssistantSourceVolumeStrategy::_send_volume_set(source_entity_id, volume); + this->_source_player.set_volume(volume); } -void SourceEntitySourceVolumeStrategy::home_assistant_event_callback(nlohmann::json event_data) { - try { - if (!event_data.contains("event") || !event_data["event"].contains("data")) { - return; - } - nlohmann::json data = event_data["event"]["data"]; - if (!data.contains("entity_id") || !data["entity_id"].is_string()) { - return; - } - - bool changed = false; - { - std::lock_guard lock_guard(this->_mutex); - if (data["entity_id"].get().compare(this->_source_entity_id) != 0) { - return; // Event for a previous source. - } - - std::optional new_volume = this->_source_volume; - if (!data.contains("new_state") || data["new_state"].is_null()) { - new_volume.reset(); - } else if (data["new_state"].contains("attributes") && data["new_state"]["attributes"].contains("volume_level")) { - new_volume = HomeAssistantSourceVolumeStrategy::_volume_from_json(data["new_state"]["attributes"]["volume_level"]); - } - // Home Assistant does not report volume while a media player is off, keep the last known value in that case. - - changed = new_volume != this->_source_volume; - this->_source_volume = new_volume; - } +std::optional SourceEntitySourceVolumeStrategy::get_source_player_sources() { + return this->_source_player.get_sources(); +} - if (changed && this->_on_change) { - this->_on_change(); - } - } catch (std::exception &e) { - SPDLOG_ERROR("Caught exception during processing of media player source event. Error: {}", e.what()); - } +void SourceEntitySourceVolumeStrategy::select_source_player_source(const std::string &source) { + this->_source_player.select_source(source); } diff --git a/docker/MQTTManager/include/media_player/home_assistant_source_volume.hpp b/docker/MQTTManager/include/media_player/home_assistant_source_volume.hpp index 1c76a152..538c0235 100644 --- a/docker/MQTTManager/include/media_player/home_assistant_source_volume.hpp +++ b/docker/MQTTManager/include/media_player/home_assistant_source_volume.hpp @@ -1,6 +1,8 @@ #ifndef MQTT_MANAGER_HOME_ASSISTANT_SOURCE_VOLUME_HPP #define MQTT_MANAGER_HOME_ASSISTANT_SOURCE_VOLUME_HPP +#include "media_player/home_assistant_source_player.hpp" +#include "media_player/media_player.hpp" #include #include #include @@ -13,6 +15,7 @@ * Some setups (for example multi-room audio matrices) have a separate volume for the source * feeding a media player. How that source and its volume are exposed in Home Assistant differs * between integrations, a strategy selected per media player decides how to handle it. + * The strategy also gives access to the sources of the source player. */ class HomeAssistantSourceVolumeStrategy { public: @@ -35,24 +38,22 @@ class HomeAssistantSourceVolumeStrategy { virtual void set_source_volume(uint8_t volume) = 0; /** - * Create the strategy selected for the media player. - * @param media_player_id: ID of the media player, used for logging. - * @param entity_data: The media player's entity_data from the DB. - * @param on_change: Called when the source volume changes without the media player itself changing. + * Get the sources of the source player currently feeding the media player, or nothing if there is no source player. */ - static std::unique_ptr create(uint32_t media_player_id, const nlohmann::json &entity_data, std::function on_change); + virtual std::optional get_source_player_sources() = 0; -protected: /** - * Convert a Home Assistant volume level (0.0-1.0) to 0-100%. - * Home Assistant always reports volume_level as 0.0-1.0, whatever the device uses. 0-100 is only used towards the NSPanel. + * Select a source of the source player currently feeding the media player. */ - static std::optional _volume_from_json(const nlohmann::json &volume_level); + virtual void select_source_player_source(const std::string &source) = 0; /** - * Set the volume of the given Home Assistant media player. + * Create the strategy selected for the media player. + * @param media_player_id: ID of the media player, used for logging. + * @param entity_data: The media player's entity_data from the DB. + * @param on_change: Called when the source volume or sources change without the media player itself changing. */ - static void _send_volume_set(const std::string &entity_id, uint8_t volume); + static std::unique_ptr create(uint32_t media_player_id, const nlohmann::json &entity_data, std::function on_change); }; /** @@ -63,6 +64,8 @@ class NoSourceVolumeStrategy : public HomeAssistantSourceVolumeStrategy { void update_from_player_attributes(const nlohmann::json &attributes); std::optional get_source_volume(); void set_source_volume(uint8_t volume); + std::optional get_source_player_sources(); + void select_source_player_source(const std::string &source); }; /** @@ -71,17 +74,18 @@ class NoSourceVolumeStrategy : public HomeAssistantSourceVolumeStrategy { */ class PlayerAttributesSourceVolumeStrategy : public HomeAssistantSourceVolumeStrategy { public: - PlayerAttributesSourceVolumeStrategy(std::string source_entity_attribute, std::string source_volume_attribute); + PlayerAttributesSourceVolumeStrategy(std::string source_entity_attribute, std::string source_volume_attribute, std::function on_change); void update_from_player_attributes(const nlohmann::json &attributes); std::optional get_source_volume(); void set_source_volume(uint8_t volume); + std::optional get_source_player_sources(); + void select_source_player_source(const std::string &source); private: - std::string _source_entity_attribute; std::string _source_volume_attribute; + HomeAssistantSourcePlayer _source_player; std::mutex _mutex; - std::string _source_entity_id; std::optional _source_volume; }; @@ -92,19 +96,14 @@ class PlayerAttributesSourceVolumeStrategy : public HomeAssistantSourceVolumeStr class SourceEntitySourceVolumeStrategy : public HomeAssistantSourceVolumeStrategy { public: SourceEntitySourceVolumeStrategy(std::string source_entity_attribute, std::function on_change); - ~SourceEntitySourceVolumeStrategy(); void update_from_player_attributes(const nlohmann::json &attributes); std::optional get_source_volume(); void set_source_volume(uint8_t volume); - void home_assistant_event_callback(nlohmann::json event_data); + std::optional get_source_player_sources(); + void select_source_player_source(const std::string &source); private: - std::string _source_entity_attribute; - std::function _on_change; - - std::mutex _mutex; - std::string _source_entity_id; - std::optional _source_volume; + HomeAssistantSourcePlayer _source_player; }; #endif // !MQTT_MANAGER_HOME_ASSISTANT_SOURCE_VOLUME_HPP diff --git a/docker/MQTTManager/include/media_player/media_player.cpp b/docker/MQTTManager/include/media_player/media_player.cpp index 0f6a0510..315693b8 100644 --- a/docker/MQTTManager/include/media_player/media_player.cpp +++ b/docker/MQTTManager/include/media_player/media_player.cpp @@ -94,6 +94,13 @@ void MediaPlayerEntity::send_state_update_to_nspanel() { media_player_state->set_can_mute(this->_can_mute); media_player_state->set_album_art_url(this->_get_album_art_url()); media_player_state->set_volume_step(this->_volume_step); + { + std::lock_guard lock_guard(this->_sources_mutex); + MediaPlayerEntity::_fill_source_selection(media_player_state->mutable_player_sources(), this->_player_sources); + if (this->_source_player_sources.has_value()) { + MediaPlayerEntity::_fill_source_selection(media_player_state->mutable_source_player_sources(), this->_source_player_sources.value()); + } + } google::protobuf::util::MessageDifferencer differencer; if (!differencer.Compare(this->_last_media_player_state, state)) { @@ -128,7 +135,7 @@ void MediaPlayerEntity::command_callback(NSPanelMQTTManagerCommand &command) { this->previous_track(); break; case NSPanelMQTTManagerCommand_MediaPlayerCommand_PlaybackAction_NONE: - // The command only changes volume or mute. + // The command only changes volume, mute or source. break; default: SPDLOG_WARN("Received unknown playback action {} for media player {}::{}.", static_cast(media_player_command.playback_action()), this->_id, this->_name); @@ -146,6 +153,97 @@ void MediaPlayerEntity::command_callback(NSPanelMQTTManagerCommand &command) { if (media_player_command.has_muted()) { this->set_muted(media_player_command.muted()); } + + if (!media_player_command.select_player_source().empty()) { + std::optional source; + { + std::lock_guard lock_guard(this->_sources_mutex); + source = this->_find_source(this->_player_sources, media_player_command.select_player_source(), "source"); + } + if (source.has_value()) { + this->select_player_source(source.value()); + } + } + + if (!media_player_command.select_source_player_source().empty()) { + std::optional source; + { + std::lock_guard lock_guard(this->_sources_mutex); + source = this->_find_source(this->_source_player_sources, media_player_command.select_source_player_source(), "source player source"); + } + if (source.has_value()) { + this->select_source_player_source(source.value()); + } + } +} + +void MediaPlayerEntity::_set_player_sources(MediaPlayerSources sources) { + std::lock_guard lock_guard(this->_sources_mutex); + if (this->_player_sources != sources) { + this->_warn_if_sources_limited(sources, "sources"); + this->_player_sources = std::move(sources); + } +} + +void MediaPlayerEntity::_set_source_player_sources(std::optional sources) { + std::lock_guard lock_guard(this->_sources_mutex); + if (this->_source_player_sources != sources) { + if (sources.has_value()) { + this->_warn_if_sources_limited(sources.value(), "source player sources"); + } + this->_source_player_sources = std::move(sources); + } +} + +std::string MediaPlayerEntity::_limit_source_name(const std::string &name) { + if (name.size() <= MediaPlayerEntity::max_source_name_length) { + return name; + } + // Step back from the cut while it would land on a UTF-8 continuation byte (10xxxxxx). + size_t length = MediaPlayerEntity::max_source_name_length; + while (length > 0 && (static_cast(name[length]) & 0xC0) == 0x80) { + length--; + } + return name.substr(0, length); +} + +void MediaPlayerEntity::_fill_source_selection(NSPanelEntityState_MediaPlayer_SourceSelection *selection, const MediaPlayerSources &sources) { + for (size_t i = 0; i < sources.sources.size() && i < MediaPlayerEntity::max_sources; i++) { + selection->add_sources(MediaPlayerEntity::_limit_source_name(sources.sources[i])); + } + selection->set_current_source(MediaPlayerEntity::_limit_source_name(sources.current_source)); + selection->set_can_select(sources.can_select); +} + +std::optional MediaPlayerEntity::_find_source(const std::optional &sources, const std::string &name, std::string_view description) { + if (!sources.has_value()) { + SPDLOG_WARN("Received command to select {} '{}' for media player {}::{} but it has no source player.", description, name, this->_id, this->_name); + return std::nullopt; + } + if (!sources->can_select) { + SPDLOG_WARN("Received command to select {} '{}' for media player {}::{} but it can not select one.", description, name, this->_id, this->_name); + return std::nullopt; + } + // Only the sources sent to the NSPanel can be selected, compare with their names as sent. + for (size_t i = 0; i < sources->sources.size() && i < MediaPlayerEntity::max_sources; i++) { + if (MediaPlayerEntity::_limit_source_name(sources->sources[i]).compare(name) == 0) { + return sources->sources[i]; + } + } + SPDLOG_WARN("Received command to select {} '{}' for media player {}::{} but it is not one of its current sources.", description, name, this->_id, this->_name); + return std::nullopt; +} + +void MediaPlayerEntity::_warn_if_sources_limited(const MediaPlayerSources &sources, std::string_view description) { + if (sources.sources.size() > MediaPlayerEntity::max_sources) { + SPDLOG_WARN("Media player {}::{} has {} {}, only the first {} will be sent to the NSPanel.", this->_id, this->_name, sources.sources.size(), description, MediaPlayerEntity::max_sources); + } + for (size_t i = 0; i < sources.sources.size() && i < MediaPlayerEntity::max_sources; i++) { + if (sources.sources[i].size() > MediaPlayerEntity::max_source_name_length) { + SPDLOG_WARN("Media player {}::{} has {} with names longer than {} bytes, they will be shortened on the NSPanel.", this->_id, this->_name, description, MediaPlayerEntity::max_source_name_length); + break; + } + } } void MediaPlayerEntity::_set_album_art_source(const std::string &source) { diff --git a/docker/MQTTManager/include/media_player/media_player.hpp b/docker/MQTTManager/include/media_player/media_player.hpp index 451ce7a6..d278857d 100644 --- a/docker/MQTTManager/include/media_player/media_player.hpp +++ b/docker/MQTTManager/include/media_player/media_player.hpp @@ -10,6 +10,18 @@ #include #include #include +#include + +/** + * Sources a media player (or the source player feeding it) can select, as reported by the controller. + */ +struct MediaPlayerSources { + std::vector sources; + std::string current_source; // Empty if unknown. + bool can_select = false; + + bool operator==(const MediaPlayerSources &other) const = default; +}; class MediaPlayerEntity : public MqttManagerEntity { public: @@ -77,6 +89,23 @@ class MediaPlayerEntity : public MqttManagerEntity { */ virtual void set_muted(bool muted) = 0; + /** + * Select a source (input) of the media player. + * @param source: Name of the source as reported by the controller. + */ + virtual void select_player_source(const std::string &source) = 0; + + /** + * Select a source of the source player currently feeding the media player. + * @param source: Name of the source as reported by the controller. + */ + virtual void select_source_player_source(const std::string &source) = 0; + + // Limits on the source lists sent to the NSPanel, which can only receive 4 KB in one MQTT message. + // The NSPanel pages through longer lists than it can show at once. + static constexpr size_t max_sources = 32; + static constexpr size_t max_source_name_length = 64; // In bytes + /** * Get the current album art as the original image data (for example a JPEG) from the controller. * The image is downloaded on first request and cached until the album art changes. The same pointer is @@ -114,6 +143,17 @@ class MediaPlayerEntity : public MqttManagerEntity { */ virtual bool _download_album_art(const std::string &source, std::string &image_data) = 0; + /** + * Set the sources of the media player. They are sent with the next state update. + */ + void _set_player_sources(MediaPlayerSources sources); + + /** + * Set the sources of the source player feeding the media player, or nothing if there is no source player. + * They are sent with the next state update. + */ + void _set_source_player_sources(std::optional sources); + uint32_t _id; std::string _name; uint16_t _room_id; @@ -145,6 +185,32 @@ class MediaPlayerEntity : public MqttManagerEntity { */ std::string _get_album_art_url(); + /** + * Shorten a source name to what is sent to the NSPanel, without splitting a UTF-8 character. + */ + static std::string _limit_source_name(const std::string &name); + + /** + * Fill in a source list for the NSPanel, limited to max_sources entries of max_source_name_length bytes. + */ + static void _fill_source_selection(NSPanelEntityState_MediaPlayer_SourceSelection *selection, const MediaPlayerSources &sources); + + /** + * Find the source a name sent by the NSPanel refers to. The NSPanel only knows the limited names. + * @return The source as reported by the controller, or nothing if the source can not be selected. + */ + std::optional _find_source(const std::optional &sources, const std::string &name, std::string_view description); + + /** + * Log a warning if sources will be cut short when sent to the NSPanel. + */ + void _warn_if_sources_limited(const MediaPlayerSources &sources, std::string_view description); + + // Guards the source lists. They are updated by the controller and read when the NSPanel selects a source. + std::mutex _sources_mutex; + MediaPlayerSources _player_sources; + std::optional _source_player_sources; + // Guards _album_art_source. Only held briefly, never while downloading. std::mutex _album_art_source_mutex; std::string _album_art_source; diff --git a/docker/MQTTManager/include/protobuf/protobuf_nspanel.pb.cc b/docker/MQTTManager/include/protobuf/protobuf_nspanel.pb.cc index 7ffd0ad4..059123fe 100644 --- a/docker/MQTTManager/include/protobuf/protobuf_nspanel.pb.cc +++ b/docker/MQTTManager/include/protobuf/protobuf_nspanel.pb.cc @@ -233,7 +233,13 @@ PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT inline constexpr NSPanelMQTTManagerCommand_MediaPlayerCommand::Impl_::Impl_( ::_pbi::ConstantInitialized) noexcept - : media_player_id_{0}, + : select_player_source_( + &::google::protobuf::internal::fixed_address_empty_string, + ::_pbi::ConstantInitialized()), + select_source_player_source_( + &::google::protobuf::internal::fixed_address_empty_string, + ::_pbi::ConstantInitialized()), + media_player_id_{0}, playback_action_{static_cast< ::NSPanelMQTTManagerCommand_MediaPlayerCommand_PlaybackAction >(0)}, volume_{0}, has_volume_{false}, @@ -841,6 +847,8 @@ const ::uint32_t PROTOBUF_FIELD_OFFSET(::NSPanelMQTTManagerCommand_MediaPlayerCommand, _impl_.source_volume_), PROTOBUF_FIELD_OFFSET(::NSPanelMQTTManagerCommand_MediaPlayerCommand, _impl_.has_muted_), PROTOBUF_FIELD_OFFSET(::NSPanelMQTTManagerCommand_MediaPlayerCommand, _impl_.muted_), + PROTOBUF_FIELD_OFFSET(::NSPanelMQTTManagerCommand_MediaPlayerCommand, _impl_.select_player_source_), + PROTOBUF_FIELD_OFFSET(::NSPanelMQTTManagerCommand_MediaPlayerCommand, _impl_.select_source_player_source_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(::NSPanelMQTTManagerCommand, _internal_metadata_), ~0u, // no _extensions_ @@ -882,7 +890,7 @@ static const ::_pbi::MigrationSchema {238, -1, -1, sizeof(::NSPanelMQTTManagerCommand_ThermostatTemperatureCommand)}, {248, -1, -1, sizeof(::NSPanelMQTTManagerCommand_ThermostatCommand)}, {259, -1, -1, sizeof(::NSPanelMQTTManagerCommand_MediaPlayerCommand)}, - {275, -1, -1, sizeof(::NSPanelMQTTManagerCommand)}, + {277, -1, -1, sizeof(::NSPanelMQTTManagerCommand)}, }; static const ::_pb::Message* const file_default_instances[] = { &::_NSPanelConfig_RoomInfo_default_instance_._instance, @@ -998,7 +1006,7 @@ const char descriptor_table_protodef_protobuf_5fnspanel_2eproto[] ABSL_ATTRIBUTE "ing\030\010 \001(\t\032\222\001\n\014ForecastItem\022\024\n\014weather_ic" "on\030\001 \001(\t\022\034\n\024precipitation_string\030\002 \001(\t\022!" "\n\031temperature_maxmin_string\030\003 \001(\t\022\023\n\013win" - "d_string\030\004 \001(\t\022\026\n\016display_string\030\005 \001(\t\"\272" + "d_string\030\004 \001(\t\022\026\n\016display_string\030\005 \001(\t\"\375" "\020\n\031NSPanelMQTTManagerCommand\022M\n\022first_pa" "ge_turn_on\030\001 \001(\0132/.NSPanelMQTTManagerCom" "mand.FirstPageTurnLightOnH\000\022O\n\023first_pag" @@ -1041,26 +1049,27 @@ const char descriptor_table_protodef_protobuf_5fnspanel_2eproto[] ABSL_ATTRIBUTE "\025\n\rthermostat_id\030\001 \001(\005\022\023\n\013temperature\030\002 " "\001(\002\032M\n\021ThermostatCommand\022\025\n\rthermostat_i" "d\030\001 \001(\005\022\016\n\006option\030\002 \001(\t\022\021\n\tnew_value\030\003 \001" - "(\t\032\321\002\n\022MediaPlayerCommand\022\027\n\017media_playe" + "(\t\032\224\003\n\022MediaPlayerCommand\022\027\n\017media_playe" "r_id\030\001 \001(\005\022U\n\017playback_action\030\002 \001(\0162<.NS" "PanelMQTTManagerCommand.MediaPlayerComma" "nd.PlaybackAction\022\022\n\nhas_volume\030\003 \001(\010\022\016\n" "\006volume\030\004 \001(\005\022\031\n\021has_source_volume\030\005 \001(\010" "\022\025\n\rsource_volume\030\006 \001(\005\022\021\n\thas_muted\030\007 \001" - "(\010\022\r\n\005muted\030\010 \001(\010\"S\n\016PlaybackAction\022\010\n\004N" - "ONE\020\000\022\010\n\004PLAY\020\001\022\t\n\005PAUSE\020\002\022\016\n\nNEXT_TRACK" - "\020\003\022\022\n\016PREVIOUS_TRACK\020\004\"D\n\023AffectLightsOp" - "tions\022\007\n\003ALL\020\000\022\020\n\014TABLE_LIGHTS\020\001\022\022\n\016CEIL" - "ING_LIGHTS\020\002B\r\n\013CommandData*[\n\023NSPanelWa" - "rningLevel\022\014\n\010CRITICAL\020\000\022\t\n\005ERROR\020\001\022\013\n\007W" - "ARNING\020\002\022\010\n\004INFO\020\003\022\t\n\005DEBUG\020\004\022\t\n\005TRACE\020\005" - "b\006proto3" + "(\010\022\r\n\005muted\030\010 \001(\010\022\034\n\024select_player_sourc" + "e\030\t \001(\t\022#\n\033select_source_player_source\030\n" + " \001(\t\"S\n\016PlaybackAction\022\010\n\004NONE\020\000\022\010\n\004PLAY" + "\020\001\022\t\n\005PAUSE\020\002\022\016\n\nNEXT_TRACK\020\003\022\022\n\016PREVIOU" + "S_TRACK\020\004\"D\n\023AffectLightsOptions\022\007\n\003ALL\020" + "\000\022\020\n\014TABLE_LIGHTS\020\001\022\022\n\016CEILING_LIGHTS\020\002B" + "\r\n\013CommandData*[\n\023NSPanelWarningLevel\022\014\n" + "\010CRITICAL\020\000\022\t\n\005ERROR\020\001\022\013\n\007WARNING\020\002\022\010\n\004I" + "NFO\020\003\022\t\n\005DEBUG\020\004\022\t\n\005TRACE\020\005b\006proto3" }; static ::absl::once_flag descriptor_table_protobuf_5fnspanel_2eproto_once; PROTOBUF_CONSTINIT const ::_pbi::DescriptorTable descriptor_table_protobuf_5fnspanel_2eproto = { false, false, - 5888, + 5955, descriptor_table_protodef_protobuf_5fnspanel_2eproto, "protobuf_nspanel.proto", &descriptor_table_protobuf_5fnspanel_2eproto_once, @@ -7213,15 +7222,38 @@ NSPanelMQTTManagerCommand_MediaPlayerCommand::NSPanelMQTTManagerCommand_MediaPla SharedCtor(arena); // @@protoc_insertion_point(arena_constructor:NSPanelMQTTManagerCommand.MediaPlayerCommand) } +inline PROTOBUF_NDEBUG_INLINE NSPanelMQTTManagerCommand_MediaPlayerCommand::Impl_::Impl_( + ::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena, + const Impl_& from, const ::NSPanelMQTTManagerCommand_MediaPlayerCommand& from_msg) + : select_player_source_(arena, from.select_player_source_), + select_source_player_source_(arena, from.select_source_player_source_), + _cached_size_{0} {} + NSPanelMQTTManagerCommand_MediaPlayerCommand::NSPanelMQTTManagerCommand_MediaPlayerCommand( - ::google::protobuf::Arena* arena, const NSPanelMQTTManagerCommand_MediaPlayerCommand& from) - : NSPanelMQTTManagerCommand_MediaPlayerCommand(arena) { - MergeFrom(from); + ::google::protobuf::Arena* arena, + const NSPanelMQTTManagerCommand_MediaPlayerCommand& from) + : ::google::protobuf::Message(arena) { + NSPanelMQTTManagerCommand_MediaPlayerCommand* const _this = this; + (void)_this; + _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>( + from._internal_metadata_); + new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from); + ::memcpy(reinterpret_cast(&_impl_) + + offsetof(Impl_, media_player_id_), + reinterpret_cast(&from._impl_) + + offsetof(Impl_, media_player_id_), + offsetof(Impl_, source_volume_) - + offsetof(Impl_, media_player_id_) + + sizeof(Impl_::source_volume_)); + + // @@protoc_insertion_point(copy_constructor:NSPanelMQTTManagerCommand.MediaPlayerCommand) } inline PROTOBUF_NDEBUG_INLINE NSPanelMQTTManagerCommand_MediaPlayerCommand::Impl_::Impl_( ::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena) - : _cached_size_{0} {} + : select_player_source_(arena), + select_source_player_source_(arena), + _cached_size_{0} {} inline void NSPanelMQTTManagerCommand_MediaPlayerCommand::SharedCtor(::_pb::Arena* arena) { new (&_impl_) Impl_(internal_visibility(), arena); @@ -7239,6 +7271,8 @@ NSPanelMQTTManagerCommand_MediaPlayerCommand::~NSPanelMQTTManagerCommand_MediaPl } inline void NSPanelMQTTManagerCommand_MediaPlayerCommand::SharedDtor() { ABSL_DCHECK(GetArena() == nullptr); + _impl_.select_player_source_.Destroy(); + _impl_.select_source_player_source_.Destroy(); _impl_.~Impl_(); } @@ -7263,15 +7297,15 @@ NSPanelMQTTManagerCommand_MediaPlayerCommand::GetClassData() const { return _data_.base(); } PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 -const ::_pbi::TcParseTable<3, 8, 0, 0, 2> NSPanelMQTTManagerCommand_MediaPlayerCommand::_table_ = { +const ::_pbi::TcParseTable<4, 10, 0, 108, 2> NSPanelMQTTManagerCommand_MediaPlayerCommand::_table_ = { { 0, // no _has_bits_ 0, // no _extensions_ - 8, 56, // max_field_number, fast_idx_mask + 10, 120, // max_field_number, fast_idx_mask offsetof(decltype(_table_), field_lookup_table), - 4294967040, // skipmap + 4294966272, // skipmap offsetof(decltype(_table_), field_entries), - 8, // num_field_entries + 10, // num_field_entries 0, // num_aux_entries offsetof(decltype(_table_), field_names), // no aux_entries &_NSPanelMQTTManagerCommand_MediaPlayerCommand_default_instance_._instance, @@ -7281,9 +7315,7 @@ const ::_pbi::TcParseTable<3, 8, 0, 0, 2> NSPanelMQTTManagerCommand_MediaPlayerC ::_pbi::TcParser::GetTable<::NSPanelMQTTManagerCommand_MediaPlayerCommand>(), // to_prefetch #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ - // bool muted = 8; - {::_pbi::TcParser::SingularVarintNoZag1(), - {64, 63, 0, PROTOBUF_FIELD_OFFSET(NSPanelMQTTManagerCommand_MediaPlayerCommand, _impl_.muted_)}}, + {::_pbi::TcParser::MiniParse, {}}, // int32 media_player_id = 1; {::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(NSPanelMQTTManagerCommand_MediaPlayerCommand, _impl_.media_player_id_), 63>(), {8, 63, 0, PROTOBUF_FIELD_OFFSET(NSPanelMQTTManagerCommand_MediaPlayerCommand, _impl_.media_player_id_)}}, @@ -7305,6 +7337,20 @@ const ::_pbi::TcParseTable<3, 8, 0, 0, 2> NSPanelMQTTManagerCommand_MediaPlayerC // bool has_muted = 7; {::_pbi::TcParser::SingularVarintNoZag1(), {56, 63, 0, PROTOBUF_FIELD_OFFSET(NSPanelMQTTManagerCommand_MediaPlayerCommand, _impl_.has_muted_)}}, + // bool muted = 8; + {::_pbi::TcParser::SingularVarintNoZag1(), + {64, 63, 0, PROTOBUF_FIELD_OFFSET(NSPanelMQTTManagerCommand_MediaPlayerCommand, _impl_.muted_)}}, + // string select_player_source = 9; + {::_pbi::TcParser::FastUS1, + {74, 63, 0, PROTOBUF_FIELD_OFFSET(NSPanelMQTTManagerCommand_MediaPlayerCommand, _impl_.select_player_source_)}}, + // string select_source_player_source = 10; + {::_pbi::TcParser::FastUS1, + {82, 63, 0, PROTOBUF_FIELD_OFFSET(NSPanelMQTTManagerCommand_MediaPlayerCommand, _impl_.select_source_player_source_)}}, + {::_pbi::TcParser::MiniParse, {}}, + {::_pbi::TcParser::MiniParse, {}}, + {::_pbi::TcParser::MiniParse, {}}, + {::_pbi::TcParser::MiniParse, {}}, + {::_pbi::TcParser::MiniParse, {}}, }}, {{ 65535, 65535 }}, {{ @@ -7332,9 +7378,19 @@ const ::_pbi::TcParseTable<3, 8, 0, 0, 2> NSPanelMQTTManagerCommand_MediaPlayerC // bool muted = 8; {PROTOBUF_FIELD_OFFSET(NSPanelMQTTManagerCommand_MediaPlayerCommand, _impl_.muted_), 0, 0, (0 | ::_fl::kFcSingular | ::_fl::kBool)}, + // string select_player_source = 9; + {PROTOBUF_FIELD_OFFSET(NSPanelMQTTManagerCommand_MediaPlayerCommand, _impl_.select_player_source_), 0, 0, + (0 | ::_fl::kFcSingular | ::_fl::kUtf8String | ::_fl::kRepAString)}, + // string select_source_player_source = 10; + {PROTOBUF_FIELD_OFFSET(NSPanelMQTTManagerCommand_MediaPlayerCommand, _impl_.select_source_player_source_), 0, 0, + (0 | ::_fl::kFcSingular | ::_fl::kUtf8String | ::_fl::kRepAString)}, }}, // no aux_entries {{ + "\54\0\0\0\0\0\0\0\0\24\33\0\0\0\0\0" + "NSPanelMQTTManagerCommand.MediaPlayerCommand" + "select_player_source" + "select_source_player_source" }}, }; @@ -7345,6 +7401,8 @@ PROTOBUF_NOINLINE void NSPanelMQTTManagerCommand_MediaPlayerCommand::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; + _impl_.select_player_source_.ClearToEmpty(); + _impl_.select_source_player_source_.ClearToEmpty(); ::memset(&_impl_.media_player_id_, 0, static_cast<::size_t>( reinterpret_cast(&_impl_.source_volume_) - reinterpret_cast(&_impl_.media_player_id_)) + sizeof(_impl_.source_volume_)); @@ -7414,6 +7472,22 @@ ::uint8_t* NSPanelMQTTManagerCommand_MediaPlayerCommand::_InternalSerialize( 8, this->_internal_muted(), target); } + // string select_player_source = 9; + if (!this->_internal_select_player_source().empty()) { + const std::string& _s = this->_internal_select_player_source(); + ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + _s.data(), static_cast(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "NSPanelMQTTManagerCommand.MediaPlayerCommand.select_player_source"); + target = stream->WriteStringMaybeAliased(9, _s, target); + } + + // string select_source_player_source = 10; + if (!this->_internal_select_source_player_source().empty()) { + const std::string& _s = this->_internal_select_source_player_source(); + ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + _s.data(), static_cast(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "NSPanelMQTTManagerCommand.MediaPlayerCommand.select_source_player_source"); + target = stream->WriteStringMaybeAliased(10, _s, target); + } + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( @@ -7432,6 +7506,18 @@ ::size_t NSPanelMQTTManagerCommand_MediaPlayerCommand::ByteSizeLong() const { (void) cached_has_bits; ::_pbi::Prefetch5LinesFrom7Lines(reinterpret_cast(this)); + // string select_player_source = 9; + if (!this->_internal_select_player_source().empty()) { + total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize( + this->_internal_select_player_source()); + } + + // string select_source_player_source = 10; + if (!this->_internal_select_source_player_source().empty()) { + total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize( + this->_internal_select_source_player_source()); + } + // int32 media_player_id = 1; if (this->_internal_media_player_id() != 0) { total_size += ::_pbi::WireFormatLite::Int32SizePlusOne( @@ -7488,6 +7574,12 @@ void NSPanelMQTTManagerCommand_MediaPlayerCommand::MergeImpl(::google::protobuf: ::uint32_t cached_has_bits = 0; (void) cached_has_bits; + if (!from._internal_select_player_source().empty()) { + _this->_internal_set_select_player_source(from._internal_select_player_source()); + } + if (!from._internal_select_source_player_source().empty()) { + _this->_internal_set_select_source_player_source(from._internal_select_source_player_source()); + } if (from._internal_media_player_id() != 0) { _this->_impl_.media_player_id_ = from._impl_.media_player_id_; } @@ -7525,7 +7617,11 @@ void NSPanelMQTTManagerCommand_MediaPlayerCommand::CopyFrom(const NSPanelMQTTMan void NSPanelMQTTManagerCommand_MediaPlayerCommand::InternalSwap(NSPanelMQTTManagerCommand_MediaPlayerCommand* PROTOBUF_RESTRICT other) { using std::swap; + auto* arena = GetArena(); + ABSL_DCHECK_EQ(arena, other->GetArena()); _internal_metadata_.InternalSwap(&other->_internal_metadata_); + ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.select_player_source_, &other->_impl_.select_player_source_, arena); + ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.select_source_player_source_, &other->_impl_.select_source_player_source_, arena); ::google::protobuf::internal::memswap< PROTOBUF_FIELD_OFFSET(NSPanelMQTTManagerCommand_MediaPlayerCommand, _impl_.source_volume_) + sizeof(NSPanelMQTTManagerCommand_MediaPlayerCommand::_impl_.source_volume_) diff --git a/docker/MQTTManager/include/protobuf/protobuf_nspanel.pb.h b/docker/MQTTManager/include/protobuf/protobuf_nspanel.pb.h index 2c49774b..720d45b8 100644 --- a/docker/MQTTManager/include/protobuf/protobuf_nspanel.pb.h +++ b/docker/MQTTManager/include/protobuf/protobuf_nspanel.pb.h @@ -2385,6 +2385,8 @@ class NSPanelMQTTManagerCommand_MediaPlayerCommand final : public ::google::prot // accessors ------------------------------------------------------- enum : int { + kSelectPlayerSourceFieldNumber = 9, + kSelectSourcePlayerSourceFieldNumber = 10, kMediaPlayerIdFieldNumber = 1, kPlaybackActionFieldNumber = 2, kVolumeFieldNumber = 4, @@ -2394,6 +2396,38 @@ class NSPanelMQTTManagerCommand_MediaPlayerCommand final : public ::google::prot kMutedFieldNumber = 8, kSourceVolumeFieldNumber = 6, }; + // string select_player_source = 9; + void clear_select_player_source() ; + const std::string& select_player_source() const; + template + void set_select_player_source(Arg_&& arg, Args_... args); + std::string* mutable_select_player_source(); + PROTOBUF_NODISCARD std::string* release_select_player_source(); + void set_allocated_select_player_source(std::string* value); + + private: + const std::string& _internal_select_player_source() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_select_player_source( + const std::string& value); + std::string* _internal_mutable_select_player_source(); + + public: + // string select_source_player_source = 10; + void clear_select_source_player_source() ; + const std::string& select_source_player_source() const; + template + void set_select_source_player_source(Arg_&& arg, Args_... args); + std::string* mutable_select_source_player_source(); + PROTOBUF_NODISCARD std::string* release_select_source_player_source(); + void set_allocated_select_source_player_source(std::string* value); + + private: + const std::string& _internal_select_source_player_source() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_select_source_player_source( + const std::string& value); + std::string* _internal_mutable_select_source_player_source(); + + public: // int32 media_player_id = 1; void clear_media_player_id() ; ::int32_t media_player_id() const; @@ -2479,8 +2513,8 @@ class NSPanelMQTTManagerCommand_MediaPlayerCommand final : public ::google::prot class _Internal; friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< - 3, 8, 0, - 0, 2> + 4, 10, 0, + 108, 2> _table_; static constexpr const void* _raw_default_instance_ = @@ -2500,6 +2534,8 @@ class NSPanelMQTTManagerCommand_MediaPlayerCommand final : public ::google::prot inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena, const Impl_& from, const NSPanelMQTTManagerCommand_MediaPlayerCommand& from_msg); + ::google::protobuf::internal::ArenaStringPtr select_player_source_; + ::google::protobuf::internal::ArenaStringPtr select_source_player_source_; ::int32_t media_player_id_; int playback_action_; ::int32_t volume_; @@ -9638,6 +9674,106 @@ inline void NSPanelMQTTManagerCommand_MediaPlayerCommand::_internal_set_muted(bo _impl_.muted_ = value; } +// string select_player_source = 9; +inline void NSPanelMQTTManagerCommand_MediaPlayerCommand::clear_select_player_source() { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.select_player_source_.ClearToEmpty(); +} +inline const std::string& NSPanelMQTTManagerCommand_MediaPlayerCommand::select_player_source() const + ABSL_ATTRIBUTE_LIFETIME_BOUND { + // @@protoc_insertion_point(field_get:NSPanelMQTTManagerCommand.MediaPlayerCommand.select_player_source) + return _internal_select_player_source(); +} +template +inline PROTOBUF_ALWAYS_INLINE void NSPanelMQTTManagerCommand_MediaPlayerCommand::set_select_player_source(Arg_&& arg, + Args_... args) { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.select_player_source_.Set(static_cast(arg), args..., GetArena()); + // @@protoc_insertion_point(field_set:NSPanelMQTTManagerCommand.MediaPlayerCommand.select_player_source) +} +inline std::string* NSPanelMQTTManagerCommand_MediaPlayerCommand::mutable_select_player_source() ABSL_ATTRIBUTE_LIFETIME_BOUND { + std::string* _s = _internal_mutable_select_player_source(); + // @@protoc_insertion_point(field_mutable:NSPanelMQTTManagerCommand.MediaPlayerCommand.select_player_source) + return _s; +} +inline const std::string& NSPanelMQTTManagerCommand_MediaPlayerCommand::_internal_select_player_source() const { + ::google::protobuf::internal::TSanRead(&_impl_); + return _impl_.select_player_source_.Get(); +} +inline void NSPanelMQTTManagerCommand_MediaPlayerCommand::_internal_set_select_player_source(const std::string& value) { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.select_player_source_.Set(value, GetArena()); +} +inline std::string* NSPanelMQTTManagerCommand_MediaPlayerCommand::_internal_mutable_select_player_source() { + ::google::protobuf::internal::TSanWrite(&_impl_); + return _impl_.select_player_source_.Mutable( GetArena()); +} +inline std::string* NSPanelMQTTManagerCommand_MediaPlayerCommand::release_select_player_source() { + ::google::protobuf::internal::TSanWrite(&_impl_); + // @@protoc_insertion_point(field_release:NSPanelMQTTManagerCommand.MediaPlayerCommand.select_player_source) + return _impl_.select_player_source_.Release(); +} +inline void NSPanelMQTTManagerCommand_MediaPlayerCommand::set_allocated_select_player_source(std::string* value) { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.select_player_source_.SetAllocated(value, GetArena()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (_impl_.select_player_source_.IsDefault()) { + _impl_.select_player_source_.Set("", GetArena()); + } + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:NSPanelMQTTManagerCommand.MediaPlayerCommand.select_player_source) +} + +// string select_source_player_source = 10; +inline void NSPanelMQTTManagerCommand_MediaPlayerCommand::clear_select_source_player_source() { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.select_source_player_source_.ClearToEmpty(); +} +inline const std::string& NSPanelMQTTManagerCommand_MediaPlayerCommand::select_source_player_source() const + ABSL_ATTRIBUTE_LIFETIME_BOUND { + // @@protoc_insertion_point(field_get:NSPanelMQTTManagerCommand.MediaPlayerCommand.select_source_player_source) + return _internal_select_source_player_source(); +} +template +inline PROTOBUF_ALWAYS_INLINE void NSPanelMQTTManagerCommand_MediaPlayerCommand::set_select_source_player_source(Arg_&& arg, + Args_... args) { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.select_source_player_source_.Set(static_cast(arg), args..., GetArena()); + // @@protoc_insertion_point(field_set:NSPanelMQTTManagerCommand.MediaPlayerCommand.select_source_player_source) +} +inline std::string* NSPanelMQTTManagerCommand_MediaPlayerCommand::mutable_select_source_player_source() ABSL_ATTRIBUTE_LIFETIME_BOUND { + std::string* _s = _internal_mutable_select_source_player_source(); + // @@protoc_insertion_point(field_mutable:NSPanelMQTTManagerCommand.MediaPlayerCommand.select_source_player_source) + return _s; +} +inline const std::string& NSPanelMQTTManagerCommand_MediaPlayerCommand::_internal_select_source_player_source() const { + ::google::protobuf::internal::TSanRead(&_impl_); + return _impl_.select_source_player_source_.Get(); +} +inline void NSPanelMQTTManagerCommand_MediaPlayerCommand::_internal_set_select_source_player_source(const std::string& value) { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.select_source_player_source_.Set(value, GetArena()); +} +inline std::string* NSPanelMQTTManagerCommand_MediaPlayerCommand::_internal_mutable_select_source_player_source() { + ::google::protobuf::internal::TSanWrite(&_impl_); + return _impl_.select_source_player_source_.Mutable( GetArena()); +} +inline std::string* NSPanelMQTTManagerCommand_MediaPlayerCommand::release_select_source_player_source() { + ::google::protobuf::internal::TSanWrite(&_impl_); + // @@protoc_insertion_point(field_release:NSPanelMQTTManagerCommand.MediaPlayerCommand.select_source_player_source) + return _impl_.select_source_player_source_.Release(); +} +inline void NSPanelMQTTManagerCommand_MediaPlayerCommand::set_allocated_select_source_player_source(std::string* value) { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.select_source_player_source_.SetAllocated(value, GetArena()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (_impl_.select_source_player_source_.IsDefault()) { + _impl_.select_source_player_source_.Set("", GetArena()); + } + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:NSPanelMQTTManagerCommand.MediaPlayerCommand.select_source_player_source) +} + // ------------------------------------------------------------------- // NSPanelMQTTManagerCommand diff --git a/docker/MQTTManager/include/protobuf/protobuf_nspanel_entity.pb.cc b/docker/MQTTManager/include/protobuf/protobuf_nspanel_entity.pb.cc index bd8b8fce..519c215d 100644 --- a/docker/MQTTManager/include/protobuf/protobuf_nspanel_entity.pb.cc +++ b/docker/MQTTManager/include/protobuf/protobuf_nspanel_entity.pb.cc @@ -48,48 +48,28 @@ struct NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValueDefau PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValueDefaultTypeInternal _NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue_default_instance_; -inline constexpr NSPanelEntityState_MediaPlayer::Impl_::Impl_( +inline constexpr NSPanelEntityState_MediaPlayer_SourceSelection::Impl_::Impl_( ::_pbi::ConstantInitialized) noexcept - : name_( - &::google::protobuf::internal::fixed_address_empty_string, - ::_pbi::ConstantInitialized()), - media_title_( + : sources_{}, + current_source_( &::google::protobuf::internal::fixed_address_empty_string, ::_pbi::ConstantInitialized()), - media_artist_( - &::google::protobuf::internal::fixed_address_empty_string, - ::_pbi::ConstantInitialized()), - album_art_url_( - &::google::protobuf::internal::fixed_address_empty_string, - ::_pbi::ConstantInitialized()), - media_player_id_{0}, - state_{static_cast< ::NSPanelEntityState_MediaPlayer_PlaybackState >(0)}, - volume_{0}, - source_volume_{0}, - is_muted_{false}, - has_source_volume_{false}, - can_play_{false}, - can_pause_{false}, - can_next_track_{false}, - can_previous_track_{false}, - can_set_volume_{false}, - can_mute_{false}, - volume_step_{0}, + can_select_{false}, _cached_size_{0} {} template -PROTOBUF_CONSTEXPR NSPanelEntityState_MediaPlayer::NSPanelEntityState_MediaPlayer(::_pbi::ConstantInitialized) +PROTOBUF_CONSTEXPR NSPanelEntityState_MediaPlayer_SourceSelection::NSPanelEntityState_MediaPlayer_SourceSelection(::_pbi::ConstantInitialized) : _impl_(::_pbi::ConstantInitialized()) {} -struct NSPanelEntityState_MediaPlayerDefaultTypeInternal { - PROTOBUF_CONSTEXPR NSPanelEntityState_MediaPlayerDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} - ~NSPanelEntityState_MediaPlayerDefaultTypeInternal() {} +struct NSPanelEntityState_MediaPlayer_SourceSelectionDefaultTypeInternal { + PROTOBUF_CONSTEXPR NSPanelEntityState_MediaPlayer_SourceSelectionDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} + ~NSPanelEntityState_MediaPlayer_SourceSelectionDefaultTypeInternal() {} union { - NSPanelEntityState_MediaPlayer _instance; + NSPanelEntityState_MediaPlayer_SourceSelection _instance; }; }; PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 NSPanelEntityState_MediaPlayerDefaultTypeInternal _NSPanelEntityState_MediaPlayer_default_instance_; + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 NSPanelEntityState_MediaPlayer_SourceSelectionDefaultTypeInternal _NSPanelEntityState_MediaPlayer_SourceSelection_default_instance_; inline constexpr NSPanelEntityState_Light::Impl_::Impl_( ::_pbi::ConstantInitialized) noexcept @@ -149,6 +129,51 @@ struct NSPanelEntityState_Thermostat_ThermostatOptionDefaultTypeInternal { PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 NSPanelEntityState_Thermostat_ThermostatOptionDefaultTypeInternal _NSPanelEntityState_Thermostat_ThermostatOption_default_instance_; +inline constexpr NSPanelEntityState_MediaPlayer::Impl_::Impl_( + ::_pbi::ConstantInitialized) noexcept + : _cached_size_{0}, + name_( + &::google::protobuf::internal::fixed_address_empty_string, + ::_pbi::ConstantInitialized()), + media_title_( + &::google::protobuf::internal::fixed_address_empty_string, + ::_pbi::ConstantInitialized()), + media_artist_( + &::google::protobuf::internal::fixed_address_empty_string, + ::_pbi::ConstantInitialized()), + album_art_url_( + &::google::protobuf::internal::fixed_address_empty_string, + ::_pbi::ConstantInitialized()), + player_sources_{nullptr}, + source_player_sources_{nullptr}, + media_player_id_{0}, + state_{static_cast< ::NSPanelEntityState_MediaPlayer_PlaybackState >(0)}, + volume_{0}, + source_volume_{0}, + is_muted_{false}, + has_source_volume_{false}, + can_play_{false}, + can_pause_{false}, + can_next_track_{false}, + can_previous_track_{false}, + can_set_volume_{false}, + can_mute_{false}, + volume_step_{0} {} + +template +PROTOBUF_CONSTEXPR NSPanelEntityState_MediaPlayer::NSPanelEntityState_MediaPlayer(::_pbi::ConstantInitialized) + : _impl_(::_pbi::ConstantInitialized()) {} +struct NSPanelEntityState_MediaPlayerDefaultTypeInternal { + PROTOBUF_CONSTEXPR NSPanelEntityState_MediaPlayerDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} + ~NSPanelEntityState_MediaPlayerDefaultTypeInternal() {} + union { + NSPanelEntityState_MediaPlayer _instance; + }; +}; + +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 NSPanelEntityState_MediaPlayerDefaultTypeInternal _NSPanelEntityState_MediaPlayer_default_instance_; + inline constexpr NSPanelEntityState_Thermostat::Impl_::Impl_( ::_pbi::ConstantInitialized) noexcept : options_{}, @@ -257,6 +282,17 @@ const ::uint32_t PROTOBUF_FIELD_OFFSET(::NSPanelEntityState_Thermostat, _impl_.step_size_), PROTOBUF_FIELD_OFFSET(::NSPanelEntityState_Thermostat, _impl_.options_), ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::NSPanelEntityState_MediaPlayer_SourceSelection, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::NSPanelEntityState_MediaPlayer_SourceSelection, _impl_.sources_), + PROTOBUF_FIELD_OFFSET(::NSPanelEntityState_MediaPlayer_SourceSelection, _impl_.current_source_), + PROTOBUF_FIELD_OFFSET(::NSPanelEntityState_MediaPlayer_SourceSelection, _impl_.can_select_), + PROTOBUF_FIELD_OFFSET(::NSPanelEntityState_MediaPlayer, _impl_._has_bits_), PROTOBUF_FIELD_OFFSET(::NSPanelEntityState_MediaPlayer, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ @@ -281,6 +317,27 @@ const ::uint32_t PROTOBUF_FIELD_OFFSET(::NSPanelEntityState_MediaPlayer, _impl_.can_mute_), PROTOBUF_FIELD_OFFSET(::NSPanelEntityState_MediaPlayer, _impl_.album_art_url_), PROTOBUF_FIELD_OFFSET(::NSPanelEntityState_MediaPlayer, _impl_.volume_step_), + PROTOBUF_FIELD_OFFSET(::NSPanelEntityState_MediaPlayer, _impl_.player_sources_), + PROTOBUF_FIELD_OFFSET(::NSPanelEntityState_MediaPlayer, _impl_.source_player_sources_), + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + 0, + 1, ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(::NSPanelEntityState, _internal_metadata_), ~0u, // no _extensions_ @@ -301,20 +358,22 @@ static const ::_pbi::MigrationSchema {18, -1, -1, sizeof(::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue)}, {28, -1, -1, sizeof(::NSPanelEntityState_Thermostat_ThermostatOption)}, {40, -1, -1, sizeof(::NSPanelEntityState_Thermostat)}, - {55, -1, -1, sizeof(::NSPanelEntityState_MediaPlayer)}, - {80, -1, -1, sizeof(::NSPanelEntityState)}, + {55, -1, -1, sizeof(::NSPanelEntityState_MediaPlayer_SourceSelection)}, + {66, 93, -1, sizeof(::NSPanelEntityState_MediaPlayer)}, + {112, -1, -1, sizeof(::NSPanelEntityState)}, }; static const ::_pb::Message* const file_default_instances[] = { &::_NSPanelEntityState_Light_default_instance_._instance, &::_NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue_default_instance_._instance, &::_NSPanelEntityState_Thermostat_ThermostatOption_default_instance_._instance, &::_NSPanelEntityState_Thermostat_default_instance_._instance, + &::_NSPanelEntityState_MediaPlayer_SourceSelection_default_instance_._instance, &::_NSPanelEntityState_MediaPlayer_default_instance_._instance, &::_NSPanelEntityState_default_instance_._instance, }; const char descriptor_table_protodef_protobuf_5fnspanel_5fentity_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE( protodesc_cold) = { - "\n\035protobuf_nspanel_entity.proto\"\217\013\n\022NSPa" + "\n\035protobuf_nspanel_entity.proto\"\370\014\n\022NSPa" "nelEntityState\022*\n\005light\030\001 \001(\0132\031.NSPanelE" "ntityState.LightH\000\0224\n\nthermostat\030\002 \001(\0132\036" ".NSPanelEntityState.ThermostatH\000\0227\n\014medi" @@ -337,7 +396,7 @@ const char descriptor_table_protodef_protobuf_5fnspanel_5fentity_2eproto[] ABSL_ "\030\004 \003(\0132E.NSPanelEntityState.Thermostat.T" "hermostatOption.ThermostatOptionValue\0324\n" "\025ThermostatOptionValue\022\r\n\005value\030\001 \001(\t\022\014\n" - "\004icon\030\002 \001(\t\032\201\004\n\013MediaPlayer\022\027\n\017media_pla" + "\004icon\030\002 \001(\t\032\352\005\n\013MediaPlayer\022\027\n\017media_pla" "yer_id\030\001 \001(\005\022\014\n\004name\030\002 \001(\t\022<\n\005state\030\003 \001(" "\0162-.NSPanelEntityState.MediaPlayer.Playb" "ackState\022\023\n\013media_title\030\004 \001(\t\022\024\n\014media_a" @@ -347,22 +406,28 @@ const char descriptor_table_protodef_protobuf_5fnspanel_5fentity_2eproto[] ABSL_ "_pause\030\013 \001(\010\022\026\n\016can_next_track\030\014 \001(\010\022\032\n\022" "can_previous_track\030\r \001(\010\022\026\n\016can_set_volu" "me\030\016 \001(\010\022\020\n\010can_mute\030\017 \001(\010\022\025\n\ralbum_art_" - "url\030\020 \001(\t\022\023\n\013volume_step\030\021 \001(\005\"_\n\rPlayba" - "ckState\022\013\n\007UNKNOWN\020\000\022\007\n\003OFF\020\001\022\006\n\002ON\020\002\022\010\n" - "\004IDLE\020\003\022\013\n\007PLAYING\020\004\022\n\n\006PAUSED\020\005\022\r\n\tBUFF" - "ERING\020\006B\010\n\006entityb\006proto3" + "url\030\020 \001(\t\022\023\n\013volume_step\030\021 \001(\005\022G\n\016player" + "_sources\030\022 \001(\0132/.NSPanelEntityState.Medi" + "aPlayer.SourceSelection\022N\n\025source_player" + "_sources\030\023 \001(\0132/.NSPanelEntityState.Medi" + "aPlayer.SourceSelection\032N\n\017SourceSelecti" + "on\022\017\n\007sources\030\001 \003(\t\022\026\n\016current_source\030\002 " + "\001(\t\022\022\n\ncan_select\030\003 \001(\010\"_\n\rPlaybackState" + "\022\013\n\007UNKNOWN\020\000\022\007\n\003OFF\020\001\022\006\n\002ON\020\002\022\010\n\004IDLE\020\003" + "\022\013\n\007PLAYING\020\004\022\n\n\006PAUSED\020\005\022\r\n\tBUFFERING\020\006" + "B\010\n\006entityb\006proto3" }; static ::absl::once_flag descriptor_table_protobuf_5fnspanel_5fentity_2eproto_once; PROTOBUF_CONSTINIT const ::_pbi::DescriptorTable descriptor_table_protobuf_5fnspanel_5fentity_2eproto = { false, false, - 1465, + 1698, descriptor_table_protodef_protobuf_5fnspanel_5fentity_2eproto, "protobuf_nspanel_entity.proto", &descriptor_table_protobuf_5fnspanel_5fentity_2eproto_once, nullptr, 0, - 6, + 7, schemas, file_default_instances, TableStruct_protobuf_5fnspanel_5fentity_2eproto::offsets, @@ -1728,8 +1793,257 @@ ::google::protobuf::Metadata NSPanelEntityState_Thermostat::GetMetadata() const } // =================================================================== +class NSPanelEntityState_MediaPlayer_SourceSelection::_Internal { + public: +}; + +NSPanelEntityState_MediaPlayer_SourceSelection::NSPanelEntityState_MediaPlayer_SourceSelection(::google::protobuf::Arena* arena) + : ::google::protobuf::Message(arena) { + SharedCtor(arena); + // @@protoc_insertion_point(arena_constructor:NSPanelEntityState.MediaPlayer.SourceSelection) +} +inline PROTOBUF_NDEBUG_INLINE NSPanelEntityState_MediaPlayer_SourceSelection::Impl_::Impl_( + ::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena, + const Impl_& from, const ::NSPanelEntityState_MediaPlayer_SourceSelection& from_msg) + : sources_{visibility, arena, from.sources_}, + current_source_(arena, from.current_source_), + _cached_size_{0} {} + +NSPanelEntityState_MediaPlayer_SourceSelection::NSPanelEntityState_MediaPlayer_SourceSelection( + ::google::protobuf::Arena* arena, + const NSPanelEntityState_MediaPlayer_SourceSelection& from) + : ::google::protobuf::Message(arena) { + NSPanelEntityState_MediaPlayer_SourceSelection* const _this = this; + (void)_this; + _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>( + from._internal_metadata_); + new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from); + _impl_.can_select_ = from._impl_.can_select_; + + // @@protoc_insertion_point(copy_constructor:NSPanelEntityState.MediaPlayer.SourceSelection) +} +inline PROTOBUF_NDEBUG_INLINE NSPanelEntityState_MediaPlayer_SourceSelection::Impl_::Impl_( + ::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena) + : sources_{visibility, arena}, + current_source_(arena), + _cached_size_{0} {} + +inline void NSPanelEntityState_MediaPlayer_SourceSelection::SharedCtor(::_pb::Arena* arena) { + new (&_impl_) Impl_(internal_visibility(), arena); + _impl_.can_select_ = {}; +} +NSPanelEntityState_MediaPlayer_SourceSelection::~NSPanelEntityState_MediaPlayer_SourceSelection() { + // @@protoc_insertion_point(destructor:NSPanelEntityState.MediaPlayer.SourceSelection) + _internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>(); + SharedDtor(); +} +inline void NSPanelEntityState_MediaPlayer_SourceSelection::SharedDtor() { + ABSL_DCHECK(GetArena() == nullptr); + _impl_.current_source_.Destroy(); + _impl_.~Impl_(); +} + +const ::google::protobuf::MessageLite::ClassData* +NSPanelEntityState_MediaPlayer_SourceSelection::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: + ClassDataFull _data_ = { + { + &_table_.header, + nullptr, // OnDemandRegisterArenaDtor + nullptr, // IsInitialized + PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer_SourceSelection, _impl_._cached_size_), + false, + }, + &NSPanelEntityState_MediaPlayer_SourceSelection::MergeImpl, + &NSPanelEntityState_MediaPlayer_SourceSelection::kDescriptorMethods, + &descriptor_table_protobuf_5fnspanel_5fentity_2eproto, + nullptr, // tracker + }; + ::google::protobuf::internal::PrefetchToLocalCache(&_data_); + ::google::protobuf::internal::PrefetchToLocalCache(_data_.tc_table); + return _data_.base(); +} +PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 +const ::_pbi::TcParseTable<2, 3, 0, 76, 2> NSPanelEntityState_MediaPlayer_SourceSelection::_table_ = { + { + 0, // no _has_bits_ + 0, // no _extensions_ + 3, 24, // max_field_number, fast_idx_mask + offsetof(decltype(_table_), field_lookup_table), + 4294967288, // skipmap + offsetof(decltype(_table_), field_entries), + 3, // num_field_entries + 0, // num_aux_entries + offsetof(decltype(_table_), field_names), // no aux_entries + &_NSPanelEntityState_MediaPlayer_SourceSelection_default_instance_._instance, + nullptr, // post_loop_handler + ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::NSPanelEntityState_MediaPlayer_SourceSelection>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE + }, {{ + {::_pbi::TcParser::MiniParse, {}}, + // repeated string sources = 1; + {::_pbi::TcParser::FastUR1, + {10, 63, 0, PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer_SourceSelection, _impl_.sources_)}}, + // string current_source = 2; + {::_pbi::TcParser::FastUS1, + {18, 63, 0, PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer_SourceSelection, _impl_.current_source_)}}, + // bool can_select = 3; + {::_pbi::TcParser::SingularVarintNoZag1(), + {24, 63, 0, PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer_SourceSelection, _impl_.can_select_)}}, + }}, {{ + 65535, 65535 + }}, {{ + // repeated string sources = 1; + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer_SourceSelection, _impl_.sources_), 0, 0, + (0 | ::_fl::kFcRepeated | ::_fl::kUtf8String | ::_fl::kRepSString)}, + // string current_source = 2; + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer_SourceSelection, _impl_.current_source_), 0, 0, + (0 | ::_fl::kFcSingular | ::_fl::kUtf8String | ::_fl::kRepAString)}, + // bool can_select = 3; + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer_SourceSelection, _impl_.can_select_), 0, 0, + (0 | ::_fl::kFcSingular | ::_fl::kBool)}, + }}, + // no aux_entries + {{ + "\56\7\16\0\0\0\0\0" + "NSPanelEntityState.MediaPlayer.SourceSelection" + "sources" + "current_source" + }}, +}; + +PROTOBUF_NOINLINE void NSPanelEntityState_MediaPlayer_SourceSelection::Clear() { +// @@protoc_insertion_point(message_clear_start:NSPanelEntityState.MediaPlayer.SourceSelection) + ::google::protobuf::internal::TSanWrite(&_impl_); + ::uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + _impl_.sources_.Clear(); + _impl_.current_source_.ClearToEmpty(); + _impl_.can_select_ = false; + _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); +} + +::uint8_t* NSPanelEntityState_MediaPlayer_SourceSelection::_InternalSerialize( + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:NSPanelEntityState.MediaPlayer.SourceSelection) + ::uint32_t cached_has_bits = 0; + (void)cached_has_bits; + + // repeated string sources = 1; + for (int i = 0, n = this->_internal_sources_size(); i < n; ++i) { + const auto& s = this->_internal_sources().Get(i); + ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + s.data(), static_cast(s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "NSPanelEntityState.MediaPlayer.SourceSelection.sources"); + target = stream->WriteString(1, s, target); + } + + // string current_source = 2; + if (!this->_internal_current_source().empty()) { + const std::string& _s = this->_internal_current_source(); + ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + _s.data(), static_cast(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "NSPanelEntityState.MediaPlayer.SourceSelection.current_source"); + target = stream->WriteStringMaybeAliased(2, _s, target); + } + + // bool can_select = 3; + if (this->_internal_can_select() != 0) { + target = stream->EnsureSpace(target); + target = ::_pbi::WireFormatLite::WriteBoolToArray( + 3, this->_internal_can_select(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = + ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:NSPanelEntityState.MediaPlayer.SourceSelection) + return target; +} + +::size_t NSPanelEntityState_MediaPlayer_SourceSelection::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:NSPanelEntityState.MediaPlayer.SourceSelection) + ::size_t total_size = 0; + + ::uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + ::_pbi::Prefetch5LinesFrom7Lines(reinterpret_cast(this)); + // repeated string sources = 1; + total_size += 1 * ::google::protobuf::internal::FromIntSize(_internal_sources().size()); + for (int i = 0, n = _internal_sources().size(); i < n; ++i) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + _internal_sources().Get(i)); + } + // string current_source = 2; + if (!this->_internal_current_source().empty()) { + total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize( + this->_internal_current_source()); + } + + // bool can_select = 3; + if (this->_internal_can_select() != 0) { + total_size += 2; + } + + return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); +} + + +void NSPanelEntityState_MediaPlayer_SourceSelection::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { + auto* const _this = static_cast(&to_msg); + auto& from = static_cast(from_msg); + // @@protoc_insertion_point(class_specific_merge_from_start:NSPanelEntityState.MediaPlayer.SourceSelection) + ABSL_DCHECK_NE(&from, _this); + ::uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + _this->_internal_mutable_sources()->MergeFrom(from._internal_sources()); + if (!from._internal_current_source().empty()) { + _this->_internal_set_current_source(from._internal_current_source()); + } + if (from._internal_can_select() != 0) { + _this->_impl_.can_select_ = from._impl_.can_select_; + } + _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); +} + +void NSPanelEntityState_MediaPlayer_SourceSelection::CopyFrom(const NSPanelEntityState_MediaPlayer_SourceSelection& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:NSPanelEntityState.MediaPlayer.SourceSelection) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + + +void NSPanelEntityState_MediaPlayer_SourceSelection::InternalSwap(NSPanelEntityState_MediaPlayer_SourceSelection* PROTOBUF_RESTRICT other) { + using std::swap; + auto* arena = GetArena(); + ABSL_DCHECK_EQ(arena, other->GetArena()); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + _impl_.sources_.InternalSwap(&other->_impl_.sources_); + ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.current_source_, &other->_impl_.current_source_, arena); + swap(_impl_.can_select_, other->_impl_.can_select_); +} + +::google::protobuf::Metadata NSPanelEntityState_MediaPlayer_SourceSelection::GetMetadata() const { + return ::google::protobuf::Message::GetMetadataImpl(GetClassData()->full()); +} +// =================================================================== + class NSPanelEntityState_MediaPlayer::_Internal { public: + using HasBits = + decltype(std::declval()._impl_._has_bits_); + static constexpr ::int32_t kHasBitsOffset = + 8 * PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_._has_bits_); }; NSPanelEntityState_MediaPlayer::NSPanelEntityState_MediaPlayer(::google::protobuf::Arena* arena) @@ -1740,11 +2054,12 @@ NSPanelEntityState_MediaPlayer::NSPanelEntityState_MediaPlayer(::google::protobu inline PROTOBUF_NDEBUG_INLINE NSPanelEntityState_MediaPlayer::Impl_::Impl_( ::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena, const Impl_& from, const ::NSPanelEntityState_MediaPlayer& from_msg) - : name_(arena, from.name_), + : _has_bits_{from._has_bits_}, + _cached_size_{0}, + name_(arena, from.name_), media_title_(arena, from.media_title_), media_artist_(arena, from.media_artist_), - album_art_url_(arena, from.album_art_url_), - _cached_size_{0} {} + album_art_url_(arena, from.album_art_url_) {} NSPanelEntityState_MediaPlayer::NSPanelEntityState_MediaPlayer( ::google::protobuf::Arena* arena, @@ -1755,6 +2070,13 @@ NSPanelEntityState_MediaPlayer::NSPanelEntityState_MediaPlayer( _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>( from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from); + ::uint32_t cached_has_bits = _impl_._has_bits_[0]; + _impl_.player_sources_ = (cached_has_bits & 0x00000001u) ? ::google::protobuf::Message::CopyConstruct<::NSPanelEntityState_MediaPlayer_SourceSelection>( + arena, *from._impl_.player_sources_) + : nullptr; + _impl_.source_player_sources_ = (cached_has_bits & 0x00000002u) ? ::google::protobuf::Message::CopyConstruct<::NSPanelEntityState_MediaPlayer_SourceSelection>( + arena, *from._impl_.source_player_sources_) + : nullptr; ::memcpy(reinterpret_cast(&_impl_) + offsetof(Impl_, media_player_id_), reinterpret_cast(&from._impl_) + @@ -1768,19 +2090,19 @@ NSPanelEntityState_MediaPlayer::NSPanelEntityState_MediaPlayer( inline PROTOBUF_NDEBUG_INLINE NSPanelEntityState_MediaPlayer::Impl_::Impl_( ::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena) - : name_(arena), + : _cached_size_{0}, + name_(arena), media_title_(arena), media_artist_(arena), - album_art_url_(arena), - _cached_size_{0} {} + album_art_url_(arena) {} inline void NSPanelEntityState_MediaPlayer::SharedCtor(::_pb::Arena* arena) { new (&_impl_) Impl_(internal_visibility(), arena); ::memset(reinterpret_cast(&_impl_) + - offsetof(Impl_, media_player_id_), + offsetof(Impl_, player_sources_), 0, offsetof(Impl_, volume_step_) - - offsetof(Impl_, media_player_id_) + + offsetof(Impl_, player_sources_) + sizeof(Impl_::volume_step_)); } NSPanelEntityState_MediaPlayer::~NSPanelEntityState_MediaPlayer() { @@ -1794,6 +2116,8 @@ inline void NSPanelEntityState_MediaPlayer::SharedDtor() { _impl_.media_title_.Destroy(); _impl_.media_artist_.Destroy(); _impl_.album_art_url_.Destroy(); + delete _impl_.player_sources_; + delete _impl_.source_player_sources_; _impl_.~Impl_(); } @@ -1818,17 +2142,17 @@ NSPanelEntityState_MediaPlayer::GetClassData() const { return _data_.base(); } PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 -const ::_pbi::TcParseTable<5, 17, 0, 95, 2> NSPanelEntityState_MediaPlayer::_table_ = { +const ::_pbi::TcParseTable<5, 19, 2, 95, 2> NSPanelEntityState_MediaPlayer::_table_ = { { - 0, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_._has_bits_), 0, // no _extensions_ - 17, 248, // max_field_number, fast_idx_mask + 19, 248, // max_field_number, fast_idx_mask offsetof(decltype(_table_), field_lookup_table), - 4294836224, // skipmap + 4294443008, // skipmap offsetof(decltype(_table_), field_entries), - 17, // num_field_entries - 0, // num_aux_entries - offsetof(decltype(_table_), field_names), // no aux_entries + 19, // num_field_entries + 2, // num_aux_entries + offsetof(decltype(_table_), aux_entries), &_NSPanelEntityState_MediaPlayer_default_instance_._instance, nullptr, // post_loop_handler ::_pbi::TcParser::GenericFallback, // fallback @@ -1888,8 +2212,12 @@ const ::_pbi::TcParseTable<5, 17, 0, 95, 2> NSPanelEntityState_MediaPlayer::_tab // int32 volume_step = 17; {::_pbi::TcParser::FastV32S2, {392, 63, 0, PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.volume_step_)}}, - {::_pbi::TcParser::MiniParse, {}}, - {::_pbi::TcParser::MiniParse, {}}, + // .NSPanelEntityState.MediaPlayer.SourceSelection player_sources = 18; + {::_pbi::TcParser::FastMtS2, + {402, 0, 0, PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.player_sources_)}}, + // .NSPanelEntityState.MediaPlayer.SourceSelection source_player_sources = 19; + {::_pbi::TcParser::FastMtS2, + {410, 1, 1, PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.source_player_sources_)}}, {::_pbi::TcParser::MiniParse, {}}, {::_pbi::TcParser::MiniParse, {}}, {::_pbi::TcParser::MiniParse, {}}, @@ -1906,59 +2234,66 @@ const ::_pbi::TcParseTable<5, 17, 0, 95, 2> NSPanelEntityState_MediaPlayer::_tab 65535, 65535 }}, {{ // int32 media_player_id = 1; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.media_player_id_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.media_player_id_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kInt32)}, // string name = 2; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.name_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.name_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kUtf8String | ::_fl::kRepAString)}, // .NSPanelEntityState.MediaPlayer.PlaybackState state = 3; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.state_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.state_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kOpenEnum)}, // string media_title = 4; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.media_title_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.media_title_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kUtf8String | ::_fl::kRepAString)}, // string media_artist = 5; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.media_artist_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.media_artist_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kUtf8String | ::_fl::kRepAString)}, // int32 volume = 6; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.volume_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.volume_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kInt32)}, // bool is_muted = 7; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.is_muted_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.is_muted_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kBool)}, // bool has_source_volume = 8; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.has_source_volume_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.has_source_volume_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kBool)}, // int32 source_volume = 9; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.source_volume_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.source_volume_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kInt32)}, // bool can_play = 10; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.can_play_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.can_play_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kBool)}, // bool can_pause = 11; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.can_pause_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.can_pause_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kBool)}, // bool can_next_track = 12; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.can_next_track_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.can_next_track_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kBool)}, // bool can_previous_track = 13; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.can_previous_track_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.can_previous_track_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kBool)}, // bool can_set_volume = 14; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.can_set_volume_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.can_set_volume_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kBool)}, // bool can_mute = 15; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.can_mute_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.can_mute_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kBool)}, // string album_art_url = 16; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.album_art_url_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.album_art_url_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kUtf8String | ::_fl::kRepAString)}, // int32 volume_step = 17; - {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.volume_step_), 0, 0, + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.volume_step_), -1, 0, (0 | ::_fl::kFcSingular | ::_fl::kInt32)}, - }}, - // no aux_entries - {{ + // .NSPanelEntityState.MediaPlayer.SourceSelection player_sources = 18; + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.player_sources_), _Internal::kHasBitsOffset + 0, 0, + (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + // .NSPanelEntityState.MediaPlayer.SourceSelection source_player_sources = 19; + {PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.source_player_sources_), _Internal::kHasBitsOffset + 1, 1, + (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + }}, {{ + {::_pbi::TcParser::GetTable<::NSPanelEntityState_MediaPlayer_SourceSelection>()}, + {::_pbi::TcParser::GetTable<::NSPanelEntityState_MediaPlayer_SourceSelection>()}, + }}, {{ "\36\0\4\0\13\14\0\0\0\0\0\0\0\0\0\0\15\0\0\0\0\0\0\0" "NSPanelEntityState.MediaPlayer" "name" @@ -1979,9 +2314,21 @@ PROTOBUF_NOINLINE void NSPanelEntityState_MediaPlayer::Clear() { _impl_.media_title_.ClearToEmpty(); _impl_.media_artist_.ClearToEmpty(); _impl_.album_art_url_.ClearToEmpty(); + cached_has_bits = _impl_._has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + ABSL_DCHECK(_impl_.player_sources_ != nullptr); + _impl_.player_sources_->Clear(); + } + if (cached_has_bits & 0x00000002u) { + ABSL_DCHECK(_impl_.source_player_sources_ != nullptr); + _impl_.source_player_sources_->Clear(); + } + } ::memset(&_impl_.media_player_id_, 0, static_cast<::size_t>( reinterpret_cast(&_impl_.volume_step_) - reinterpret_cast(&_impl_.media_player_id_)) + sizeof(_impl_.volume_step_)); + _impl_._has_bits_.Clear(); _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } @@ -2115,6 +2462,19 @@ ::uint8_t* NSPanelEntityState_MediaPlayer::_InternalSerialize( 17, this->_internal_volume_step(), target); } + cached_has_bits = _impl_._has_bits_[0]; + // .NSPanelEntityState.MediaPlayer.SourceSelection player_sources = 18; + if (cached_has_bits & 0x00000001u) { + target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( + 18, *_impl_.player_sources_, _impl_.player_sources_->GetCachedSize(), target, stream); + } + + // .NSPanelEntityState.MediaPlayer.SourceSelection source_player_sources = 19; + if (cached_has_bits & 0x00000002u) { + target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( + 19, *_impl_.source_player_sources_, _impl_.source_player_sources_->GetCachedSize(), target, stream); + } + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( @@ -2157,6 +2517,21 @@ ::size_t NSPanelEntityState_MediaPlayer::ByteSizeLong() const { this->_internal_album_art_url()); } + cached_has_bits = _impl_._has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + // .NSPanelEntityState.MediaPlayer.SourceSelection player_sources = 18; + if (cached_has_bits & 0x00000001u) { + total_size += + 2 + ::google::protobuf::internal::WireFormatLite::MessageSize(*_impl_.player_sources_); + } + + // .NSPanelEntityState.MediaPlayer.SourceSelection source_player_sources = 19; + if (cached_has_bits & 0x00000002u) { + total_size += + 2 + ::google::protobuf::internal::WireFormatLite::MessageSize(*_impl_.source_player_sources_); + } + + } // int32 media_player_id = 1; if (this->_internal_media_player_id() != 0) { total_size += ::_pbi::WireFormatLite::Int32SizePlusOne( @@ -2234,6 +2609,7 @@ ::size_t NSPanelEntityState_MediaPlayer::ByteSizeLong() const { void NSPanelEntityState_MediaPlayer::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:NSPanelEntityState.MediaPlayer) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -2251,6 +2627,27 @@ void NSPanelEntityState_MediaPlayer::MergeImpl(::google::protobuf::MessageLite& if (!from._internal_album_art_url().empty()) { _this->_internal_set_album_art_url(from._internal_album_art_url()); } + cached_has_bits = from._impl_._has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + ABSL_DCHECK(from._impl_.player_sources_ != nullptr); + if (_this->_impl_.player_sources_ == nullptr) { + _this->_impl_.player_sources_ = + ::google::protobuf::Message::CopyConstruct<::NSPanelEntityState_MediaPlayer_SourceSelection>(arena, *from._impl_.player_sources_); + } else { + _this->_impl_.player_sources_->MergeFrom(*from._impl_.player_sources_); + } + } + if (cached_has_bits & 0x00000002u) { + ABSL_DCHECK(from._impl_.source_player_sources_ != nullptr); + if (_this->_impl_.source_player_sources_ == nullptr) { + _this->_impl_.source_player_sources_ = + ::google::protobuf::Message::CopyConstruct<::NSPanelEntityState_MediaPlayer_SourceSelection>(arena, *from._impl_.source_player_sources_); + } else { + _this->_impl_.source_player_sources_->MergeFrom(*from._impl_.source_player_sources_); + } + } + } if (from._internal_media_player_id() != 0) { _this->_impl_.media_player_id_ = from._impl_.media_player_id_; } @@ -2290,6 +2687,7 @@ void NSPanelEntityState_MediaPlayer::MergeImpl(::google::protobuf::MessageLite& if (from._internal_volume_step() != 0) { _this->_impl_.volume_step_ = from._impl_.volume_step_; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -2306,6 +2704,7 @@ void NSPanelEntityState_MediaPlayer::InternalSwap(NSPanelEntityState_MediaPlayer auto* arena = GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena); ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.media_title_, &other->_impl_.media_title_, arena); ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.media_artist_, &other->_impl_.media_artist_, arena); @@ -2313,9 +2712,9 @@ void NSPanelEntityState_MediaPlayer::InternalSwap(NSPanelEntityState_MediaPlayer ::google::protobuf::internal::memswap< PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.volume_step_) + sizeof(NSPanelEntityState_MediaPlayer::_impl_.volume_step_) - - PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.media_player_id_)>( - reinterpret_cast(&_impl_.media_player_id_), - reinterpret_cast(&other->_impl_.media_player_id_)); + - PROTOBUF_FIELD_OFFSET(NSPanelEntityState_MediaPlayer, _impl_.player_sources_)>( + reinterpret_cast(&_impl_.player_sources_), + reinterpret_cast(&other->_impl_.player_sources_)); } ::google::protobuf::Metadata NSPanelEntityState_MediaPlayer::GetMetadata() const { diff --git a/docker/MQTTManager/include/protobuf/protobuf_nspanel_entity.pb.h b/docker/MQTTManager/include/protobuf/protobuf_nspanel_entity.pb.h index d7cfb6d0..84139b73 100644 --- a/docker/MQTTManager/include/protobuf/protobuf_nspanel_entity.pb.h +++ b/docker/MQTTManager/include/protobuf/protobuf_nspanel_entity.pb.h @@ -59,6 +59,9 @@ extern NSPanelEntityState_LightDefaultTypeInternal _NSPanelEntityState_Light_def class NSPanelEntityState_MediaPlayer; struct NSPanelEntityState_MediaPlayerDefaultTypeInternal; extern NSPanelEntityState_MediaPlayerDefaultTypeInternal _NSPanelEntityState_MediaPlayer_default_instance_; +class NSPanelEntityState_MediaPlayer_SourceSelection; +struct NSPanelEntityState_MediaPlayer_SourceSelectionDefaultTypeInternal; +extern NSPanelEntityState_MediaPlayer_SourceSelectionDefaultTypeInternal _NSPanelEntityState_MediaPlayer_SourceSelection_default_instance_; class NSPanelEntityState_Thermostat; struct NSPanelEntityState_ThermostatDefaultTypeInternal; extern NSPanelEntityState_ThermostatDefaultTypeInternal _NSPanelEntityState_Thermostat_default_instance_; @@ -345,23 +348,23 @@ class NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue final }; // ------------------------------------------------------------------- -class NSPanelEntityState_MediaPlayer final : public ::google::protobuf::Message -/* @@protoc_insertion_point(class_definition:NSPanelEntityState.MediaPlayer) */ { +class NSPanelEntityState_MediaPlayer_SourceSelection final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:NSPanelEntityState.MediaPlayer.SourceSelection) */ { public: - inline NSPanelEntityState_MediaPlayer() : NSPanelEntityState_MediaPlayer(nullptr) {} - ~NSPanelEntityState_MediaPlayer() override; + inline NSPanelEntityState_MediaPlayer_SourceSelection() : NSPanelEntityState_MediaPlayer_SourceSelection(nullptr) {} + ~NSPanelEntityState_MediaPlayer_SourceSelection() override; template - explicit PROTOBUF_CONSTEXPR NSPanelEntityState_MediaPlayer( + explicit PROTOBUF_CONSTEXPR NSPanelEntityState_MediaPlayer_SourceSelection( ::google::protobuf::internal::ConstantInitialized); - inline NSPanelEntityState_MediaPlayer(const NSPanelEntityState_MediaPlayer& from) : NSPanelEntityState_MediaPlayer(nullptr, from) {} - inline NSPanelEntityState_MediaPlayer(NSPanelEntityState_MediaPlayer&& from) noexcept - : NSPanelEntityState_MediaPlayer(nullptr, std::move(from)) {} - inline NSPanelEntityState_MediaPlayer& operator=(const NSPanelEntityState_MediaPlayer& from) { + inline NSPanelEntityState_MediaPlayer_SourceSelection(const NSPanelEntityState_MediaPlayer_SourceSelection& from) : NSPanelEntityState_MediaPlayer_SourceSelection(nullptr, from) {} + inline NSPanelEntityState_MediaPlayer_SourceSelection(NSPanelEntityState_MediaPlayer_SourceSelection&& from) noexcept + : NSPanelEntityState_MediaPlayer_SourceSelection(nullptr, std::move(from)) {} + inline NSPanelEntityState_MediaPlayer_SourceSelection& operator=(const NSPanelEntityState_MediaPlayer_SourceSelection& from) { CopyFrom(from); return *this; } - inline NSPanelEntityState_MediaPlayer& operator=(NSPanelEntityState_MediaPlayer&& from) noexcept { + inline NSPanelEntityState_MediaPlayer_SourceSelection& operator=(NSPanelEntityState_MediaPlayer_SourceSelection&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() #ifdef PROTOBUF_FORCE_COPY_IN_MOVE @@ -393,16 +396,16 @@ class NSPanelEntityState_MediaPlayer final : public ::google::protobuf::Message static const ::google::protobuf::Reflection* GetReflection() { return default_instance().GetMetadata().reflection; } - static const NSPanelEntityState_MediaPlayer& default_instance() { + static const NSPanelEntityState_MediaPlayer_SourceSelection& default_instance() { return *internal_default_instance(); } - static inline const NSPanelEntityState_MediaPlayer* internal_default_instance() { - return reinterpret_cast( - &_NSPanelEntityState_MediaPlayer_default_instance_); + static inline const NSPanelEntityState_MediaPlayer_SourceSelection* internal_default_instance() { + return reinterpret_cast( + &_NSPanelEntityState_MediaPlayer_SourceSelection_default_instance_); } static constexpr int kIndexInFileMessages = 4; - friend void swap(NSPanelEntityState_MediaPlayer& a, NSPanelEntityState_MediaPlayer& b) { a.Swap(&b); } - inline void Swap(NSPanelEntityState_MediaPlayer* other) { + friend void swap(NSPanelEntityState_MediaPlayer_SourceSelection& a, NSPanelEntityState_MediaPlayer_SourceSelection& b) { a.Swap(&b); } + inline void Swap(NSPanelEntityState_MediaPlayer_SourceSelection* other) { if (other == this) return; #ifdef PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() != nullptr && GetArena() == other->GetArena()) { @@ -414,7 +417,7 @@ class NSPanelEntityState_MediaPlayer final : public ::google::protobuf::Message ::google::protobuf::internal::GenericSwap(this, other); } } - void UnsafeArenaSwap(NSPanelEntityState_MediaPlayer* other) { + void UnsafeArenaSwap(NSPanelEntityState_MediaPlayer_SourceSelection* other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); @@ -422,13 +425,13 @@ class NSPanelEntityState_MediaPlayer final : public ::google::protobuf::Message // implements Message ---------------------------------------------- - NSPanelEntityState_MediaPlayer* New(::google::protobuf::Arena* arena = nullptr) const final { - return ::google::protobuf::Message::DefaultConstruct(arena); + NSPanelEntityState_MediaPlayer_SourceSelection* New(::google::protobuf::Arena* arena = nullptr) const final { + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; - void CopyFrom(const NSPanelEntityState_MediaPlayer& from); + void CopyFrom(const NSPanelEntityState_MediaPlayer_SourceSelection& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom(const NSPanelEntityState_MediaPlayer& from) { NSPanelEntityState_MediaPlayer::MergeImpl(*this, from); } + void MergeFrom(const NSPanelEntityState_MediaPlayer_SourceSelection& from) { NSPanelEntityState_MediaPlayer_SourceSelection::MergeImpl(*this, from); } private: static void MergeImpl( @@ -449,16 +452,16 @@ class NSPanelEntityState_MediaPlayer final : public ::google::protobuf::Message private: void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); - void InternalSwap(NSPanelEntityState_MediaPlayer* other); + void InternalSwap(NSPanelEntityState_MediaPlayer_SourceSelection* other); private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { return "NSPanelEntityState.MediaPlayer"; } + static ::absl::string_view FullMessageName() { return "NSPanelEntityState.MediaPlayer.SourceSelection"; } protected: - explicit NSPanelEntityState_MediaPlayer(::google::protobuf::Arena* arena); - NSPanelEntityState_MediaPlayer(::google::protobuf::Arena* arena, const NSPanelEntityState_MediaPlayer& from); - NSPanelEntityState_MediaPlayer(::google::protobuf::Arena* arena, NSPanelEntityState_MediaPlayer&& from) noexcept - : NSPanelEntityState_MediaPlayer(arena) { + explicit NSPanelEntityState_MediaPlayer_SourceSelection(::google::protobuf::Arena* arena); + NSPanelEntityState_MediaPlayer_SourceSelection(::google::protobuf::Arena* arena, const NSPanelEntityState_MediaPlayer_SourceSelection& from); + NSPanelEntityState_MediaPlayer_SourceSelection(::google::protobuf::Arena* arena, NSPanelEntityState_MediaPlayer_SourceSelection&& from) noexcept + : NSPanelEntityState_MediaPlayer_SourceSelection(arena) { *this = ::std::move(from); } const ::google::protobuf::Message::ClassData* GetClassData() const final; @@ -466,256 +469,78 @@ class NSPanelEntityState_MediaPlayer final : public ::google::protobuf::Message public: ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- - using PlaybackState = NSPanelEntityState_MediaPlayer_PlaybackState; - static constexpr PlaybackState UNKNOWN = NSPanelEntityState_MediaPlayer_PlaybackState_UNKNOWN; - static constexpr PlaybackState OFF = NSPanelEntityState_MediaPlayer_PlaybackState_OFF; - static constexpr PlaybackState ON = NSPanelEntityState_MediaPlayer_PlaybackState_ON; - static constexpr PlaybackState IDLE = NSPanelEntityState_MediaPlayer_PlaybackState_IDLE; - static constexpr PlaybackState PLAYING = NSPanelEntityState_MediaPlayer_PlaybackState_PLAYING; - static constexpr PlaybackState PAUSED = NSPanelEntityState_MediaPlayer_PlaybackState_PAUSED; - static constexpr PlaybackState BUFFERING = NSPanelEntityState_MediaPlayer_PlaybackState_BUFFERING; - static inline bool PlaybackState_IsValid(int value) { - return NSPanelEntityState_MediaPlayer_PlaybackState_IsValid(value); - } - static constexpr PlaybackState PlaybackState_MIN = NSPanelEntityState_MediaPlayer_PlaybackState_PlaybackState_MIN; - static constexpr PlaybackState PlaybackState_MAX = NSPanelEntityState_MediaPlayer_PlaybackState_PlaybackState_MAX; - static constexpr int PlaybackState_ARRAYSIZE = NSPanelEntityState_MediaPlayer_PlaybackState_PlaybackState_ARRAYSIZE; - static inline const ::google::protobuf::EnumDescriptor* PlaybackState_descriptor() { - return NSPanelEntityState_MediaPlayer_PlaybackState_descriptor(); - } - template - static inline const std::string& PlaybackState_Name(T value) { - return NSPanelEntityState_MediaPlayer_PlaybackState_Name(value); - } - static inline bool PlaybackState_Parse(absl::string_view name, PlaybackState* value) { - return NSPanelEntityState_MediaPlayer_PlaybackState_Parse(name, value); - } // accessors ------------------------------------------------------- enum : int { - kNameFieldNumber = 2, - kMediaTitleFieldNumber = 4, - kMediaArtistFieldNumber = 5, - kAlbumArtUrlFieldNumber = 16, - kMediaPlayerIdFieldNumber = 1, - kStateFieldNumber = 3, - kVolumeFieldNumber = 6, - kSourceVolumeFieldNumber = 9, - kIsMutedFieldNumber = 7, - kHasSourceVolumeFieldNumber = 8, - kCanPlayFieldNumber = 10, - kCanPauseFieldNumber = 11, - kCanNextTrackFieldNumber = 12, - kCanPreviousTrackFieldNumber = 13, - kCanSetVolumeFieldNumber = 14, - kCanMuteFieldNumber = 15, - kVolumeStepFieldNumber = 17, + kSourcesFieldNumber = 1, + kCurrentSourceFieldNumber = 2, + kCanSelectFieldNumber = 3, }; - // string name = 2; - void clear_name() ; - const std::string& name() const; - template - void set_name(Arg_&& arg, Args_... args); - std::string* mutable_name(); - PROTOBUF_NODISCARD std::string* release_name(); - void set_allocated_name(std::string* value); - - private: - const std::string& _internal_name() const; - inline PROTOBUF_ALWAYS_INLINE void _internal_set_name( - const std::string& value); - std::string* _internal_mutable_name(); - - public: - // string media_title = 4; - void clear_media_title() ; - const std::string& media_title() const; - template - void set_media_title(Arg_&& arg, Args_... args); - std::string* mutable_media_title(); - PROTOBUF_NODISCARD std::string* release_media_title(); - void set_allocated_media_title(std::string* value); - + // repeated string sources = 1; + int sources_size() const; private: - const std::string& _internal_media_title() const; - inline PROTOBUF_ALWAYS_INLINE void _internal_set_media_title( - const std::string& value); - std::string* _internal_mutable_media_title(); + int _internal_sources_size() const; public: - // string media_artist = 5; - void clear_media_artist() ; - const std::string& media_artist() const; - template - void set_media_artist(Arg_&& arg, Args_... args); - std::string* mutable_media_artist(); - PROTOBUF_NODISCARD std::string* release_media_artist(); - void set_allocated_media_artist(std::string* value); + void clear_sources() ; + const std::string& sources(int index) const; + std::string* mutable_sources(int index); + void set_sources(int index, const std::string& value); + void set_sources(int index, std::string&& value); + void set_sources(int index, const char* value); + void set_sources(int index, const char* value, std::size_t size); + void set_sources(int index, absl::string_view value); + std::string* add_sources(); + void add_sources(const std::string& value); + void add_sources(std::string&& value); + void add_sources(const char* value); + void add_sources(const char* value, std::size_t size); + void add_sources(absl::string_view value); + const ::google::protobuf::RepeatedPtrField& sources() const; + ::google::protobuf::RepeatedPtrField* mutable_sources(); private: - const std::string& _internal_media_artist() const; - inline PROTOBUF_ALWAYS_INLINE void _internal_set_media_artist( - const std::string& value); - std::string* _internal_mutable_media_artist(); + const ::google::protobuf::RepeatedPtrField& _internal_sources() const; + ::google::protobuf::RepeatedPtrField* _internal_mutable_sources(); public: - // string album_art_url = 16; - void clear_album_art_url() ; - const std::string& album_art_url() const; + // string current_source = 2; + void clear_current_source() ; + const std::string& current_source() const; template - void set_album_art_url(Arg_&& arg, Args_... args); - std::string* mutable_album_art_url(); - PROTOBUF_NODISCARD std::string* release_album_art_url(); - void set_allocated_album_art_url(std::string* value); + void set_current_source(Arg_&& arg, Args_... args); + std::string* mutable_current_source(); + PROTOBUF_NODISCARD std::string* release_current_source(); + void set_allocated_current_source(std::string* value); private: - const std::string& _internal_album_art_url() const; - inline PROTOBUF_ALWAYS_INLINE void _internal_set_album_art_url( + const std::string& _internal_current_source() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_current_source( const std::string& value); - std::string* _internal_mutable_album_art_url(); - - public: - // int32 media_player_id = 1; - void clear_media_player_id() ; - ::int32_t media_player_id() const; - void set_media_player_id(::int32_t value); - - private: - ::int32_t _internal_media_player_id() const; - void _internal_set_media_player_id(::int32_t value); - - public: - // .NSPanelEntityState.MediaPlayer.PlaybackState state = 3; - void clear_state() ; - ::NSPanelEntityState_MediaPlayer_PlaybackState state() const; - void set_state(::NSPanelEntityState_MediaPlayer_PlaybackState value); - - private: - ::NSPanelEntityState_MediaPlayer_PlaybackState _internal_state() const; - void _internal_set_state(::NSPanelEntityState_MediaPlayer_PlaybackState value); - - public: - // int32 volume = 6; - void clear_volume() ; - ::int32_t volume() const; - void set_volume(::int32_t value); - - private: - ::int32_t _internal_volume() const; - void _internal_set_volume(::int32_t value); - - public: - // int32 source_volume = 9; - void clear_source_volume() ; - ::int32_t source_volume() const; - void set_source_volume(::int32_t value); - - private: - ::int32_t _internal_source_volume() const; - void _internal_set_source_volume(::int32_t value); - - public: - // bool is_muted = 7; - void clear_is_muted() ; - bool is_muted() const; - void set_is_muted(bool value); - - private: - bool _internal_is_muted() const; - void _internal_set_is_muted(bool value); - - public: - // bool has_source_volume = 8; - void clear_has_source_volume() ; - bool has_source_volume() const; - void set_has_source_volume(bool value); - - private: - bool _internal_has_source_volume() const; - void _internal_set_has_source_volume(bool value); - - public: - // bool can_play = 10; - void clear_can_play() ; - bool can_play() const; - void set_can_play(bool value); - - private: - bool _internal_can_play() const; - void _internal_set_can_play(bool value); - - public: - // bool can_pause = 11; - void clear_can_pause() ; - bool can_pause() const; - void set_can_pause(bool value); - - private: - bool _internal_can_pause() const; - void _internal_set_can_pause(bool value); - - public: - // bool can_next_track = 12; - void clear_can_next_track() ; - bool can_next_track() const; - void set_can_next_track(bool value); - - private: - bool _internal_can_next_track() const; - void _internal_set_can_next_track(bool value); - - public: - // bool can_previous_track = 13; - void clear_can_previous_track() ; - bool can_previous_track() const; - void set_can_previous_track(bool value); - - private: - bool _internal_can_previous_track() const; - void _internal_set_can_previous_track(bool value); - - public: - // bool can_set_volume = 14; - void clear_can_set_volume() ; - bool can_set_volume() const; - void set_can_set_volume(bool value); - - private: - bool _internal_can_set_volume() const; - void _internal_set_can_set_volume(bool value); - - public: - // bool can_mute = 15; - void clear_can_mute() ; - bool can_mute() const; - void set_can_mute(bool value); - - private: - bool _internal_can_mute() const; - void _internal_set_can_mute(bool value); + std::string* _internal_mutable_current_source(); public: - // int32 volume_step = 17; - void clear_volume_step() ; - ::int32_t volume_step() const; - void set_volume_step(::int32_t value); + // bool can_select = 3; + void clear_can_select() ; + bool can_select() const; + void set_can_select(bool value); private: - ::int32_t _internal_volume_step() const; - void _internal_set_volume_step(::int32_t value); + bool _internal_can_select() const; + void _internal_set_can_select(bool value); public: - // @@protoc_insertion_point(class_scope:NSPanelEntityState.MediaPlayer) + // @@protoc_insertion_point(class_scope:NSPanelEntityState.MediaPlayer.SourceSelection) private: class _Internal; friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< - 5, 17, 0, - 95, 2> + 2, 3, 0, + 76, 2> _table_; static constexpr const void* _raw_default_instance_ = - &_NSPanelEntityState_MediaPlayer_default_instance_; + &_NSPanelEntityState_MediaPlayer_SourceSelection_default_instance_; friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -730,24 +555,10 @@ class NSPanelEntityState_MediaPlayer final : public ::google::protobuf::Message ::google::protobuf::Arena* arena); inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena, const Impl_& from, - const NSPanelEntityState_MediaPlayer& from_msg); - ::google::protobuf::internal::ArenaStringPtr name_; - ::google::protobuf::internal::ArenaStringPtr media_title_; - ::google::protobuf::internal::ArenaStringPtr media_artist_; - ::google::protobuf::internal::ArenaStringPtr album_art_url_; - ::int32_t media_player_id_; - int state_; - ::int32_t volume_; - ::int32_t source_volume_; - bool is_muted_; - bool has_source_volume_; - bool can_play_; - bool can_pause_; - bool can_next_track_; - bool can_previous_track_; - bool can_set_volume_; - bool can_mute_; - ::int32_t volume_step_; + const NSPanelEntityState_MediaPlayer_SourceSelection& from_msg); + ::google::protobuf::RepeatedPtrField sources_; + ::google::protobuf::internal::ArenaStringPtr current_source_; + bool can_select_; mutable ::google::protobuf::internal::CachedSize _cached_size_; PROTOBUF_TSAN_DECLARE_MEMBER }; @@ -1183,89 +994,520 @@ class NSPanelEntityState_Thermostat_ThermostatOption final : public ::google::pr // nested types ---------------------------------------------------- using ThermostatOptionValue = NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue; - // accessors ------------------------------------------------------- - enum : int { - kOptionsFieldNumber = 4, - kNameFieldNumber = 1, - kCurrentValueFieldNumber = 2, - kCurrentIconFieldNumber = 3, - }; - // repeated .NSPanelEntityState.Thermostat.ThermostatOption.ThermostatOptionValue options = 4; - int options_size() const; + // accessors ------------------------------------------------------- + enum : int { + kOptionsFieldNumber = 4, + kNameFieldNumber = 1, + kCurrentValueFieldNumber = 2, + kCurrentIconFieldNumber = 3, + }; + // repeated .NSPanelEntityState.Thermostat.ThermostatOption.ThermostatOptionValue options = 4; + int options_size() const; + private: + int _internal_options_size() const; + + public: + void clear_options() ; + ::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue* mutable_options(int index); + ::google::protobuf::RepeatedPtrField<::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue>* mutable_options(); + + private: + const ::google::protobuf::RepeatedPtrField<::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue>& _internal_options() const; + ::google::protobuf::RepeatedPtrField<::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue>* _internal_mutable_options(); + public: + const ::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue& options(int index) const; + ::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue* add_options(); + const ::google::protobuf::RepeatedPtrField<::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue>& options() const; + // string name = 1; + void clear_name() ; + const std::string& name() const; + template + void set_name(Arg_&& arg, Args_... args); + std::string* mutable_name(); + PROTOBUF_NODISCARD std::string* release_name(); + void set_allocated_name(std::string* value); + + private: + const std::string& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name( + const std::string& value); + std::string* _internal_mutable_name(); + + public: + // string current_value = 2; + void clear_current_value() ; + const std::string& current_value() const; + template + void set_current_value(Arg_&& arg, Args_... args); + std::string* mutable_current_value(); + PROTOBUF_NODISCARD std::string* release_current_value(); + void set_allocated_current_value(std::string* value); + + private: + const std::string& _internal_current_value() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_current_value( + const std::string& value); + std::string* _internal_mutable_current_value(); + + public: + // string current_icon = 3; + void clear_current_icon() ; + const std::string& current_icon() const; + template + void set_current_icon(Arg_&& arg, Args_... args); + std::string* mutable_current_icon(); + PROTOBUF_NODISCARD std::string* release_current_icon(); + void set_allocated_current_icon(std::string* value); + + private: + const std::string& _internal_current_icon() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_current_icon( + const std::string& value); + std::string* _internal_mutable_current_icon(); + + public: + // @@protoc_insertion_point(class_scope:NSPanelEntityState.Thermostat.ThermostatOption) + private: + class _Internal; + friend class ::google::protobuf::internal::TcParser; + static const ::google::protobuf::internal::TcParseTable< + 2, 4, 1, + 84, 2> + _table_; + + static constexpr const void* _raw_default_instance_ = + &_NSPanelEntityState_Thermostat_ThermostatOption_default_instance_; + + friend class ::google::protobuf::MessageLite; + friend class ::google::protobuf::Arena; + template + friend class ::google::protobuf::Arena::InternalHelper; + using InternalArenaConstructable_ = void; + using DestructorSkippable_ = void; + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from, + const NSPanelEntityState_Thermostat_ThermostatOption& from_msg); + ::google::protobuf::RepeatedPtrField< ::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue > options_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::internal::ArenaStringPtr current_value_; + ::google::protobuf::internal::ArenaStringPtr current_icon_; + mutable ::google::protobuf::internal::CachedSize _cached_size_; + PROTOBUF_TSAN_DECLARE_MEMBER + }; + union { Impl_ _impl_; }; + friend struct ::TableStruct_protobuf_5fnspanel_5fentity_2eproto; +}; +// ------------------------------------------------------------------- + +class NSPanelEntityState_MediaPlayer final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:NSPanelEntityState.MediaPlayer) */ { + public: + inline NSPanelEntityState_MediaPlayer() : NSPanelEntityState_MediaPlayer(nullptr) {} + ~NSPanelEntityState_MediaPlayer() override; + template + explicit PROTOBUF_CONSTEXPR NSPanelEntityState_MediaPlayer( + ::google::protobuf::internal::ConstantInitialized); + + inline NSPanelEntityState_MediaPlayer(const NSPanelEntityState_MediaPlayer& from) : NSPanelEntityState_MediaPlayer(nullptr, from) {} + inline NSPanelEntityState_MediaPlayer(NSPanelEntityState_MediaPlayer&& from) noexcept + : NSPanelEntityState_MediaPlayer(nullptr, std::move(from)) {} + inline NSPanelEntityState_MediaPlayer& operator=(const NSPanelEntityState_MediaPlayer& from) { + CopyFrom(from); + return *this; + } + inline NSPanelEntityState_MediaPlayer& operator=(NSPanelEntityState_MediaPlayer&& from) noexcept { + if (this == &from) return *this; + if (GetArena() == from.GetArena() +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetArena() != nullptr +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const + ABSL_ATTRIBUTE_LIFETIME_BOUND { + return _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance); + } + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() + ABSL_ATTRIBUTE_LIFETIME_BOUND { + return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); + } + + static const ::google::protobuf::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::google::protobuf::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::google::protobuf::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const NSPanelEntityState_MediaPlayer& default_instance() { + return *internal_default_instance(); + } + static inline const NSPanelEntityState_MediaPlayer* internal_default_instance() { + return reinterpret_cast( + &_NSPanelEntityState_MediaPlayer_default_instance_); + } + static constexpr int kIndexInFileMessages = 5; + friend void swap(NSPanelEntityState_MediaPlayer& a, NSPanelEntityState_MediaPlayer& b) { a.Swap(&b); } + inline void Swap(NSPanelEntityState_MediaPlayer* other) { + if (other == this) return; +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() == other->GetArena()) { +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::google::protobuf::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(NSPanelEntityState_MediaPlayer* other) { + if (other == this) return; + ABSL_DCHECK(GetArena() == other->GetArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + NSPanelEntityState_MediaPlayer* New(::google::protobuf::Arena* arena = nullptr) const final { + return ::google::protobuf::Message::DefaultConstruct(arena); + } + using ::google::protobuf::Message::CopyFrom; + void CopyFrom(const NSPanelEntityState_MediaPlayer& from); + using ::google::protobuf::Message::MergeFrom; + void MergeFrom(const NSPanelEntityState_MediaPlayer& from) { NSPanelEntityState_MediaPlayer::MergeImpl(*this, from); } + + private: + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + + public: + bool IsInitialized() const { + return true; + } + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; + ::size_t ByteSizeLong() const final; + ::uint8_t* _InternalSerialize( + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const { return _impl_._cached_size_.Get(); } + + private: + void SharedCtor(::google::protobuf::Arena* arena); + void SharedDtor(); + void InternalSwap(NSPanelEntityState_MediaPlayer* other); + private: + friend class ::google::protobuf::internal::AnyMetadata; + static ::absl::string_view FullMessageName() { return "NSPanelEntityState.MediaPlayer"; } + + protected: + explicit NSPanelEntityState_MediaPlayer(::google::protobuf::Arena* arena); + NSPanelEntityState_MediaPlayer(::google::protobuf::Arena* arena, const NSPanelEntityState_MediaPlayer& from); + NSPanelEntityState_MediaPlayer(::google::protobuf::Arena* arena, NSPanelEntityState_MediaPlayer&& from) noexcept + : NSPanelEntityState_MediaPlayer(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::Message::ClassData* GetClassData() const final; + + public: + ::google::protobuf::Metadata GetMetadata() const; + // nested types ---------------------------------------------------- + using SourceSelection = NSPanelEntityState_MediaPlayer_SourceSelection; + using PlaybackState = NSPanelEntityState_MediaPlayer_PlaybackState; + static constexpr PlaybackState UNKNOWN = NSPanelEntityState_MediaPlayer_PlaybackState_UNKNOWN; + static constexpr PlaybackState OFF = NSPanelEntityState_MediaPlayer_PlaybackState_OFF; + static constexpr PlaybackState ON = NSPanelEntityState_MediaPlayer_PlaybackState_ON; + static constexpr PlaybackState IDLE = NSPanelEntityState_MediaPlayer_PlaybackState_IDLE; + static constexpr PlaybackState PLAYING = NSPanelEntityState_MediaPlayer_PlaybackState_PLAYING; + static constexpr PlaybackState PAUSED = NSPanelEntityState_MediaPlayer_PlaybackState_PAUSED; + static constexpr PlaybackState BUFFERING = NSPanelEntityState_MediaPlayer_PlaybackState_BUFFERING; + static inline bool PlaybackState_IsValid(int value) { + return NSPanelEntityState_MediaPlayer_PlaybackState_IsValid(value); + } + static constexpr PlaybackState PlaybackState_MIN = NSPanelEntityState_MediaPlayer_PlaybackState_PlaybackState_MIN; + static constexpr PlaybackState PlaybackState_MAX = NSPanelEntityState_MediaPlayer_PlaybackState_PlaybackState_MAX; + static constexpr int PlaybackState_ARRAYSIZE = NSPanelEntityState_MediaPlayer_PlaybackState_PlaybackState_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* PlaybackState_descriptor() { + return NSPanelEntityState_MediaPlayer_PlaybackState_descriptor(); + } + template + static inline const std::string& PlaybackState_Name(T value) { + return NSPanelEntityState_MediaPlayer_PlaybackState_Name(value); + } + static inline bool PlaybackState_Parse(absl::string_view name, PlaybackState* value) { + return NSPanelEntityState_MediaPlayer_PlaybackState_Parse(name, value); + } + + // accessors ------------------------------------------------------- + enum : int { + kNameFieldNumber = 2, + kMediaTitleFieldNumber = 4, + kMediaArtistFieldNumber = 5, + kAlbumArtUrlFieldNumber = 16, + kPlayerSourcesFieldNumber = 18, + kSourcePlayerSourcesFieldNumber = 19, + kMediaPlayerIdFieldNumber = 1, + kStateFieldNumber = 3, + kVolumeFieldNumber = 6, + kSourceVolumeFieldNumber = 9, + kIsMutedFieldNumber = 7, + kHasSourceVolumeFieldNumber = 8, + kCanPlayFieldNumber = 10, + kCanPauseFieldNumber = 11, + kCanNextTrackFieldNumber = 12, + kCanPreviousTrackFieldNumber = 13, + kCanSetVolumeFieldNumber = 14, + kCanMuteFieldNumber = 15, + kVolumeStepFieldNumber = 17, + }; + // string name = 2; + void clear_name() ; + const std::string& name() const; + template + void set_name(Arg_&& arg, Args_... args); + std::string* mutable_name(); + PROTOBUF_NODISCARD std::string* release_name(); + void set_allocated_name(std::string* value); + + private: + const std::string& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name( + const std::string& value); + std::string* _internal_mutable_name(); + + public: + // string media_title = 4; + void clear_media_title() ; + const std::string& media_title() const; + template + void set_media_title(Arg_&& arg, Args_... args); + std::string* mutable_media_title(); + PROTOBUF_NODISCARD std::string* release_media_title(); + void set_allocated_media_title(std::string* value); + + private: + const std::string& _internal_media_title() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_media_title( + const std::string& value); + std::string* _internal_mutable_media_title(); + + public: + // string media_artist = 5; + void clear_media_artist() ; + const std::string& media_artist() const; + template + void set_media_artist(Arg_&& arg, Args_... args); + std::string* mutable_media_artist(); + PROTOBUF_NODISCARD std::string* release_media_artist(); + void set_allocated_media_artist(std::string* value); + + private: + const std::string& _internal_media_artist() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_media_artist( + const std::string& value); + std::string* _internal_mutable_media_artist(); + + public: + // string album_art_url = 16; + void clear_album_art_url() ; + const std::string& album_art_url() const; + template + void set_album_art_url(Arg_&& arg, Args_... args); + std::string* mutable_album_art_url(); + PROTOBUF_NODISCARD std::string* release_album_art_url(); + void set_allocated_album_art_url(std::string* value); + + private: + const std::string& _internal_album_art_url() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_album_art_url( + const std::string& value); + std::string* _internal_mutable_album_art_url(); + + public: + // .NSPanelEntityState.MediaPlayer.SourceSelection player_sources = 18; + bool has_player_sources() const; + void clear_player_sources() ; + const ::NSPanelEntityState_MediaPlayer_SourceSelection& player_sources() const; + PROTOBUF_NODISCARD ::NSPanelEntityState_MediaPlayer_SourceSelection* release_player_sources(); + ::NSPanelEntityState_MediaPlayer_SourceSelection* mutable_player_sources(); + void set_allocated_player_sources(::NSPanelEntityState_MediaPlayer_SourceSelection* value); + void unsafe_arena_set_allocated_player_sources(::NSPanelEntityState_MediaPlayer_SourceSelection* value); + ::NSPanelEntityState_MediaPlayer_SourceSelection* unsafe_arena_release_player_sources(); + + private: + const ::NSPanelEntityState_MediaPlayer_SourceSelection& _internal_player_sources() const; + ::NSPanelEntityState_MediaPlayer_SourceSelection* _internal_mutable_player_sources(); + + public: + // .NSPanelEntityState.MediaPlayer.SourceSelection source_player_sources = 19; + bool has_source_player_sources() const; + void clear_source_player_sources() ; + const ::NSPanelEntityState_MediaPlayer_SourceSelection& source_player_sources() const; + PROTOBUF_NODISCARD ::NSPanelEntityState_MediaPlayer_SourceSelection* release_source_player_sources(); + ::NSPanelEntityState_MediaPlayer_SourceSelection* mutable_source_player_sources(); + void set_allocated_source_player_sources(::NSPanelEntityState_MediaPlayer_SourceSelection* value); + void unsafe_arena_set_allocated_source_player_sources(::NSPanelEntityState_MediaPlayer_SourceSelection* value); + ::NSPanelEntityState_MediaPlayer_SourceSelection* unsafe_arena_release_source_player_sources(); + + private: + const ::NSPanelEntityState_MediaPlayer_SourceSelection& _internal_source_player_sources() const; + ::NSPanelEntityState_MediaPlayer_SourceSelection* _internal_mutable_source_player_sources(); + + public: + // int32 media_player_id = 1; + void clear_media_player_id() ; + ::int32_t media_player_id() const; + void set_media_player_id(::int32_t value); + + private: + ::int32_t _internal_media_player_id() const; + void _internal_set_media_player_id(::int32_t value); + + public: + // .NSPanelEntityState.MediaPlayer.PlaybackState state = 3; + void clear_state() ; + ::NSPanelEntityState_MediaPlayer_PlaybackState state() const; + void set_state(::NSPanelEntityState_MediaPlayer_PlaybackState value); + + private: + ::NSPanelEntityState_MediaPlayer_PlaybackState _internal_state() const; + void _internal_set_state(::NSPanelEntityState_MediaPlayer_PlaybackState value); + + public: + // int32 volume = 6; + void clear_volume() ; + ::int32_t volume() const; + void set_volume(::int32_t value); + + private: + ::int32_t _internal_volume() const; + void _internal_set_volume(::int32_t value); + + public: + // int32 source_volume = 9; + void clear_source_volume() ; + ::int32_t source_volume() const; + void set_source_volume(::int32_t value); + + private: + ::int32_t _internal_source_volume() const; + void _internal_set_source_volume(::int32_t value); + + public: + // bool is_muted = 7; + void clear_is_muted() ; + bool is_muted() const; + void set_is_muted(bool value); + + private: + bool _internal_is_muted() const; + void _internal_set_is_muted(bool value); + + public: + // bool has_source_volume = 8; + void clear_has_source_volume() ; + bool has_source_volume() const; + void set_has_source_volume(bool value); + + private: + bool _internal_has_source_volume() const; + void _internal_set_has_source_volume(bool value); + + public: + // bool can_play = 10; + void clear_can_play() ; + bool can_play() const; + void set_can_play(bool value); + + private: + bool _internal_can_play() const; + void _internal_set_can_play(bool value); + + public: + // bool can_pause = 11; + void clear_can_pause() ; + bool can_pause() const; + void set_can_pause(bool value); + + private: + bool _internal_can_pause() const; + void _internal_set_can_pause(bool value); + + public: + // bool can_next_track = 12; + void clear_can_next_track() ; + bool can_next_track() const; + void set_can_next_track(bool value); + private: - int _internal_options_size() const; + bool _internal_can_next_track() const; + void _internal_set_can_next_track(bool value); public: - void clear_options() ; - ::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue* mutable_options(int index); - ::google::protobuf::RepeatedPtrField<::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue>* mutable_options(); + // bool can_previous_track = 13; + void clear_can_previous_track() ; + bool can_previous_track() const; + void set_can_previous_track(bool value); private: - const ::google::protobuf::RepeatedPtrField<::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue>& _internal_options() const; - ::google::protobuf::RepeatedPtrField<::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue>* _internal_mutable_options(); + bool _internal_can_previous_track() const; + void _internal_set_can_previous_track(bool value); + public: - const ::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue& options(int index) const; - ::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue* add_options(); - const ::google::protobuf::RepeatedPtrField<::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue>& options() const; - // string name = 1; - void clear_name() ; - const std::string& name() const; - template - void set_name(Arg_&& arg, Args_... args); - std::string* mutable_name(); - PROTOBUF_NODISCARD std::string* release_name(); - void set_allocated_name(std::string* value); + // bool can_set_volume = 14; + void clear_can_set_volume() ; + bool can_set_volume() const; + void set_can_set_volume(bool value); private: - const std::string& _internal_name() const; - inline PROTOBUF_ALWAYS_INLINE void _internal_set_name( - const std::string& value); - std::string* _internal_mutable_name(); + bool _internal_can_set_volume() const; + void _internal_set_can_set_volume(bool value); public: - // string current_value = 2; - void clear_current_value() ; - const std::string& current_value() const; - template - void set_current_value(Arg_&& arg, Args_... args); - std::string* mutable_current_value(); - PROTOBUF_NODISCARD std::string* release_current_value(); - void set_allocated_current_value(std::string* value); + // bool can_mute = 15; + void clear_can_mute() ; + bool can_mute() const; + void set_can_mute(bool value); private: - const std::string& _internal_current_value() const; - inline PROTOBUF_ALWAYS_INLINE void _internal_set_current_value( - const std::string& value); - std::string* _internal_mutable_current_value(); + bool _internal_can_mute() const; + void _internal_set_can_mute(bool value); public: - // string current_icon = 3; - void clear_current_icon() ; - const std::string& current_icon() const; - template - void set_current_icon(Arg_&& arg, Args_... args); - std::string* mutable_current_icon(); - PROTOBUF_NODISCARD std::string* release_current_icon(); - void set_allocated_current_icon(std::string* value); + // int32 volume_step = 17; + void clear_volume_step() ; + ::int32_t volume_step() const; + void set_volume_step(::int32_t value); private: - const std::string& _internal_current_icon() const; - inline PROTOBUF_ALWAYS_INLINE void _internal_set_current_icon( - const std::string& value); - std::string* _internal_mutable_current_icon(); + ::int32_t _internal_volume_step() const; + void _internal_set_volume_step(::int32_t value); public: - // @@protoc_insertion_point(class_scope:NSPanelEntityState.Thermostat.ThermostatOption) + // @@protoc_insertion_point(class_scope:NSPanelEntityState.MediaPlayer) private: class _Internal; friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< - 2, 4, 1, - 84, 2> + 5, 19, 2, + 95, 2> _table_; static constexpr const void* _raw_default_instance_ = - &_NSPanelEntityState_Thermostat_ThermostatOption_default_instance_; + &_NSPanelEntityState_MediaPlayer_default_instance_; friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -1280,12 +1522,28 @@ class NSPanelEntityState_Thermostat_ThermostatOption final : public ::google::pr ::google::protobuf::Arena* arena); inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena, const Impl_& from, - const NSPanelEntityState_Thermostat_ThermostatOption& from_msg); - ::google::protobuf::RepeatedPtrField< ::NSPanelEntityState_Thermostat_ThermostatOption_ThermostatOptionValue > options_; - ::google::protobuf::internal::ArenaStringPtr name_; - ::google::protobuf::internal::ArenaStringPtr current_value_; - ::google::protobuf::internal::ArenaStringPtr current_icon_; + const NSPanelEntityState_MediaPlayer& from_msg); + ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::internal::ArenaStringPtr media_title_; + ::google::protobuf::internal::ArenaStringPtr media_artist_; + ::google::protobuf::internal::ArenaStringPtr album_art_url_; + ::NSPanelEntityState_MediaPlayer_SourceSelection* player_sources_; + ::NSPanelEntityState_MediaPlayer_SourceSelection* source_player_sources_; + ::int32_t media_player_id_; + int state_; + ::int32_t volume_; + ::int32_t source_volume_; + bool is_muted_; + bool has_source_volume_; + bool can_play_; + bool can_pause_; + bool can_next_track_; + bool can_previous_track_; + bool can_set_volume_; + bool can_mute_; + ::int32_t volume_step_; PROTOBUF_TSAN_DECLARE_MEMBER }; union { Impl_ _impl_; }; @@ -1611,7 +1869,7 @@ class NSPanelEntityState final : public ::google::protobuf::Message return reinterpret_cast( &_NSPanelEntityState_default_instance_); } - static constexpr int kIndexInFileMessages = 5; + static constexpr int kIndexInFileMessages = 6; friend void swap(NSPanelEntityState& a, NSPanelEntityState& b) { a.Swap(&b); } inline void Swap(NSPanelEntityState* other) { if (other == this) return; @@ -2578,6 +2836,184 @@ NSPanelEntityState_Thermostat::_internal_mutable_options() { // ------------------------------------------------------------------- +// NSPanelEntityState_MediaPlayer_SourceSelection + +// repeated string sources = 1; +inline int NSPanelEntityState_MediaPlayer_SourceSelection::_internal_sources_size() const { + return _internal_sources().size(); +} +inline int NSPanelEntityState_MediaPlayer_SourceSelection::sources_size() const { + return _internal_sources_size(); +} +inline void NSPanelEntityState_MediaPlayer_SourceSelection::clear_sources() { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.sources_.Clear(); +} +inline std::string* NSPanelEntityState_MediaPlayer_SourceSelection::add_sources() + ABSL_ATTRIBUTE_LIFETIME_BOUND { + ::google::protobuf::internal::TSanWrite(&_impl_); + std::string* _s = _internal_mutable_sources()->Add(); + // @@protoc_insertion_point(field_add_mutable:NSPanelEntityState.MediaPlayer.SourceSelection.sources) + return _s; +} +inline const std::string& NSPanelEntityState_MediaPlayer_SourceSelection::sources(int index) const + ABSL_ATTRIBUTE_LIFETIME_BOUND { + // @@protoc_insertion_point(field_get:NSPanelEntityState.MediaPlayer.SourceSelection.sources) + return _internal_sources().Get(index); +} +inline std::string* NSPanelEntityState_MediaPlayer_SourceSelection::mutable_sources(int index) + ABSL_ATTRIBUTE_LIFETIME_BOUND { + // @@protoc_insertion_point(field_mutable:NSPanelEntityState.MediaPlayer.SourceSelection.sources) + return _internal_mutable_sources()->Mutable(index); +} +inline void NSPanelEntityState_MediaPlayer_SourceSelection::set_sources(int index, const std::string& value) { + _internal_mutable_sources()->Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set:NSPanelEntityState.MediaPlayer.SourceSelection.sources) +} +inline void NSPanelEntityState_MediaPlayer_SourceSelection::set_sources(int index, std::string&& value) { + _internal_mutable_sources()->Mutable(index)->assign(std::move(value)); + // @@protoc_insertion_point(field_set:NSPanelEntityState.MediaPlayer.SourceSelection.sources) +} +inline void NSPanelEntityState_MediaPlayer_SourceSelection::set_sources(int index, const char* value) { + ABSL_DCHECK(value != nullptr); + _internal_mutable_sources()->Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:NSPanelEntityState.MediaPlayer.SourceSelection.sources) +} +inline void NSPanelEntityState_MediaPlayer_SourceSelection::set_sources(int index, const char* value, + std::size_t size) { + _internal_mutable_sources()->Mutable(index)->assign( + reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:NSPanelEntityState.MediaPlayer.SourceSelection.sources) +} +inline void NSPanelEntityState_MediaPlayer_SourceSelection::set_sources(int index, absl::string_view value) { + _internal_mutable_sources()->Mutable(index)->assign( + value.data(), value.size()); + // @@protoc_insertion_point(field_set_string_piece:NSPanelEntityState.MediaPlayer.SourceSelection.sources) +} +inline void NSPanelEntityState_MediaPlayer_SourceSelection::add_sources(const std::string& value) { + ::google::protobuf::internal::TSanWrite(&_impl_); + _internal_mutable_sources()->Add()->assign(value); + // @@protoc_insertion_point(field_add:NSPanelEntityState.MediaPlayer.SourceSelection.sources) +} +inline void NSPanelEntityState_MediaPlayer_SourceSelection::add_sources(std::string&& value) { + ::google::protobuf::internal::TSanWrite(&_impl_); + _internal_mutable_sources()->Add(std::move(value)); + // @@protoc_insertion_point(field_add:NSPanelEntityState.MediaPlayer.SourceSelection.sources) +} +inline void NSPanelEntityState_MediaPlayer_SourceSelection::add_sources(const char* value) { + ABSL_DCHECK(value != nullptr); + ::google::protobuf::internal::TSanWrite(&_impl_); + _internal_mutable_sources()->Add()->assign(value); + // @@protoc_insertion_point(field_add_char:NSPanelEntityState.MediaPlayer.SourceSelection.sources) +} +inline void NSPanelEntityState_MediaPlayer_SourceSelection::add_sources(const char* value, std::size_t size) { + ::google::protobuf::internal::TSanWrite(&_impl_); + _internal_mutable_sources()->Add()->assign( + reinterpret_cast(value), size); + // @@protoc_insertion_point(field_add_pointer:NSPanelEntityState.MediaPlayer.SourceSelection.sources) +} +inline void NSPanelEntityState_MediaPlayer_SourceSelection::add_sources(absl::string_view value) { + ::google::protobuf::internal::TSanWrite(&_impl_); + _internal_mutable_sources()->Add()->assign(value.data(), + value.size()); + // @@protoc_insertion_point(field_add_string_piece:NSPanelEntityState.MediaPlayer.SourceSelection.sources) +} +inline const ::google::protobuf::RepeatedPtrField& +NSPanelEntityState_MediaPlayer_SourceSelection::sources() const ABSL_ATTRIBUTE_LIFETIME_BOUND { + // @@protoc_insertion_point(field_list:NSPanelEntityState.MediaPlayer.SourceSelection.sources) + return _internal_sources(); +} +inline ::google::protobuf::RepeatedPtrField* +NSPanelEntityState_MediaPlayer_SourceSelection::mutable_sources() ABSL_ATTRIBUTE_LIFETIME_BOUND { + // @@protoc_insertion_point(field_mutable_list:NSPanelEntityState.MediaPlayer.SourceSelection.sources) + ::google::protobuf::internal::TSanWrite(&_impl_); + return _internal_mutable_sources(); +} +inline const ::google::protobuf::RepeatedPtrField& +NSPanelEntityState_MediaPlayer_SourceSelection::_internal_sources() const { + ::google::protobuf::internal::TSanRead(&_impl_); + return _impl_.sources_; +} +inline ::google::protobuf::RepeatedPtrField* +NSPanelEntityState_MediaPlayer_SourceSelection::_internal_mutable_sources() { + ::google::protobuf::internal::TSanRead(&_impl_); + return &_impl_.sources_; +} + +// string current_source = 2; +inline void NSPanelEntityState_MediaPlayer_SourceSelection::clear_current_source() { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.current_source_.ClearToEmpty(); +} +inline const std::string& NSPanelEntityState_MediaPlayer_SourceSelection::current_source() const + ABSL_ATTRIBUTE_LIFETIME_BOUND { + // @@protoc_insertion_point(field_get:NSPanelEntityState.MediaPlayer.SourceSelection.current_source) + return _internal_current_source(); +} +template +inline PROTOBUF_ALWAYS_INLINE void NSPanelEntityState_MediaPlayer_SourceSelection::set_current_source(Arg_&& arg, + Args_... args) { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.current_source_.Set(static_cast(arg), args..., GetArena()); + // @@protoc_insertion_point(field_set:NSPanelEntityState.MediaPlayer.SourceSelection.current_source) +} +inline std::string* NSPanelEntityState_MediaPlayer_SourceSelection::mutable_current_source() ABSL_ATTRIBUTE_LIFETIME_BOUND { + std::string* _s = _internal_mutable_current_source(); + // @@protoc_insertion_point(field_mutable:NSPanelEntityState.MediaPlayer.SourceSelection.current_source) + return _s; +} +inline const std::string& NSPanelEntityState_MediaPlayer_SourceSelection::_internal_current_source() const { + ::google::protobuf::internal::TSanRead(&_impl_); + return _impl_.current_source_.Get(); +} +inline void NSPanelEntityState_MediaPlayer_SourceSelection::_internal_set_current_source(const std::string& value) { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.current_source_.Set(value, GetArena()); +} +inline std::string* NSPanelEntityState_MediaPlayer_SourceSelection::_internal_mutable_current_source() { + ::google::protobuf::internal::TSanWrite(&_impl_); + return _impl_.current_source_.Mutable( GetArena()); +} +inline std::string* NSPanelEntityState_MediaPlayer_SourceSelection::release_current_source() { + ::google::protobuf::internal::TSanWrite(&_impl_); + // @@protoc_insertion_point(field_release:NSPanelEntityState.MediaPlayer.SourceSelection.current_source) + return _impl_.current_source_.Release(); +} +inline void NSPanelEntityState_MediaPlayer_SourceSelection::set_allocated_current_source(std::string* value) { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.current_source_.SetAllocated(value, GetArena()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (_impl_.current_source_.IsDefault()) { + _impl_.current_source_.Set("", GetArena()); + } + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:NSPanelEntityState.MediaPlayer.SourceSelection.current_source) +} + +// bool can_select = 3; +inline void NSPanelEntityState_MediaPlayer_SourceSelection::clear_can_select() { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.can_select_ = false; +} +inline bool NSPanelEntityState_MediaPlayer_SourceSelection::can_select() const { + // @@protoc_insertion_point(field_get:NSPanelEntityState.MediaPlayer.SourceSelection.can_select) + return _internal_can_select(); +} +inline void NSPanelEntityState_MediaPlayer_SourceSelection::set_can_select(bool value) { + _internal_set_can_select(value); + // @@protoc_insertion_point(field_set:NSPanelEntityState.MediaPlayer.SourceSelection.can_select) +} +inline bool NSPanelEntityState_MediaPlayer_SourceSelection::_internal_can_select() const { + ::google::protobuf::internal::TSanRead(&_impl_); + return _impl_.can_select_; +} +inline void NSPanelEntityState_MediaPlayer_SourceSelection::_internal_set_can_select(bool value) { + ::google::protobuf::internal::TSanWrite(&_impl_); + _impl_.can_select_ = value; +} + +// ------------------------------------------------------------------- + // NSPanelEntityState_MediaPlayer // int32 media_player_id = 1; @@ -3066,6 +3502,198 @@ inline void NSPanelEntityState_MediaPlayer::_internal_set_volume_step(::int32_t _impl_.volume_step_ = value; } +// .NSPanelEntityState.MediaPlayer.SourceSelection player_sources = 18; +inline bool NSPanelEntityState_MediaPlayer::has_player_sources() const { + bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0; + PROTOBUF_ASSUME(!value || _impl_.player_sources_ != nullptr); + return value; +} +inline void NSPanelEntityState_MediaPlayer::clear_player_sources() { + ::google::protobuf::internal::TSanWrite(&_impl_); + if (_impl_.player_sources_ != nullptr) _impl_.player_sources_->Clear(); + _impl_._has_bits_[0] &= ~0x00000001u; +} +inline const ::NSPanelEntityState_MediaPlayer_SourceSelection& NSPanelEntityState_MediaPlayer::_internal_player_sources() const { + ::google::protobuf::internal::TSanRead(&_impl_); + const ::NSPanelEntityState_MediaPlayer_SourceSelection* p = _impl_.player_sources_; + return p != nullptr ? *p : reinterpret_cast(::_NSPanelEntityState_MediaPlayer_SourceSelection_default_instance_); +} +inline const ::NSPanelEntityState_MediaPlayer_SourceSelection& NSPanelEntityState_MediaPlayer::player_sources() const ABSL_ATTRIBUTE_LIFETIME_BOUND { + // @@protoc_insertion_point(field_get:NSPanelEntityState.MediaPlayer.player_sources) + return _internal_player_sources(); +} +inline void NSPanelEntityState_MediaPlayer::unsafe_arena_set_allocated_player_sources(::NSPanelEntityState_MediaPlayer_SourceSelection* value) { + ::google::protobuf::internal::TSanWrite(&_impl_); + if (GetArena() == nullptr) { + delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.player_sources_); + } + _impl_.player_sources_ = reinterpret_cast<::NSPanelEntityState_MediaPlayer_SourceSelection*>(value); + if (value != nullptr) { + _impl_._has_bits_[0] |= 0x00000001u; + } else { + _impl_._has_bits_[0] &= ~0x00000001u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:NSPanelEntityState.MediaPlayer.player_sources) +} +inline ::NSPanelEntityState_MediaPlayer_SourceSelection* NSPanelEntityState_MediaPlayer::release_player_sources() { + ::google::protobuf::internal::TSanWrite(&_impl_); + + _impl_._has_bits_[0] &= ~0x00000001u; + ::NSPanelEntityState_MediaPlayer_SourceSelection* released = _impl_.player_sources_; + _impl_.player_sources_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released); + released = ::google::protobuf::internal::DuplicateIfNonNull(released); + if (GetArena() == nullptr) { + delete old; + } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArena() != nullptr) { + released = ::google::protobuf::internal::DuplicateIfNonNull(released); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return released; +} +inline ::NSPanelEntityState_MediaPlayer_SourceSelection* NSPanelEntityState_MediaPlayer::unsafe_arena_release_player_sources() { + ::google::protobuf::internal::TSanWrite(&_impl_); + // @@protoc_insertion_point(field_release:NSPanelEntityState.MediaPlayer.player_sources) + + _impl_._has_bits_[0] &= ~0x00000001u; + ::NSPanelEntityState_MediaPlayer_SourceSelection* temp = _impl_.player_sources_; + _impl_.player_sources_ = nullptr; + return temp; +} +inline ::NSPanelEntityState_MediaPlayer_SourceSelection* NSPanelEntityState_MediaPlayer::_internal_mutable_player_sources() { + ::google::protobuf::internal::TSanWrite(&_impl_); + if (_impl_.player_sources_ == nullptr) { + auto* p = ::google::protobuf::Message::DefaultConstruct<::NSPanelEntityState_MediaPlayer_SourceSelection>(GetArena()); + _impl_.player_sources_ = reinterpret_cast<::NSPanelEntityState_MediaPlayer_SourceSelection*>(p); + } + return _impl_.player_sources_; +} +inline ::NSPanelEntityState_MediaPlayer_SourceSelection* NSPanelEntityState_MediaPlayer::mutable_player_sources() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000001u; + ::NSPanelEntityState_MediaPlayer_SourceSelection* _msg = _internal_mutable_player_sources(); + // @@protoc_insertion_point(field_mutable:NSPanelEntityState.MediaPlayer.player_sources) + return _msg; +} +inline void NSPanelEntityState_MediaPlayer::set_allocated_player_sources(::NSPanelEntityState_MediaPlayer_SourceSelection* value) { + ::google::protobuf::Arena* message_arena = GetArena(); + ::google::protobuf::internal::TSanWrite(&_impl_); + if (message_arena == nullptr) { + delete (_impl_.player_sources_); + } + + if (value != nullptr) { + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); + if (message_arena != submessage_arena) { + value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); + } + _impl_._has_bits_[0] |= 0x00000001u; + } else { + _impl_._has_bits_[0] &= ~0x00000001u; + } + + _impl_.player_sources_ = reinterpret_cast<::NSPanelEntityState_MediaPlayer_SourceSelection*>(value); + // @@protoc_insertion_point(field_set_allocated:NSPanelEntityState.MediaPlayer.player_sources) +} + +// .NSPanelEntityState.MediaPlayer.SourceSelection source_player_sources = 19; +inline bool NSPanelEntityState_MediaPlayer::has_source_player_sources() const { + bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0; + PROTOBUF_ASSUME(!value || _impl_.source_player_sources_ != nullptr); + return value; +} +inline void NSPanelEntityState_MediaPlayer::clear_source_player_sources() { + ::google::protobuf::internal::TSanWrite(&_impl_); + if (_impl_.source_player_sources_ != nullptr) _impl_.source_player_sources_->Clear(); + _impl_._has_bits_[0] &= ~0x00000002u; +} +inline const ::NSPanelEntityState_MediaPlayer_SourceSelection& NSPanelEntityState_MediaPlayer::_internal_source_player_sources() const { + ::google::protobuf::internal::TSanRead(&_impl_); + const ::NSPanelEntityState_MediaPlayer_SourceSelection* p = _impl_.source_player_sources_; + return p != nullptr ? *p : reinterpret_cast(::_NSPanelEntityState_MediaPlayer_SourceSelection_default_instance_); +} +inline const ::NSPanelEntityState_MediaPlayer_SourceSelection& NSPanelEntityState_MediaPlayer::source_player_sources() const ABSL_ATTRIBUTE_LIFETIME_BOUND { + // @@protoc_insertion_point(field_get:NSPanelEntityState.MediaPlayer.source_player_sources) + return _internal_source_player_sources(); +} +inline void NSPanelEntityState_MediaPlayer::unsafe_arena_set_allocated_source_player_sources(::NSPanelEntityState_MediaPlayer_SourceSelection* value) { + ::google::protobuf::internal::TSanWrite(&_impl_); + if (GetArena() == nullptr) { + delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.source_player_sources_); + } + _impl_.source_player_sources_ = reinterpret_cast<::NSPanelEntityState_MediaPlayer_SourceSelection*>(value); + if (value != nullptr) { + _impl_._has_bits_[0] |= 0x00000002u; + } else { + _impl_._has_bits_[0] &= ~0x00000002u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:NSPanelEntityState.MediaPlayer.source_player_sources) +} +inline ::NSPanelEntityState_MediaPlayer_SourceSelection* NSPanelEntityState_MediaPlayer::release_source_player_sources() { + ::google::protobuf::internal::TSanWrite(&_impl_); + + _impl_._has_bits_[0] &= ~0x00000002u; + ::NSPanelEntityState_MediaPlayer_SourceSelection* released = _impl_.source_player_sources_; + _impl_.source_player_sources_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released); + released = ::google::protobuf::internal::DuplicateIfNonNull(released); + if (GetArena() == nullptr) { + delete old; + } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArena() != nullptr) { + released = ::google::protobuf::internal::DuplicateIfNonNull(released); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return released; +} +inline ::NSPanelEntityState_MediaPlayer_SourceSelection* NSPanelEntityState_MediaPlayer::unsafe_arena_release_source_player_sources() { + ::google::protobuf::internal::TSanWrite(&_impl_); + // @@protoc_insertion_point(field_release:NSPanelEntityState.MediaPlayer.source_player_sources) + + _impl_._has_bits_[0] &= ~0x00000002u; + ::NSPanelEntityState_MediaPlayer_SourceSelection* temp = _impl_.source_player_sources_; + _impl_.source_player_sources_ = nullptr; + return temp; +} +inline ::NSPanelEntityState_MediaPlayer_SourceSelection* NSPanelEntityState_MediaPlayer::_internal_mutable_source_player_sources() { + ::google::protobuf::internal::TSanWrite(&_impl_); + if (_impl_.source_player_sources_ == nullptr) { + auto* p = ::google::protobuf::Message::DefaultConstruct<::NSPanelEntityState_MediaPlayer_SourceSelection>(GetArena()); + _impl_.source_player_sources_ = reinterpret_cast<::NSPanelEntityState_MediaPlayer_SourceSelection*>(p); + } + return _impl_.source_player_sources_; +} +inline ::NSPanelEntityState_MediaPlayer_SourceSelection* NSPanelEntityState_MediaPlayer::mutable_source_player_sources() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000002u; + ::NSPanelEntityState_MediaPlayer_SourceSelection* _msg = _internal_mutable_source_player_sources(); + // @@protoc_insertion_point(field_mutable:NSPanelEntityState.MediaPlayer.source_player_sources) + return _msg; +} +inline void NSPanelEntityState_MediaPlayer::set_allocated_source_player_sources(::NSPanelEntityState_MediaPlayer_SourceSelection* value) { + ::google::protobuf::Arena* message_arena = GetArena(); + ::google::protobuf::internal::TSanWrite(&_impl_); + if (message_arena == nullptr) { + delete (_impl_.source_player_sources_); + } + + if (value != nullptr) { + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); + if (message_arena != submessage_arena) { + value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); + } + _impl_._has_bits_[0] |= 0x00000002u; + } else { + _impl_._has_bits_[0] &= ~0x00000002u; + } + + _impl_.source_player_sources_ = reinterpret_cast<::NSPanelEntityState_MediaPlayer_SourceSelection*>(value); + // @@protoc_insertion_point(field_set_allocated:NSPanelEntityState.MediaPlayer.source_player_sources) +} + // ------------------------------------------------------------------- // NSPanelEntityState diff --git a/docker/MQTTManager/tests/media_player_test.cpp b/docker/MQTTManager/tests/media_player_test.cpp index 293ee95c..381f46b0 100644 --- a/docker/MQTTManager/tests/media_player_test.cpp +++ b/docker/MQTTManager/tests/media_player_test.cpp @@ -2,8 +2,11 @@ #include #include #include +#include #include #include +#include +#include using nspm_test::django_media_player_data; using nspm_test::home_assistant_service_calls; @@ -166,6 +169,165 @@ TEST_F(HomeAssistantMediaPlayerTest, commands_for_other_media_players_are_ignore EXPECT_TRUE(home_assistant_service_calls().empty()); } +// Unsigned, as nlohmann::json parses it from Home Assistant. A signed int in the attributes is ignored. +constexpr uint32_t SELECT_SOURCE = HomeAssistantSourcePlayer::feature_select_source; + +std::vector sources_of(const NSPanelEntityState_MediaPlayer_SourceSelection &selection) { + return std::vector(selection.sources().begin(), selection.sources().end()); +} + +TEST_F(HomeAssistantMediaPlayerTest, player_sources_are_published_from_home_assistant) { + receive_state("playing", {{"source_list", nlohmann::json::array({"TV", "Radio", "Spotify"})}, {"source", "Radio"}, {"supported_features", SELECT_SOURCE}}); + + auto state = last_published_state(); + ASSERT_TRUE(state.has_value()); + EXPECT_EQ(sources_of(state->player_sources()), std::vector({"TV", "Radio", "Spotify"})); + EXPECT_EQ(state->player_sources().current_source(), "Radio"); + EXPECT_TRUE(state->player_sources().can_select()); + EXPECT_FALSE(state->has_source_player_sources()); +} + +TEST_F(HomeAssistantMediaPlayerTest, sources_can_not_be_selected_without_the_select_source_feature) { + receive_state("playing", {{"source_list", nlohmann::json::array({"TV", "Radio"})}, {"source", "TV"}}); + + auto state = last_published_state(); + ASSERT_TRUE(state.has_value()); + EXPECT_EQ(sources_of(state->player_sources()), std::vector({"TV", "Radio"})); + EXPECT_FALSE(state->player_sources().can_select()); + + send_panel_command([](auto *command) { command->set_select_player_source("Radio"); }); + + EXPECT_TRUE(home_assistant_service_calls().empty()); +} + +TEST_F(HomeAssistantMediaPlayerTest, panel_source_selection_calls_home_assistant) { + receive_state("playing", {{"source_list", nlohmann::json::array({"TV", "Radio"})}, {"source", "TV"}, {"supported_features", SELECT_SOURCE}}); + + send_panel_command([](auto *command) { command->set_select_player_source("Radio"); }); + + auto calls = home_assistant_service_calls(); + ASSERT_EQ(calls.size(), 1); + EXPECT_EQ(calls[0], nlohmann::json({{"type", "call_service"}, {"domain", "media_player"}, {"service", "select_source"}, {"target", {{"entity_id", "media_player.lounge"}}}, {"service_data", {{"source", "Radio"}}}})); +} + +TEST_F(HomeAssistantMediaPlayerTest, selecting_an_unknown_source_is_ignored) { + receive_state("playing", {{"source_list", nlohmann::json::array({"TV", "Radio"})}, {"supported_features", SELECT_SOURCE}}); + + send_panel_command([](auto *command) { command->set_select_player_source("Vinyl"); }); + + EXPECT_TRUE(home_assistant_service_calls().empty()); +} + +TEST_F(HomeAssistantMediaPlayerTest, source_lists_are_limited_for_the_panel) { + nlohmann::json source_list = nlohmann::json::array(); + for (size_t i = 0; i < MediaPlayerEntity::max_sources + 5; i++) { + source_list.push_back("Input " + std::to_string(i)); + } + // 63 bytes then a 2 byte UTF-8 character: cutting at 64 bytes would split it, so the name is cut before it. + const std::string long_name = std::string(MediaPlayerEntity::max_source_name_length - 1, 'a') + "\xC3\xA9"; + const std::string short_name = std::string(MediaPlayerEntity::max_source_name_length - 1, 'a'); + source_list[0] = long_name; + receive_state("playing", {{"source_list", source_list}, {"source", long_name}, {"supported_features", SELECT_SOURCE}}); + + auto state = last_published_state(); + ASSERT_TRUE(state.has_value()); + ASSERT_EQ(state->player_sources().sources_size(), static_cast(MediaPlayerEntity::max_sources)); + EXPECT_EQ(state->player_sources().sources(0), short_name); + EXPECT_EQ(state->player_sources().current_source(), short_name); + EXPECT_EQ(state->player_sources().sources(MediaPlayerEntity::max_sources - 1), "Input " + std::to_string(MediaPlayerEntity::max_sources - 1)); + + // The panel only knows the shortened name, Home Assistant gets the full one. + send_panel_command([&](auto *command) { command->set_select_player_source(short_name); }); + auto calls = home_assistant_service_calls(); + ASSERT_EQ(calls.size(), 1); + EXPECT_EQ(calls[0]["service_data"]["source"], long_name); + + // Sources past the limit were never shown on the panel, so they can not be selected. + send_panel_command([&](auto *command) { command->set_select_player_source("Input " + std::to_string(MediaPlayerEntity::max_sources)); }); + EXPECT_TRUE(home_assistant_service_calls().empty()); +} + +TEST_F(HomeAssistantMediaPlayerTest, removed_entity_has_no_sources) { + receive_state("playing", {{"source_list", nlohmann::json::array({"TV", "Radio"})}, {"supported_features", SELECT_SOURCE}}); + + nlohmann::json removed = home_assistant_state_changed("media_player.lounge", ""); + removed["event"]["data"]["new_state"] = nullptr; + HomeAssistantManager::test_process_event(removed); + + auto state = last_published_state(); + ASSERT_TRUE(state.has_value()); + EXPECT_EQ(state->player_sources().sources_size(), 0); + EXPECT_FALSE(state->player_sources().can_select()); +} + +// A media player fed by a source player, as with a multi-room audio matrix: the player reports the +// entity ID of its current source player in a state attribute. +class HomeAssistantSourcePlayerSourcesTest : public HomeAssistantMediaPlayerTest { +protected: + void SetUp() override { + nspm_test::SendCaptureTest::SetUp(); + nlohmann::json entity_data = django_media_player_data("media_player.lounge"); + entity_data["source_volume_strategy"] = "source_entity"; + entity_data["source_entity_attribute"] = "source_entity"; + row = std::make_unique("media_player", "Lounge zone", entity_data); + player = std::make_unique(row->id); + } + + void receive_source_state(const std::string &entity_id, const nlohmann::json &attributes) { + auto event = home_assistant_state_changed(entity_id, "playing", attributes); + HomeAssistantManager::test_process_event(event); + } +}; + +TEST_F(HomeAssistantSourcePlayerSourcesTest, source_player_sources_are_published) { + receive_state("playing", {{"source_entity", "media_player.streamer"}}); + receive_source_state("media_player.streamer", {{"source_list", nlohmann::json::array({"Spotify", "AirPlay"})}, {"source", "AirPlay"}, {"supported_features", SELECT_SOURCE}}); + + auto state = last_published_state(); + ASSERT_TRUE(state.has_value()); + ASSERT_TRUE(state->has_source_player_sources()); + EXPECT_EQ(sources_of(state->source_player_sources()), std::vector({"Spotify", "AirPlay"})); + EXPECT_EQ(state->source_player_sources().current_source(), "AirPlay"); + EXPECT_TRUE(state->source_player_sources().can_select()); +} + +TEST_F(HomeAssistantSourcePlayerSourcesTest, panel_source_player_selection_calls_the_source_player) { + receive_state("playing", {{"source_entity", "media_player.streamer"}}); + receive_source_state("media_player.streamer", {{"source_list", nlohmann::json::array({"Spotify", "AirPlay"})}, {"supported_features", SELECT_SOURCE}}); + home_assistant_service_calls(); + + send_panel_command([](auto *command) { command->set_select_source_player_source("Spotify"); }); + + auto calls = home_assistant_service_calls(); + ASSERT_EQ(calls.size(), 1); + EXPECT_EQ(calls[0], nlohmann::json({{"type", "call_service"}, {"domain", "media_player"}, {"service", "select_source"}, {"target", {{"entity_id", "media_player.streamer"}}}, {"service_data", {{"source", "Spotify"}}}})); +} + +TEST_F(HomeAssistantSourcePlayerSourcesTest, switching_source_player_drops_the_previous_sources) { + receive_state("playing", {{"source_entity", "media_player.streamer"}}); + receive_source_state("media_player.streamer", {{"source_list", nlohmann::json::array({"Spotify", "AirPlay"})}, {"supported_features", SELECT_SOURCE}}); + last_published_state(); + + receive_state("playing", {{"source_entity", "media_player.turntable"}}); + + auto state = last_published_state(); + ASSERT_TRUE(state.has_value()); + ASSERT_TRUE(state->has_source_player_sources()); + EXPECT_EQ(state->source_player_sources().sources_size(), 0); + + // A late event from the previous source player must not bring its sources back. + receive_source_state("media_player.streamer", {{"source_list", nlohmann::json::array({"Spotify"})}, {"supported_features", SELECT_SOURCE}}); + EXPECT_FALSE(last_published_state().has_value()); +} + +TEST_F(HomeAssistantMediaPlayerTest, source_player_selection_without_a_source_player_is_ignored) { + receive_state("playing", {{"source_list", nlohmann::json::array({"TV"})}, {"supported_features", SELECT_SOURCE}}); + + send_panel_command([](auto *command) { command->set_select_source_player_source("TV"); }); + + EXPECT_TRUE(home_assistant_service_calls().empty()); +} + TEST(MediaPlayerConfig, invalid_volume_step_falls_back_to_five) { for (auto volume_step : {0, 101}) { SCOPED_TRACE(volume_step); diff --git a/docker/protobuf/protobuf_nspanel.proto b/docker/protobuf/protobuf_nspanel.proto index 78fc5a4a..79934353 100644 --- a/docker/protobuf/protobuf_nspanel.proto +++ b/docker/protobuf/protobuf_nspanel.proto @@ -267,6 +267,9 @@ message NSPanelMQTTManagerCommand { int32 source_volume = 6; // Volume in 0-100% bool has_muted = 7; bool muted = 8; + // Name of a source to select, as sent in the state's source lists. Empty means no change. + string select_player_source = 9; + string select_source_player_source = 10; } oneof CommandData { diff --git a/docker/protobuf/protobuf_nspanel_entity.proto b/docker/protobuf/protobuf_nspanel_entity.proto index 0cbe4322..5c04867a 100644 --- a/docker/protobuf/protobuf_nspanel_entity.proto +++ b/docker/protobuf/protobuf_nspanel_entity.proto @@ -84,6 +84,21 @@ message NSPanelEntityState { // How much one volume up/down press changes the volume and source volume, in 1-100%. int32 volume_step = 17; + + message SourceSelection { + repeated string sources = 1; + // Empty if unknown. Not every player reports its current source, and it + // is not always one of the listed sources. + string current_source = 2; + bool can_select = 3; + } + + // Sources (inputs) of this player. + SourceSelection player_sources = 18; + // Sources of the source player feeding this player, if it has one (see + // source_volume). Unset when there is no source player. Changes completely + // when the player switches to another source. + SourceSelection source_player_sources = 19; } oneof entity { diff --git a/protobuf_firmware/protobuf_nspanel.pb-c.c b/protobuf_firmware/protobuf_nspanel.pb-c.c index 700dd92f..ee780b2b 100644 --- a/protobuf_firmware/protobuf_nspanel.pb-c.c +++ b/protobuf_firmware/protobuf_nspanel.pb-c.c @@ -2628,7 +2628,7 @@ const ProtobufCEnumDescriptor nspanel_mqttmanager_command__media_player_command_ nspanel_mqttmanager_command__media_player_command__playback_action__value_ranges, NULL,NULL,NULL,NULL /* reserved[1234] */ }; -static const ProtobufCFieldDescriptor nspanel_mqttmanager_command__media_player_command__field_descriptors[8] = +static const ProtobufCFieldDescriptor nspanel_mqttmanager_command__media_player_command__field_descriptors[10] = { { "media_player_id", @@ -2726,6 +2726,30 @@ static const ProtobufCFieldDescriptor nspanel_mqttmanager_command__media_player_ 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, + { + "select_player_source", + 9, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(NSPanelMQTTManagerCommand__MediaPlayerCommand, select_player_source), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "select_source_player_source", + 10, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(NSPanelMQTTManagerCommand__MediaPlayerCommand, select_source_player_source), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned nspanel_mqttmanager_command__media_player_command__field_indices_by_name[] = { 6, /* field[6] = has_muted */ @@ -2734,13 +2758,15 @@ static const unsigned nspanel_mqttmanager_command__media_player_command__field_i 0, /* field[0] = media_player_id */ 7, /* field[7] = muted */ 1, /* field[1] = playback_action */ + 8, /* field[8] = select_player_source */ + 9, /* field[9] = select_source_player_source */ 5, /* field[5] = source_volume */ 3, /* field[3] = volume */ }; static const ProtobufCIntRange nspanel_mqttmanager_command__media_player_command__number_ranges[1 + 1] = { { 1, 0 }, - { 0, 8 } + { 0, 10 } }; const ProtobufCMessageDescriptor nspanel_mqttmanager_command__media_player_command__descriptor = { @@ -2750,7 +2776,7 @@ const ProtobufCMessageDescriptor nspanel_mqttmanager_command__media_player_comma "NSPanelMQTTManagerCommand__MediaPlayerCommand", "", sizeof(NSPanelMQTTManagerCommand__MediaPlayerCommand), - 8, + 10, nspanel_mqttmanager_command__media_player_command__field_descriptors, nspanel_mqttmanager_command__media_player_command__field_indices_by_name, 1, nspanel_mqttmanager_command__media_player_command__number_ranges, diff --git a/protobuf_firmware/protobuf_nspanel.pb-c.h b/protobuf_firmware/protobuf_nspanel.pb-c.h index 54158df8..e290525b 100644 --- a/protobuf_firmware/protobuf_nspanel.pb-c.h +++ b/protobuf_firmware/protobuf_nspanel.pb-c.h @@ -461,10 +461,15 @@ struct NSPanelMQTTManagerCommand__MediaPlayerCommand int32_t source_volume; protobuf_c_boolean has_muted; protobuf_c_boolean muted; + /* + * Name of a source to select, as sent in the state's source lists. Empty means no change. + */ + char *select_player_source; + char *select_source_player_source; }; #define NSPANEL_MQTTMANAGER_COMMAND__MEDIA_PLAYER_COMMAND__INIT \ { PROTOBUF_C_MESSAGE_INIT (&nspanel_mqttmanager_command__media_player_command__descriptor) \ - , 0, NSPANEL_MQTTMANAGER_COMMAND__MEDIA_PLAYER_COMMAND__PLAYBACK_ACTION__NONE, 0, 0, 0, 0, 0, 0 } + , 0, NSPANEL_MQTTMANAGER_COMMAND__MEDIA_PLAYER_COMMAND__PLAYBACK_ACTION__NONE, 0, 0, 0, 0, 0, 0, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string } typedef enum { diff --git a/protobuf_firmware/protobuf_nspanel_entity.pb-c.c b/protobuf_firmware/protobuf_nspanel_entity.pb-c.c index 4776cf1e..19b23dd8 100644 --- a/protobuf_firmware/protobuf_nspanel_entity.pb-c.c +++ b/protobuf_firmware/protobuf_nspanel_entity.pb-c.c @@ -31,6 +31,12 @@ void nspanel_entity_state__thermostat__init static const NSPanelEntityState__Thermostat init_value = NSPANEL_ENTITY_STATE__THERMOSTAT__INIT; *message = init_value; } +void nspanel_entity_state__media_player__source_selection__init + (NSPanelEntityState__MediaPlayer__SourceSelection *message) +{ + static const NSPanelEntityState__MediaPlayer__SourceSelection init_value = NSPANEL_ENTITY_STATE__MEDIA_PLAYER__SOURCE_SELECTION__INIT; + *message = init_value; +} void nspanel_entity_state__media_player__init (NSPanelEntityState__MediaPlayer *message) { @@ -509,6 +515,70 @@ const ProtobufCMessageDescriptor nspanel_entity_state__thermostat__descriptor = (ProtobufCMessageInit) nspanel_entity_state__thermostat__init, NULL,NULL,NULL /* reserved[123] */ }; +static const ProtobufCFieldDescriptor nspanel_entity_state__media_player__source_selection__field_descriptors[3] = +{ + { + "sources", + 1, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_STRING, + offsetof(NSPanelEntityState__MediaPlayer__SourceSelection, n_sources), + offsetof(NSPanelEntityState__MediaPlayer__SourceSelection, sources), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "current_source", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(NSPanelEntityState__MediaPlayer__SourceSelection, current_source), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "can_select", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BOOL, + 0, /* quantifier_offset */ + offsetof(NSPanelEntityState__MediaPlayer__SourceSelection, can_select), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned nspanel_entity_state__media_player__source_selection__field_indices_by_name[] = { + 2, /* field[2] = can_select */ + 1, /* field[1] = current_source */ + 0, /* field[0] = sources */ +}; +static const ProtobufCIntRange nspanel_entity_state__media_player__source_selection__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 3 } +}; +const ProtobufCMessageDescriptor nspanel_entity_state__media_player__source_selection__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "NSPanelEntityState.MediaPlayer.SourceSelection", + "SourceSelection", + "NSPanelEntityState__MediaPlayer__SourceSelection", + "", + sizeof(NSPanelEntityState__MediaPlayer__SourceSelection), + 3, + nspanel_entity_state__media_player__source_selection__field_descriptors, + nspanel_entity_state__media_player__source_selection__field_indices_by_name, + 1, nspanel_entity_state__media_player__source_selection__number_ranges, + (ProtobufCMessageInit) nspanel_entity_state__media_player__source_selection__init, + NULL,NULL,NULL /* reserved[123] */ +}; static const ProtobufCEnumValue nspanel_entity_state__media_player__playback_state__enum_values_by_number[7] = { { "UNKNOWN", "NSPANEL_ENTITY_STATE__MEDIA_PLAYER__PLAYBACK_STATE__UNKNOWN", 0 }, @@ -547,7 +617,7 @@ const ProtobufCEnumDescriptor nspanel_entity_state__media_player__playback_state nspanel_entity_state__media_player__playback_state__value_ranges, NULL,NULL,NULL,NULL /* reserved[1234] */ }; -static const ProtobufCFieldDescriptor nspanel_entity_state__media_player__field_descriptors[16] = +static const ProtobufCFieldDescriptor nspanel_entity_state__media_player__field_descriptors[19] = { { "media_player_id", @@ -741,6 +811,42 @@ static const ProtobufCFieldDescriptor nspanel_entity_state__media_player__field_ 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, + { + "volume_step", + 17, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(NSPanelEntityState__MediaPlayer, volume_step), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "player_sources", + 18, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(NSPanelEntityState__MediaPlayer, player_sources), + &nspanel_entity_state__media_player__source_selection__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "source_player_sources", + 19, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(NSPanelEntityState__MediaPlayer, source_player_sources), + &nspanel_entity_state__media_player__source_selection__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned nspanel_entity_state__media_player__field_indices_by_name[] = { 15, /* field[15] = album_art_url */ @@ -756,14 +862,17 @@ static const unsigned nspanel_entity_state__media_player__field_indices_by_name[ 0, /* field[0] = media_player_id */ 3, /* field[3] = media_title */ 1, /* field[1] = name */ + 17, /* field[17] = player_sources */ + 18, /* field[18] = source_player_sources */ 8, /* field[8] = source_volume */ 2, /* field[2] = state */ 5, /* field[5] = volume */ + 16, /* field[16] = volume_step */ }; static const ProtobufCIntRange nspanel_entity_state__media_player__number_ranges[1 + 1] = { { 1, 0 }, - { 0, 16 } + { 0, 19 } }; const ProtobufCMessageDescriptor nspanel_entity_state__media_player__descriptor = { @@ -773,7 +882,7 @@ const ProtobufCMessageDescriptor nspanel_entity_state__media_player__descriptor "NSPanelEntityState__MediaPlayer", "", sizeof(NSPanelEntityState__MediaPlayer), - 16, + 19, nspanel_entity_state__media_player__field_descriptors, nspanel_entity_state__media_player__field_indices_by_name, 1, nspanel_entity_state__media_player__number_ranges, diff --git a/protobuf_firmware/protobuf_nspanel_entity.pb-c.h b/protobuf_firmware/protobuf_nspanel_entity.pb-c.h index 4d2d1925..09242909 100644 --- a/protobuf_firmware/protobuf_nspanel_entity.pb-c.h +++ b/protobuf_firmware/protobuf_nspanel_entity.pb-c.h @@ -21,6 +21,7 @@ typedef struct NSPanelEntityState__Thermostat NSPanelEntityState__Thermostat; typedef struct NSPanelEntityState__Thermostat__ThermostatOption NSPanelEntityState__Thermostat__ThermostatOption; typedef struct NSPanelEntityState__Thermostat__ThermostatOption__ThermostatOptionValue NSPanelEntityState__Thermostat__ThermostatOption__ThermostatOptionValue; typedef struct NSPanelEntityState__MediaPlayer NSPanelEntityState__MediaPlayer; +typedef struct NSPanelEntityState__MediaPlayer__SourceSelection NSPanelEntityState__MediaPlayer__SourceSelection; /* --- enums --- */ @@ -104,6 +105,23 @@ struct NSPanelEntityState__Thermostat , 0, (char *)protobuf_c_empty_string, 0, 0, 0, 0, 0,NULL } +struct NSPanelEntityState__MediaPlayer__SourceSelection +{ + ProtobufCMessage base; + size_t n_sources; + char **sources; + /* + * Empty if unknown. Not every player reports its current source, and it + * is not always one of the listed sources. + */ + char *current_source; + protobuf_c_boolean can_select; +}; +#define NSPANEL_ENTITY_STATE__MEDIA_PLAYER__SOURCE_SELECTION__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&nspanel_entity_state__media_player__source_selection__descriptor) \ + , 0,NULL, (char *)protobuf_c_empty_string, 0 } + + struct NSPanelEntityState__MediaPlayer { ProtobufCMessage base; @@ -138,10 +156,24 @@ struct NSPanelEntityState__MediaPlayer * the panel can compare it with the last URL to tell when to fetch again. */ char *album_art_url; + /* + * How much one volume up/down press changes the volume and source volume, in 1-100%. + */ + int32_t volume_step; + /* + * Sources (inputs) of this player. + */ + NSPanelEntityState__MediaPlayer__SourceSelection *player_sources; + /* + * Sources of the source player feeding this player, if it has one (see + * source_volume). Unset when there is no source player. Changes completely + * when the player switches to another source. + */ + NSPanelEntityState__MediaPlayer__SourceSelection *source_player_sources; }; #define NSPANEL_ENTITY_STATE__MEDIA_PLAYER__INIT \ { PROTOBUF_C_MESSAGE_INIT (&nspanel_entity_state__media_player__descriptor) \ - , 0, (char *)protobuf_c_empty_string, NSPANEL_ENTITY_STATE__MEDIA_PLAYER__PLAYBACK_STATE__UNKNOWN, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (char *)protobuf_c_empty_string } + , 0, (char *)protobuf_c_empty_string, NSPANEL_ENTITY_STATE__MEDIA_PLAYER__PLAYBACK_STATE__UNKNOWN, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (char *)protobuf_c_empty_string, 0, NULL, NULL } typedef enum { @@ -179,6 +211,9 @@ void nspanel_entity_state__thermostat__thermostat_option__init /* NSPanelEntityState__Thermostat methods */ void nspanel_entity_state__thermostat__init (NSPanelEntityState__Thermostat *message); +/* NSPanelEntityState__MediaPlayer__SourceSelection methods */ +void nspanel_entity_state__media_player__source_selection__init + (NSPanelEntityState__MediaPlayer__SourceSelection *message); /* NSPanelEntityState__MediaPlayer methods */ void nspanel_entity_state__media_player__init (NSPanelEntityState__MediaPlayer *message); @@ -215,6 +250,9 @@ typedef void (*NSPanelEntityState__Thermostat__ThermostatOption_Closure) typedef void (*NSPanelEntityState__Thermostat_Closure) (const NSPanelEntityState__Thermostat *message, void *closure_data); +typedef void (*NSPanelEntityState__MediaPlayer__SourceSelection_Closure) + (const NSPanelEntityState__MediaPlayer__SourceSelection *message, + void *closure_data); typedef void (*NSPanelEntityState__MediaPlayer_Closure) (const NSPanelEntityState__MediaPlayer *message, void *closure_data); @@ -234,6 +272,7 @@ extern const ProtobufCMessageDescriptor nspanel_entity_state__thermostat__descri extern const ProtobufCMessageDescriptor nspanel_entity_state__thermostat__thermostat_option__descriptor; extern const ProtobufCMessageDescriptor nspanel_entity_state__thermostat__thermostat_option__thermostat_option_value__descriptor; extern const ProtobufCMessageDescriptor nspanel_entity_state__media_player__descriptor; +extern const ProtobufCMessageDescriptor nspanel_entity_state__media_player__source_selection__descriptor; extern const ProtobufCEnumDescriptor nspanel_entity_state__media_player__playback_state__descriptor; PROTOBUF_C__END_DECLS