diff options
39 files changed, 1205 insertions, 172 deletions
diff --git a/src/appMain/hmi_capabilities.json b/src/appMain/hmi_capabilities.json index f2a8093665..8adb8da4b7 100755 --- a/src/appMain/hmi_capabilities.json +++ b/src/appMain/hmi_capabilities.json @@ -337,20 +337,106 @@ "dialNumberEnabled": true }, "videoStreamingCapability": { - "preferredResolution": { + "preferredResolution": { + "resolutionWidth": 800, + "resolutionHeight": 380 + }, + "maxBitrate": 20000, + "supportedFormats": [ + { + "protocol": "RAW", + "codec": "H264" + }, + { + "protocol": "RTP", + "codec": "H264" + }, + { + "protocol": "RTSP", + "codec": "Theora" + }, + { + "protocol": "RTMP", + "codec": "VP8" + }, + { + "protocol": "WEBM", + "codec": "VP9" + } + ], + "hapticSpatialDataSupported": true, + "diagonalScreenSize": 8, + "pixelPerInch": 96, + "scale": 1, + "preferredFPS": 15, + "additionalVideoStreamingCapabilities": [ + { + "preferredResolution": + { "resolutionWidth": 800, - "resolutionHeight": 350 + "resolutionHeight": 380 + }, + "hapticSpatialDataSupported": true, + "scale": 1, + "diagonalScreenSize": 8 + }, + { + "preferredResolution": + { + "resolutionWidth": 320, + "resolutionHeight": 200 + }, + "hapticSpatialDataSupported": false, + "diagonalScreenSize": 3 }, - "maxBitrate": 10000, - "supportedFormats": [{ - "protocol": "RAW", - "codec": "H264" - }], - "hapticSpatialDataSupported": false, - "diagonalScreenSize": 8, - "pixelPerInch": 117, - "scale": 1, - "preferredFPS": 15 + { + "preferredResolution": + { + "resolutionWidth": 480, + "resolutionHeight": 320 + }, + "hapticSpatialDataSupported": true, + "diagonalScreenSize": 5 + }, + { + "preferredResolution": + { + "resolutionWidth": 400, + "resolutionHeight": 380 + }, + "hapticSpatialDataSupported": true, + "diagonalScreenSize": 4 + }, + { + "preferredResolution": + { + "resolutionWidth": 800, + "resolutionHeight": 240 + }, + "hapticSpatialDataSupported": true, + "diagonalScreenSize": 4 + }, + { + "preferredResolution": + { + "resolutionWidth": 800, + "resolutionHeight": 380 + }, + "hapticSpatialDataSupported": true, + "scale": 1.5, + "diagonalScreenSize": 5 + }, + { + "preferredResolution": + { + "resolutionWidth": 800, + "resolutionHeight": 380 + }, + "hapticSpatialDataSupported": true, + "scale": 2, + "diagonalScreenSize": 4 + } + ] }, "driverDistractionCapability": { "menuLength": 10, diff --git a/src/appMain/sdl_preloaded_pt.json b/src/appMain/sdl_preloaded_pt.json index 1debd2918d..88720afcce 100644 --- a/src/appMain/sdl_preloaded_pt.json +++ b/src/appMain/sdl_preloaded_pt.json @@ -189,6 +189,13 @@ "NONE" ] }, + "OnAppCapabilityUpdated": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, "OnAppInterfaceUnregistered": { "hmi_levels": [ "BACKGROUND", diff --git a/src/components/application_manager/include/application_manager/application.h b/src/components/application_manager/include/application_manager/application.h index 4a3dc473ed..bc966cd00c 100644 --- a/src/components/application_manager/include/application_manager/application.h +++ b/src/components/application_manager/include/application_manager/application.h @@ -529,6 +529,7 @@ class Application : public virtual InitialApplicationData, * @brief The StreamingState enum defines current streaming state */ enum class StreamingState { kStopped, kStarted, kSuspended }; + enum ApplicationRegisterState { kRegistered = 0, kWaitingForRegistration }; Application() : is_greyed_out_(false) {} @@ -669,8 +670,10 @@ class Application : public virtual InitialApplicationData, /** * @brief Wakes up streaming process for application * @param service_type Type of streaming service + * @param timer_len The amount of time in ms the timer will wait */ - virtual void WakeUpStreaming(protocol_handler::ServiceType service_type) = 0; + virtual void WakeUpStreaming(protocol_handler::ServiceType service_type, + uint32_t timer_len = 0) = 0; virtual bool is_voice_communication_supported() const = 0; virtual void set_voice_communication_supported( diff --git a/src/components/application_manager/include/application_manager/application_impl.h b/src/components/application_manager/include/application_manager/application_impl.h index 6d60699a4e..21e45b4515 100644 --- a/src/components/application_manager/include/application_manager/application_impl.h +++ b/src/components/application_manager/include/application_manager/application_impl.h @@ -142,7 +142,8 @@ class ApplicationImpl : public virtual Application, void StopStreamingForce(protocol_handler::ServiceType service_type); void StopStreaming(protocol_handler::ServiceType service_type); void SuspendStreaming(protocol_handler::ServiceType service_type); - void WakeUpStreaming(protocol_handler::ServiceType service_type); + void WakeUpStreaming(protocol_handler::ServiceType service_type, + uint32_t timer_len = 0); virtual bool is_voice_communication_supported() const; virtual void set_voice_communication_supported(bool option); diff --git a/src/components/application_manager/include/application_manager/application_manager_impl.h b/src/components/application_manager/include/application_manager/application_manager_impl.h index 41f7c4f189..9191a06c6b 100644 --- a/src/components/application_manager/include/application_manager/application_manager_impl.h +++ b/src/components/application_manager/include/application_manager/application_manager_impl.h @@ -873,6 +873,10 @@ class ApplicationManagerImpl void OnAppStreaming(uint32_t app_id, protocol_handler::ServiceType service_type, + bool state) OVERRIDE; + + void OnAppStreaming(uint32_t app_id, + protocol_handler::ServiceType service_type, const Application::StreamingState new_state) OVERRIDE; mobile_api::HMILevel::eType GetDefaultHmiLevel( diff --git a/src/components/application_manager/include/application_manager/smart_object_keys.h b/src/components/application_manager/include/application_manager/smart_object_keys.h index b23e429925..0b5217e918 100644 --- a/src/components/application_manager/include/application_manager/smart_object_keys.h +++ b/src/components/application_manager/include/application_manager/smart_object_keys.h @@ -230,6 +230,8 @@ extern const char* policy_type; extern const char* property; extern const char* displays; extern const char* seat_location; +extern const char* app_capability; +extern const char* app_capability_type; // PutFile extern const char* sync_file_name; @@ -486,6 +488,7 @@ extern const char* const haptic_spatial_data_supported; extern const char* const diagonal_screen_size; extern const char* const pixel_per_inch; extern const char* const scale; +extern const char* const additional_video_streaming_capabilities; extern const char* const haptic_rect_data; extern const char* const rect; extern const char* const x; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/CMakeLists.txt b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/CMakeLists.txt index a03b34d742..67a178893c 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/CMakeLists.txt +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/CMakeLists.txt @@ -28,7 +28,10 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -include_directories(include) +include_directories( + include + ${CMAKE_CURRENT_SOURCE_DIR}/include/sdl_rpc_plugin +) set (COMMANDS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/commands diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/bc_on_app_capability_updated_notification.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/bc_on_app_capability_updated_notification.h new file mode 100644 index 0000000000..f4883cecaf --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/bc_on_app_capability_updated_notification.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_HMI_BC_ON_APP_CAPABILITY_UPDATED_NOTIFICATION_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_HMI_BC_ON_APP_CAPABILITY_UPDATED_NOTIFICATION_H_ + +#include "application_manager/commands/notification_to_hmi.h" + +namespace sdl_rpc_plugin { +namespace app_mngr = application_manager; + +namespace commands { + +class BCOnAppCapabilityUpdatedNotification + : public app_mngr::commands::NotificationToHMI { + public: + BCOnAppCapabilityUpdatedNotification( + const app_mngr::commands::MessageSharedPtr& message, + app_mngr::ApplicationManager& application_manager, + app_mngr::rpc_service::RPCService& rpc_service, + app_mngr::HMICapabilities& hmi_capabilities, + policy::PolicyHandlerInterface& policy_handle); + + ~BCOnAppCapabilityUpdatedNotification() OVERRIDE; + + void Run() OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(BCOnAppCapabilityUpdatedNotification); +}; + +} // namespace commands +} // namespace sdl_rpc_plugin + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_HMI_BC_ON_APP_CAPABILITY_UPDATED_NOTIFICATION_H_ diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/on_bc_system_capability_updated_notification_from_hmi.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/on_bc_system_capability_updated_notification_from_hmi.h index 39b5c3aee3..41b5846a46 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/on_bc_system_capability_updated_notification_from_hmi.h +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/on_bc_system_capability_updated_notification_from_hmi.h @@ -87,6 +87,18 @@ class OnBCSystemCapabilityUpdatedNotificationFromHMI ProcessSystemDisplayCapabilitiesResult ProcessSystemDisplayCapabilities( const smart_objects::SmartObject& display_capabilities); + /** + * @brief ProcessVideoStreamingCapability processes provided video + * streaming capabilities according to its structure + * @param system_capability capabilities to process + * @return true if video streaming capabilities have been processed + * properly, otherwise returns false + */ + bool ProcessVideoStreamingCapability( + const smart_objects::SmartObject& system_capability); + + void RemoveAppIdFromNotification(); + DISALLOW_COPY_AND_ASSIGN(OnBCSystemCapabilityUpdatedNotificationFromHMI); }; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/on_app_capability_updated_notification.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/on_app_capability_updated_notification.h new file mode 100644 index 0000000000..64e16f57be --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/on_app_capability_updated_notification.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2020, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_MOBILE_ON_APP_CAPABILITY_UPDATED_NOTIFICATION_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_MOBILE_ON_APP_CAPABILITY_UPDATED_NOTIFICATION_H_ + +#include "application_manager/commands/command_notification_from_mobile_impl.h" +#include "utils/macro.h" + +namespace sdl_rpc_plugin { +namespace commands { +namespace mobile { + +namespace app_mngr = application_manager; +class OnAppCapabilityUpdatedNotification + : public app_mngr::commands::CommandNotificationFromMobileImpl { + public: + /** + * @brief OnAppPermissionChangedNotification class constructor + * @param message Incoming SmartObject message + * @param application_manager Reference to the instance of the Application + *Manager + * @param rpc_service Reference to the instance of the RPCService + * @param hmi_capabilities Reference to the instance of the HMICapabilities + * @param policy_handle Reference to the instance of the PolicyHandler + **/ + OnAppCapabilityUpdatedNotification( + const app_mngr::commands::MessageSharedPtr& message, + app_mngr::ApplicationManager& application_manager, + app_mngr::rpc_service::RPCService& rpc_service, + app_mngr::HMICapabilities& hmi_capabilities, + policy::PolicyHandlerInterface& policy_handle); + + /** + * @brief OnAppPermissionChangedNotification class destructor + **/ + ~OnAppCapabilityUpdatedNotification() OVERRIDE; + + /** + * @brief Execute command + **/ + void Run() OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(OnAppCapabilityUpdatedNotification); +}; + +} // namespace mobile +} // namespace commands +} // namespace sdl_rpc_plugin + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_MOBILE_ON_APP_CAPABILITY_UPDATED_NOTIFICATION_H_ diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/bc_on_app_capability_updated_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/bc_on_app_capability_updated_notification.cc new file mode 100644 index 0000000000..a5f2137136 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/bc_on_app_capability_updated_notification.cc @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "sdl_rpc_plugin/commands/hmi/bc_on_app_capability_updated_notification.h" + +namespace sdl_rpc_plugin { +namespace app_mngr = application_manager; + +namespace commands { + +SDL_CREATE_LOG_VARIABLE("Commands") + +BCOnAppCapabilityUpdatedNotification::BCOnAppCapabilityUpdatedNotification( + const application_manager::commands::MessageSharedPtr& message, + application_manager::ApplicationManager& application_manager, + application_manager::rpc_service::RPCService& rpc_service, + application_manager::HMICapabilities& hmi_capabilities, + policy::PolicyHandlerInterface& policy_handle) + : NotificationToHMI(message, + application_manager, + rpc_service, + hmi_capabilities, + policy_handle) {} + +BCOnAppCapabilityUpdatedNotification::~BCOnAppCapabilityUpdatedNotification() {} + +void BCOnAppCapabilityUpdatedNotification::Run() { + SDL_LOG_AUTO_TRACE(); + + SendNotification(); +} + +} // namespace commands +} // namespace sdl_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_bc_system_capability_updated_notification_from_hmi.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_bc_system_capability_updated_notification_from_hmi.cc index 7ba330caa8..56ff20ecc5 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_bc_system_capability_updated_notification_from_hmi.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_bc_system_capability_updated_notification_from_hmi.cc @@ -34,6 +34,7 @@ #include "application_manager/display_capabilities_builder.h" #include "application_manager/message_helper.h" +#include "extensions/system_capability_app_extension.h" #include "interfaces/HMI_API.h" #include "interfaces/MOBILE_API.h" @@ -84,11 +85,7 @@ OnBCSystemCapabilityUpdatedNotificationFromHMI:: SDL_LOG_DEBUG("Updating display capabilities for app " << app_id); app->set_display_capabilities(display_capabilities); - // Remove app_id from notification to mobile - (*message_)[strings::params][strings::connection_key] = - (*message_)[strings::msg_params][strings::app_id]; - (*message_)[strings::msg_params].erase(strings::app_id); - + RemoveAppIdFromNotification(); auto& builder = app->display_capabilities_builder(); if (builder.IsWaitingForWindowCapabilities(display_capabilities)) { SDL_LOG_DEBUG("Application is waiting for capabilities"); @@ -99,6 +96,54 @@ OnBCSystemCapabilityUpdatedNotificationFromHMI:: return ProcessSystemDisplayCapabilitiesResult::SUCCESS; } +void OnBCSystemCapabilityUpdatedNotificationFromHMI:: + RemoveAppIdFromNotification() { + (*message_)[strings::params][strings::connection_key] = + (*message_)[strings::msg_params][strings::app_id]; + (*message_)[strings::msg_params].erase(strings::app_id); +} + +bool OnBCSystemCapabilityUpdatedNotificationFromHMI:: + ProcessVideoStreamingCapability( + const smart_objects::SmartObject& system_capability) { + if (!system_capability.keyExists(strings::video_streaming_capability)) { + SDL_LOG_WARN( + "VideoStreamingCapability is absent in the notification. " + "Notification Will be ignored"); + return false; + } + if (!(*message_)[strings::msg_params].keyExists(strings::app_id)) { + SDL_LOG_WARN( + "Notification doesn't contain an application id. Will " + "be ignored"); + return false; + } + + const auto app_id = + (*message_)[strings::msg_params][strings::app_id].asUInt(); + + auto app = application_manager_.application(app_id); + if (!app) { + SDL_LOG_WARN("Application with app_id: " + << app_id + << " isn't registered. Notification will be ignored"); + return false; + } + + auto& system_capability_extension = + SystemCapabilityAppExtension::ExtractExtension(*app); + + if (!system_capability_extension.IsSubscribedTo( + mobile_apis::SystemCapabilityType::VIDEO_STREAMING)) { + SDL_LOG_WARN("The Application with app_id: " + << app_id + << " isn't subscribed to the VIDEO_STREAMING system " + "capability type. Notification will be ignored"); + return false; + } + return true; +} + void OnBCSystemCapabilityUpdatedNotificationFromHMI::Run() { SDL_LOG_AUTO_TRACE(); @@ -109,7 +154,11 @@ void OnBCSystemCapabilityUpdatedNotificationFromHMI::Run() { const auto& system_capability = (*message_)[strings::msg_params][strings::system_capability]; - switch (system_capability[strings::system_capability_type].asInt()) { + const auto system_capability_type = + static_cast<mobile_apis::SystemCapabilityType::eType>( + system_capability[strings::system_capability_type].asInt()); + + switch (system_capability_type) { case mobile_apis::SystemCapabilityType::DISPLAYS: { if (system_capability.keyExists(strings::display_capabilities)) { const auto result = ProcessSystemDisplayCapabilities( @@ -135,6 +184,14 @@ void OnBCSystemCapabilityUpdatedNotificationFromHMI::Run() { } break; } + case mobile_apis::SystemCapabilityType::VIDEO_STREAMING: { + if (!ProcessVideoStreamingCapability(system_capability)) { + return; + } + RemoveAppIdFromNotification(); + break; + } + default: { SDL_LOG_ERROR("Unknown system capability type received"); } } SendNotificationToMobile(message_); diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_system_capability_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_system_capability_request.cc index 1cd4806f7e..64eae885a8 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_system_capability_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_system_capability_request.cc @@ -204,10 +204,12 @@ void GetSystemCapabilityRequest::Run() { auto& ext = SystemCapabilityAppExtension::ExtractExtension(*app); if ((*message_)[app_mngr::strings::msg_params][strings::subscribe] .asBool() == true) { - SDL_LOG_DEBUG("Subscribe to system capability: " << response_type); + SDL_LOG_DEBUG("Subscribe to system capability: " + << response_type << " for app_id: " << app->app_id()); ext.SubscribeTo(response_type); } else { - SDL_LOG_DEBUG("Unsubscribe from system capability: " << response_type); + SDL_LOG_DEBUG("Unsubscribe from system capability: " + << response_type << " for app_id: " << app->app_id()); ext.UnsubscribeFrom(response_type); } } diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_app_capability_updated_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_app_capability_updated_notification.cc new file mode 100644 index 0000000000..c04b10cbd4 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_app_capability_updated_notification.cc @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2020, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "sdl_rpc_plugin/commands/mobile/on_app_capability_updated_notification.h" + +namespace sdl_rpc_plugin { + +namespace commands { +namespace mobile { + +SDL_CREATE_LOG_VARIABLE("Commands") + +OnAppCapabilityUpdatedNotification::OnAppCapabilityUpdatedNotification( + const application_manager::commands::MessageSharedPtr& message, + app_mngr::ApplicationManager& application_manager, + app_mngr::rpc_service::RPCService& rpc_service, + app_mngr::HMICapabilities& hmi_capabilities, + policy::PolicyHandlerInterface& policy_handle) + : CommandNotificationFromMobileImpl(message, + application_manager, + rpc_service, + hmi_capabilities, + policy_handle) {} + +OnAppCapabilityUpdatedNotification::~OnAppCapabilityUpdatedNotification() {} + +void OnAppCapabilityUpdatedNotification::Run() { + SDL_LOG_AUTO_TRACE(); + app_mngr::ApplicationSharedPtr app = + application_manager_.application(connection_key()); + + if (!app) { + SDL_LOG_ERROR("No application associated with session key"); + return; + } + + (*message_)[app_mngr::strings::msg_params][app_mngr::strings::app_id] = + app->app_id(); + + SendNotificationToHMI( + hmi_apis::FunctionID::BasicCommunication_OnAppCapabilityUpdated); +} + +} // namespace mobile +} // namespace commands +} // namespace sdl_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_system_capability_updated_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_system_capability_updated_notification.cc index 850aa64b5f..1f15170ffe 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_system_capability_updated_notification.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_system_capability_updated_notification.cc @@ -81,15 +81,10 @@ void OnSystemCapabilityUpdatedNotification::Run() { } break; } - case mobile_apis::SystemCapabilityType::VIDEO_STREAMING: - if (hmi_capabilities_.video_streaming_capability()) { - msg_params[strings::system_capability] - [strings::video_streaming_capability] = - *hmi_capabilities_.video_streaming_capability(); - } else { - return; - } - break; + case mobile_apis::SystemCapabilityType::VIDEO_STREAMING: { + SendNotification(); + return; + } case mobile_apis::SystemCapabilityType::APP_SERVICES: { auto all_services = application_manager_.GetAppServiceManager().GetAllServiceRecords(); @@ -200,48 +195,51 @@ void OnSystemCapabilityUpdatedNotification::Run() { for (; applications.end() != app_it; ++app_it) { const ApplicationSharedPtr app = *app_it; - if (system_capability_type == - mobile_apis::SystemCapabilityType::REMOTE_CONTROL && - !app->is_remote_control_supported()) { - SDL_LOG_WARN( - "App with connection key: " - << app->app_id() - << " was subcribed to REMOTE_CONTROL system capabilities, but " - "does not have RC permissions. Unsubscribing"); - auto& ext = SystemCapabilityAppExtension::ExtractExtension(*app); - ext.UnsubscribeFrom(system_capability_type); - continue; - } - if (mobile_apis::SystemCapabilityType::DISPLAYS == system_capability_type) { - SDL_LOG_DEBUG("Using common display capabilities"); - auto capabilities = hmi_capabilities_.system_display_capabilities(); - - auto& builder = app->display_capabilities_builder(); - if (app->is_resuming() && builder.IsWindowResumptionNeeded()) { - SDL_LOG_DEBUG("Application " - << app->app_id() - << " is resuming. Providing cached capabilities"); - auto display_caps = builder.display_capabilities(); - capabilities = display_caps; - } else if (app->display_capabilities()) { - SDL_LOG_DEBUG("Application " << app->app_id() - << " has specific display capabilities"); - const WindowID window_id = - msg_params[strings::system_capability] - [strings::display_capabilities][0] - [strings::window_capabilities][0][strings::window_id] - .asInt(); - capabilities = app->display_capabilities(window_id); - } + switch (system_capability_type) { + case mobile_apis::SystemCapabilityType::REMOTE_CONTROL: { + if (!app->is_remote_control_supported()) { + SDL_LOG_WARN("App with connection key: " + << app->app_id() + << " was subcribed to REMOTE_CONTROL system " + "capabilities, but " + "does not have RC permissions. Unsubscribing"); + auto& ext = SystemCapabilityAppExtension::ExtractExtension(*app); + ext.UnsubscribeFrom(system_capability_type); + } + } break; + + case mobile_apis::SystemCapabilityType::DISPLAYS: { + SDL_LOG_DEBUG("Using common display capabilities"); + auto capabilities = hmi_capabilities_.system_display_capabilities(); + auto& builder = app->display_capabilities_builder(); + if (app->is_resuming() && builder.IsWindowResumptionNeeded()) { + SDL_LOG_DEBUG("Application " + << app->app_id() + << " is resuming. Providing cached capabilities"); + auto display_caps = builder.display_capabilities(); + capabilities = display_caps; + } else if (app->display_capabilities()) { + SDL_LOG_DEBUG("Application " << app->app_id() + << " has specific display capabilities"); + const WindowID window_id = + msg_params[strings::system_capability] + [strings::display_capabilities][0] + [strings::window_capabilities][0][strings::window_id] + .asInt(); + capabilities = app->display_capabilities(window_id); + } - if (!capabilities) { - SDL_LOG_WARN("No available display capabilities for sending. Skipping"); - continue; - } + if (!capabilities) { + SDL_LOG_WARN( + "No available display capabilities for sending. Skipping"); + continue; + } - msg_params[strings::system_capability][strings::display_capabilities] = - *capabilities; + msg_params[strings::system_capability][strings::display_capabilities] = + *capabilities; + } break; + default: { SDL_LOG_ERROR("Unknown system capability type"); } } SDL_LOG_INFO("Sending OnSystemCapabilityUpdated " << capability_type_string diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/hmi_command_factory.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/hmi_command_factory.cc index 570a4ce12e..2727c89673 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/hmi_command_factory.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/hmi_command_factory.cc @@ -173,6 +173,7 @@ #include "sdl_rpc_plugin/commands/hmi/basic_communication_on_awake_sdl.h" #include "sdl_rpc_plugin/commands/hmi/basic_communication_system_request.h" #include "sdl_rpc_plugin/commands/hmi/basic_communication_system_response.h" +#include "sdl_rpc_plugin/commands/hmi/bc_on_app_capability_updated_notification.h" #include "sdl_rpc_plugin/commands/hmi/dial_number_request.h" #include "sdl_rpc_plugin/commands/hmi/dial_number_response.h" #include "sdl_rpc_plugin/commands/hmi/navi_alert_maneuver_request.h" @@ -942,6 +943,10 @@ CommandCreator& HMICommandFactory::get_creator_factory( case hmi_apis::FunctionID::UI_OnSubtleAlertPressed: { return factory.GetCreator<commands::OnUISubtleAlertPressedNotification>(); } + case hmi_apis::FunctionID::BasicCommunication_OnAppCapabilityUpdated: { + return factory + .GetCreator<commands::BCOnAppCapabilityUpdatedNotification>(); + } default: { return factory.GetCreator<InvalidCommand>(); } } } diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/mobile_command_factory.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/mobile_command_factory.cc index 9809a11a81..0a8c342448 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/mobile_command_factory.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/mobile_command_factory.cc @@ -76,6 +76,7 @@ #include "sdl_rpc_plugin/commands/mobile/get_way_points_response.h" #include "sdl_rpc_plugin/commands/mobile/list_files_request.h" #include "sdl_rpc_plugin/commands/mobile/list_files_response.h" +#include "sdl_rpc_plugin/commands/mobile/on_app_capability_updated_notification.h" #include "sdl_rpc_plugin/commands/mobile/on_app_interface_unregistered_notification.h" #include "sdl_rpc_plugin/commands/mobile/on_audio_pass_thru_notification.h" #include "sdl_rpc_plugin/commands/mobile/on_button_event_notification.h" @@ -496,6 +497,10 @@ CommandCreator& MobileCommandFactory::get_notification_from_mobile_creator( return factory .GetCreator<commands::OnWayPointChangeNotificationFromMobile>(); } + case mobile_apis::FunctionID::OnAppCapabilityUpdatedID: { + return factory + .GetCreator<commands::mobile::OnAppCapabilityUpdatedNotification>(); + } default: {} } return factory.GetCreator<InvalidCommand>(); @@ -548,10 +553,12 @@ bool MobileCommandFactory::IsAbleToProcess( const int32_t function_id, const application_manager::commands::Command::CommandSource message_source) const { + SDL_LOG_AUTO_TRACE(); auto id = static_cast<mobile_apis::FunctionID::eType>(function_id); return get_command_creator(id, mobile_apis::messageType::INVALID_ENUM) .CanBeCreated() || - get_notification_creator(id).CanBeCreated(); + get_notification_creator(id).CanBeCreated() || + get_notification_from_mobile_creator(id).CanBeCreated(); } CommandSharedPtr MobileCommandFactory::CreateCommand( diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/bc_on_app_capability_updated_notification_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/bc_on_app_capability_updated_notification_test.cc new file mode 100644 index 0000000000..2d875a2680 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/bc_on_app_capability_updated_notification_test.cc @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2020, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "hmi/bc_on_app_capability_updated_notification.h" + +#include "application_manager/commands/commands_test.h" +#include "gtest/gtest.h" +#include "sdl_rpc_plugin/extensions/system_capability_app_extension.h" +#include "sdl_rpc_plugin/sdl_rpc_plugin.h" + +namespace test { +namespace components { +namespace commands_test { +namespace hmi_commands_test { +namespace bc_on_app_capability_updated_notification_test { + +using sdl_rpc_plugin::commands::BCOnAppCapabilityUpdatedNotification; +using ::testing::_; + +typedef std::shared_ptr<BCOnAppCapabilityUpdatedNotification> + BCOnAppCapabilityUpdatedNotificationPtr; + +namespace strings = application_manager::strings; +namespace { +const uint32_t kConnectionKey = 1u; +} // namespace + +MATCHER_P(CheckAppCapability, app_capability, "") { + return app_capability == (*arg)[strings::msg_params][strings::app_capability]; +} + +class BCOnAppCapabilityUpdatedNotificationTest + : public CommandsTest<CommandsTestMocks::kIsNice> { + protected: + void SetUp() OVERRIDE { + message_ = CreateMessage(); + (*message_)[strings::params][strings::connection_key] = kConnectionKey; + command_ = CreateCommand<BCOnAppCapabilityUpdatedNotification>(message_); + mock_app_ = CreateMockApp(); + } + + BCOnAppCapabilityUpdatedNotificationPtr command_; + MockAppPtr mock_app_; + MessageSharedPtr message_; +}; + +TEST_F(BCOnAppCapabilityUpdatedNotificationTest, Run_SendMessageToHMI_SUCCESS) { + smart_objects::SmartObject app_capability = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + app_capability[strings::app_capability_type] = + mobile_apis::AppCapabilityType::VIDEO_STREAMING; + app_capability[strings::video_streaming_capability] = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + FillVideoStreamingCapability( + app_capability[strings::video_streaming_capability]); + + (*message_)[strings::msg_params][strings::app_capability] = app_capability; + + ASSERT_TRUE(command_->Init()); + + EXPECT_CALL(mock_rpc_service_, + SendMessageToHMI(CheckAppCapability(app_capability))); + command_->Run(); +} + +} // namespace bc_on_app_capability_updated_notification_test +} // namespace hmi_commands_test +} // namespace commands_test +} // namespace components +} // namespace test diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/on_bc_system_capability_updated_notification_from_hmi_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/on_bc_system_capability_updated_notification_from_hmi_test.cc index ae2a544cc9..1316952a92 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/on_bc_system_capability_updated_notification_from_hmi_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/on_bc_system_capability_updated_notification_from_hmi_test.cc @@ -33,6 +33,8 @@ #include "hmi/on_bc_system_capability_updated_notification_from_hmi.h" #include "application_manager/commands/commands_test.h" +#include "sdl_rpc_plugin/extensions/system_capability_app_extension.h" + #include "gtest/gtest.h" namespace test { @@ -47,8 +49,10 @@ using ::testing::Return; typedef std::shared_ptr<OnBCSystemCapabilityUpdatedNotificationFromHMI> OnBCSystemCapabilityUpdatedNotificationFromHMIPtr; +typedef mobile_apis::SystemCapabilityType::eType SystemCapabilityType; namespace strings = application_manager::strings; + namespace { const uint32_t kAppId = 1u; } // namespace @@ -61,11 +65,30 @@ MATCHER(CheckMessageToMobile, "") { (*arg)[strings::params][strings::function_id].asInt()); const bool app_id_exist = (*arg)[strings::msg_params].keyExists(strings::app_id); - bool is_connection_key_correct = true; - if ((*arg)[strings::msg_params].keyExists(strings::connection_key)) { - is_connection_key_correct = - (*arg)[strings::params][strings::connection_key] == kAppId; - } + const bool is_connection_key_correct = [](arg_type arg) { + if ((*arg)[strings::msg_params].keyExists(strings::connection_key)) { + return (*arg)[strings::params][strings::connection_key] == kAppId; + } + return false; + }; + + return is_function_id_matched && app_id_exist && is_connection_key_correct; +} + +MATCHER(CheckMessageToMobileWithoutAppId, "") { + const auto function_id = mobile_apis::FunctionID::OnSystemCapabilityUpdatedID; + + const bool is_function_id_matched = + function_id == static_cast<am::mobile_api::FunctionID::eType>( + (*arg)[strings::params][strings::function_id].asInt()); + const bool app_id_exist = + (*arg)[strings::msg_params].keyExists(strings::app_id); + const bool is_connection_key_correct = [](arg_type arg) { + if ((*arg)[strings::msg_params].keyExists(strings::connection_key)) { + return (*arg)[strings::params][strings::connection_key] == kAppId; + } + return false; + }; return is_function_id_matched && !app_id_exist && is_connection_key_correct; } @@ -73,6 +96,27 @@ MATCHER_P(CheckDisplayCapabilitiesNotChanged, display_capability, "") { return display_capability == arg; } +MATCHER_P2(CheckVideoStreamingCapability, + system_capability_type, + video_streaming_capability, + "") { + const mobile_apis::SystemCapabilityType::eType received_sys_cap_type = + static_cast<mobile_apis::SystemCapabilityType::eType>( + (*arg)[strings::msg_params][strings::system_capability] + [strings::system_capability_type] + .asInt()); + + const bool system_capability_type_matched = + received_sys_cap_type == system_capability_type; + + const bool video_capability_matched = + video_streaming_capability == + (*arg)[strings::msg_params][strings::system_capability] + [strings::video_streaming_capability]; + + return system_capability_type_matched && video_capability_matched; +} + class OnBCSystemCapabilityUpdatedNotificationFromHMITest : public CommandsTest<CommandsTestMocks::kIsNice> { protected: @@ -105,7 +149,7 @@ TEST_F( EXPECT_CALL( mock_rpc_service_, ManageMobileCommand( - CheckMessageToMobile(), + CheckMessageToMobileWithoutAppId(), ::application_manager::commands::Command::CommandSource::SOURCE_SDL)) .WillOnce(Return(true)); @@ -130,7 +174,7 @@ TEST_F(OnBCSystemCapabilityUpdatedNotificationFromHMITest, TEST_F( OnBCSystemCapabilityUpdatedNotificationFromHMITest, - Run_AppRegisteredWithPresentedAppIdInMessage_SetDisplayCapabilitiesToApp_SendMessageToMobile) { + Run_AppRegisteredWithPresentedAppIdInMessage_SetDisplayCapabilitiesToAppAndAppIdIsErasedFromMessage_SendMessageToMobile) { (*message_)[am::strings::msg_params][strings::system_capability] [am::strings::system_capability_type] = mobile_apis::SystemCapabilityType::DISPLAYS; @@ -147,7 +191,7 @@ TEST_F( EXPECT_CALL( mock_rpc_service_, ManageMobileCommand( - CheckMessageToMobile(), + CheckMessageToMobileWithoutAppId(), ::application_manager::commands::Command::CommandSource::SOURCE_SDL)) .WillOnce(Return(true)); @@ -155,6 +199,149 @@ TEST_F( command_->Run(); } +TEST_F( + OnBCSystemCapabilityUpdatedNotificationFromHMITest, + Run_SysCapTypeVideoStreaming_CapabilityIsAbsent_DoesntSetInHMICapabilities) { + smart_objects::SmartObject system_capability = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + system_capability[strings::system_capability_type] = + mobile_apis::SystemCapabilityType::VIDEO_STREAMING; + + ASSERT_TRUE(command_->Init()); + EXPECT_CALL(mock_hmi_capabilities_, set_video_streaming_capability(_)) + .Times(0); + command_->Run(); +} + +TEST_F(OnBCSystemCapabilityUpdatedNotificationFromHMITest, + Run_VideoStreamingCapability_AppIdIsAbsent_NotificationIgnored) { + (*message_)[am::strings::msg_params][strings::system_capability] + [am::strings::system_capability_type] = + mobile_apis::SystemCapabilityType::VIDEO_STREAMING; + + EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _)).Times(0); + + ASSERT_TRUE(command_->Init()); + command_->Run(); +} + +TEST_F(OnBCSystemCapabilityUpdatedNotificationFromHMITest, + Run_VideoStreamingCapability_AppNotRegistered_NotificationIgnored) { + (*message_)[am::strings::msg_params][strings::system_capability] + [am::strings::system_capability_type] = + mobile_apis::SystemCapabilityType::VIDEO_STREAMING; + (*message_)[am::strings::msg_params][strings::app_id] = kAppId; + + ApplicationSharedPtr app; // Empty application shared pointer + + ON_CALL(app_mngr_, application(kAppId)).WillByDefault(Return(app)); + EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _)).Times(0); + + ASSERT_TRUE(command_->Init()); + command_->Run(); +} + +TEST_F(OnBCSystemCapabilityUpdatedNotificationFromHMITest, + Run_VideoStreamingCapability_AppNotSubsribed_NotificationIgnored) { + (*message_)[am::strings::msg_params][strings::system_capability] + [am::strings::system_capability_type] = + mobile_apis::SystemCapabilityType::VIDEO_STREAMING; + (*message_)[am::strings::msg_params][strings::app_id] = kAppId; + + sdl_rpc_plugin::SDLRPCPlugin sdl_rpc_plugin; + + // By default system capability extension is not subsribed to the + // VIDEO_STREAMING + auto system_capability_app_extension = + std::make_shared<sdl_rpc_plugin::SystemCapabilityAppExtension>( + sdl_rpc_plugin, *mock_app_); + + ON_CALL(*mock_app_, + QueryInterface(sdl_rpc_plugin::SystemCapabilityAppExtension:: + SystemCapabilityAppExtensionUID)) + .WillByDefault(Return(system_capability_app_extension)); + ON_CALL(app_mngr_, application(kAppId)).WillByDefault(Return(mock_app_)); + + EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _)).Times(0); + + ASSERT_TRUE(command_->Init()); + command_->Run(); +} + +TEST_F( + OnBCSystemCapabilityUpdatedNotificationFromHMITest, + Run_VideoStreamingCapability_AppIsSubsribed_VideoCapabilityIsAbsent_NotificationIgnored) { + const mobile_apis::SystemCapabilityType::eType system_capability_type = + mobile_apis::SystemCapabilityType::VIDEO_STREAMING; + + (*message_)[am::strings::msg_params][strings::system_capability] + [am::strings::system_capability_type] = system_capability_type; + (*message_)[am::strings::msg_params][strings::app_id] = kAppId; + + sdl_rpc_plugin::SDLRPCPlugin sdl_rpc_plugin; + std::shared_ptr<sdl_rpc_plugin::SystemCapabilityAppExtension> + system_capability_app_extension( + std::make_shared<sdl_rpc_plugin::SystemCapabilityAppExtension>( + sdl_rpc_plugin, *mock_app_)); + system_capability_app_extension->SubscribeTo(system_capability_type); + + ON_CALL(*mock_app_, + QueryInterface(sdl_rpc_plugin::SystemCapabilityAppExtension:: + SystemCapabilityAppExtensionUID)) + .WillByDefault(Return(system_capability_app_extension)); + ON_CALL(app_mngr_, application(kAppId)).WillByDefault(Return(mock_app_)); + + EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _)).Times(0); + + ASSERT_TRUE(command_->Init()); + command_->Run(); +} + +TEST_F( + OnBCSystemCapabilityUpdatedNotificationFromHMITest, + Run_VideoStreamingCapability_AppIsSubsribed_VideoCapabilityExists_NotificationForwarded) { + const mobile_apis::SystemCapabilityType::eType system_capability_type = + mobile_apis::SystemCapabilityType::VIDEO_STREAMING; + + (*message_)[am::strings::msg_params][strings::system_capability] + [am::strings::system_capability_type] = system_capability_type; + (*message_)[am::strings::msg_params][strings::app_id] = kAppId; + + (*message_)[am::strings::msg_params][strings::system_capability] + [strings::video_streaming_capability] = + new smart_objects::SmartObject( + smart_objects::SmartType::SmartType_Map); + + auto& video_streaming_capability = + (*message_)[am::strings::msg_params][strings::system_capability] + [strings::video_streaming_capability]; + + FillVideoStreamingCapability(video_streaming_capability); + + sdl_rpc_plugin::SDLRPCPlugin sdl_rpc_plugin; + std::shared_ptr<sdl_rpc_plugin::SystemCapabilityAppExtension> + system_capability_app_extension( + std::make_shared<sdl_rpc_plugin::SystemCapabilityAppExtension>( + sdl_rpc_plugin, *mock_app_)); + system_capability_app_extension->SubscribeTo(system_capability_type); + + ON_CALL(*mock_app_, + QueryInterface(sdl_rpc_plugin::SystemCapabilityAppExtension:: + SystemCapabilityAppExtensionUID)) + .WillByDefault(Return(system_capability_app_extension)); + ON_CALL(app_mngr_, application(kAppId)).WillByDefault(Return(mock_app_)); + + EXPECT_CALL(mock_rpc_service_, + ManageMobileCommand( + CheckVideoStreamingCapability(system_capability_type, + video_streaming_capability), + _)); + + ASSERT_TRUE(command_->Init()); + command_->Run(); +} + } // namespace on_bc_system_capability_updated_notification_from_hmi } // namespace hmi_commands_test } // namespace commands_test diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/on_app_capability_updated_notification_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/on_app_capability_updated_notification_test.cc new file mode 100644 index 0000000000..41e734137b --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/on_app_capability_updated_notification_test.cc @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2020, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "mobile/on_app_capability_updated_notification.h" + +#include "application_manager/commands/commands_test.h" +#include "gtest/gtest.h" +#include "sdl_rpc_plugin/extensions/system_capability_app_extension.h" +#include "sdl_rpc_plugin/sdl_rpc_plugin.h" + +namespace test { +namespace components { +namespace commands_test { +namespace mobile_commands_test { +namespace on_app_capability_updated_notification_test { + +using sdl_rpc_plugin::commands::mobile::OnAppCapabilityUpdatedNotification; +using ::testing::_; + +typedef std::shared_ptr<OnAppCapabilityUpdatedNotification> + OnAppCapabilityUpdatedNotificationPtr; + +namespace strings = application_manager::strings; +namespace { +const uint32_t kConnectionKey = 1u; +const uint32_t kAppId = 2u; +} // namespace + +MATCHER_P(CheckAppCapability, app_capability, "") { + return app_capability == (*arg)[strings::msg_params][strings::app_capability]; +} + +class OnAppCapabilityUpdatedNotificationTest + : public CommandsTest<CommandsTestMocks::kIsNice> { + protected: + void SetUp() OVERRIDE { + message_ = CreateMessage(); + (*message_)[strings::params][strings::connection_key] = kConnectionKey; + command_ = CreateCommand<OnAppCapabilityUpdatedNotification>(message_); + mock_app_ = CreateMockApp(); + } + + OnAppCapabilityUpdatedNotificationPtr command_; + MockAppPtr mock_app_; + MessageSharedPtr message_; +}; + +TEST_F(OnAppCapabilityUpdatedNotificationTest, Run_ManageHMICommand_SUCCESS) { + smart_objects::SmartObject app_capability = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + app_capability[strings::app_capability_type] = + mobile_apis::AppCapabilityType::VIDEO_STREAMING; + app_capability[strings::video_streaming_capability] = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + FillVideoStreamingCapability( + app_capability[strings::video_streaming_capability]); + + (*message_)[strings::msg_params][strings::app_capability] = app_capability; + + ASSERT_TRUE(command_->Init()); + + ON_CALL(app_mngr_, application(kConnectionKey)) + .WillByDefault(Return(mock_app_)); + ON_CALL(*mock_app_, app_id()).WillByDefault(Return(kAppId)); + + EXPECT_CALL(mock_rpc_service_, + ManageHMICommand(CheckAppCapability(app_capability), + app_mngr::commands::Command::SOURCE_SDL_TO_HMI)); + command_->Run(); +} + +} // namespace on_app_capability_updated_notification_test +} // namespace mobile_commands_test +} // namespace commands_test +} // namespace components +} // namespace test diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/on_system_capability_updated_notification_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/on_system_capability_updated_notification_test.cc index 7e7b16aa89..32a13f402c 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/on_system_capability_updated_notification_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/on_system_capability_updated_notification_test.cc @@ -63,6 +63,12 @@ MATCHER_P(CheckDisplayCapabilities, display_capabilities, "") { [strings::display_capabilities]; } +MATCHER_P(CheckVideoStreamCapability, video_streaming_capability, "") { + return video_streaming_capability == + (*arg)[strings::msg_params][strings::system_capability] + [strings::video_streaming_capability]; +} + class OnSystemCapabilityUpdatedNotificationTest : public CommandsTest<CommandsTestMocks::kIsNice> { protected: @@ -233,6 +239,43 @@ TEST_F( command_->Run(); } +TEST_F(OnSystemCapabilityUpdatedNotificationTest, + Run_VideoSteamingCapability_AppIdIsAbsent_SendMessageToMobile) { + (*message_)[am::strings::msg_params][strings::system_capability] + [am::strings::system_capability_type] = + mobile_apis::SystemCapabilityType::VIDEO_STREAMING; + + EXPECT_CALL(mock_rpc_service_, SendMessageToMobile(message_, false)); + + ASSERT_TRUE(command_->Init()); + command_->Run(); +} + +TEST_F(OnSystemCapabilityUpdatedNotificationTest, + Run_VideoSteamingCapability_AppIdExistsInMessage_SendMessageToMobile) { + (*message_)[strings::msg_params][strings::system_capability] + [strings::system_capability_type] = + mobile_apis::SystemCapabilityType::VIDEO_STREAMING; + (*message_)[strings::msg_params][strings::app_id] = kAppId; + (*message_)[strings::msg_params][strings::system_capability] + [strings::video_streaming_capability] = + new smart_objects::SmartObject(smart_objects::SmartType_Map); + + auto& video_streaming_capability = + (*message_)[strings::msg_params][strings::system_capability] + [strings::video_streaming_capability]; + + FillVideoStreamingCapability(video_streaming_capability); + + EXPECT_CALL( + mock_rpc_service_, + SendMessageToMobile( + CheckVideoStreamCapability(video_streaming_capability), false)); + + ASSERT_TRUE(command_->Init()); + command_->Run(); +} + } // namespace on_system_capability_updated_notification } // namespace mobile_commands_test } // namespace commands_test diff --git a/src/components/application_manager/src/application_impl.cc b/src/components/application_manager/src/application_impl.cc index 2e104f73e2..2952fd5481 100644 --- a/src/components/application_manager/src/application_impl.cc +++ b/src/components/application_manager/src/application_impl.cc @@ -613,9 +613,6 @@ void ApplicationImpl::StopStreaming( void ApplicationImpl::StopNaviStreaming() { SDL_LOG_AUTO_TRACE(); video_stream_suspend_timer_.Stop(); - application_manager_.OnAppStreaming(app_id(), - protocol_handler::ServiceType::kMobileNav, - StreamingState::kStopped); MessageHelper::SendNaviStopStream(app_id(), application_manager_); set_video_streaming_approved(false); set_video_stream_retry_number(0); @@ -624,9 +621,6 @@ void ApplicationImpl::StopNaviStreaming() { void ApplicationImpl::StopAudioStreaming() { SDL_LOG_AUTO_TRACE(); audio_stream_suspend_timer_.Stop(); - application_manager_.OnAppStreaming(app_id(), - protocol_handler::ServiceType::kAudio, - StreamingState::kStopped); MessageHelper::SendAudioStopStream(app_id(), application_manager_); set_audio_streaming_approved(false); set_audio_stream_retry_number(0); @@ -637,17 +631,14 @@ void ApplicationImpl::SuspendStreaming( using namespace protocol_handler; SDL_LOG_AUTO_TRACE(); - if (ServiceType::kMobileNav == service_type && !video_streaming_suspended_) { + if (ServiceType::kMobileNav == service_type) { video_stream_suspend_timer_.Stop(); - application_manager_.OnAppStreaming( - app_id(), service_type, StreamingState::kSuspended); + application_manager_.OnAppStreaming(app_id(), service_type, false); sync_primitives::AutoLock lock(video_streaming_suspended_lock_); video_streaming_suspended_ = true; - } else if (ServiceType::kAudio == service_type && - !audio_streaming_suspended_) { + } else if (ServiceType::kAudio == service_type) { audio_stream_suspend_timer_.Stop(); - application_manager_.OnAppStreaming( - app_id(), service_type, StreamingState::kSuspended); + application_manager_.OnAppStreaming(app_id(), service_type, false); sync_primitives::AutoLock lock(audio_streaming_suspended_lock_); audio_streaming_suspended_ = true; } @@ -656,7 +647,7 @@ void ApplicationImpl::SuspendStreaming( } void ApplicationImpl::WakeUpStreaming( - protocol_handler::ServiceType service_type) { + protocol_handler::ServiceType service_type, uint32_t timer_len) { using namespace protocol_handler; SDL_LOG_AUTO_TRACE(); @@ -668,29 +659,28 @@ void ApplicationImpl::WakeUpStreaming( { // reduce the range of video_streaming_suspended_lock_ sync_primitives::AutoLock auto_lock(video_streaming_suspended_lock_); if (video_streaming_suspended_) { - application_manager_.OnAppStreaming( - app_id(), service_type, StreamingState::kStarted); + application_manager_.OnAppStreaming(app_id(), service_type, true); application_manager_.ProcessOnDataStreamingNotification( service_type, app_id(), true); video_streaming_suspended_ = false; } } - - video_stream_suspend_timer_.Start(video_stream_suspend_timeout_, - timer::kPeriodic); + video_stream_suspend_timer_.Start( + timer_len == 0 ? video_stream_suspend_timeout_ : timer_len, + timer::kPeriodic); } else if (ServiceType::kAudio == service_type) { { // reduce the range of audio_streaming_suspended_lock_ sync_primitives::AutoLock auto_lock(audio_streaming_suspended_lock_); if (audio_streaming_suspended_) { - application_manager_.OnAppStreaming( - app_id(), service_type, StreamingState::kStarted); + application_manager_.OnAppStreaming(app_id(), service_type, true); application_manager_.ProcessOnDataStreamingNotification( service_type, app_id(), true); audio_streaming_suspended_ = false; } } - audio_stream_suspend_timer_.Start(audio_stream_suspend_timeout_, - timer::kPeriodic); + audio_stream_suspend_timer_.Start( + timer_len == 0 ? audio_stream_suspend_timeout_ : timer_len, + timer::kPeriodic); } } diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 3b1dc1afc6..fa927c5500 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -3609,6 +3609,27 @@ void ApplicationManagerImpl::ForbidStreaming( } void ApplicationManagerImpl::OnAppStreaming( + uint32_t app_id, protocol_handler::ServiceType service_type, bool state) { + SDL_LOG_AUTO_TRACE(); + + ApplicationSharedPtr app = application(app_id); + if (!app || (!app->is_navi() && !app->mobile_projection_enabled())) { + SDL_LOG_DEBUG( + " There is no navi or projection application with id: " << app_id); + return; + } + DCHECK_OR_RETURN_VOID(media_manager_); + + if (state) { + state_ctrl_.OnVideoStreamingStarted(app); + media_manager_->StartStreaming(app_id, service_type); + } else { + media_manager_->StopStreaming(app_id, service_type); + state_ctrl_.OnVideoStreamingStopped(app); + } +} + +void ApplicationManagerImpl::OnAppStreaming( uint32_t app_id, protocol_handler::ServiceType service_type, const Application::StreamingState new_state) { diff --git a/src/components/application_manager/src/smart_object_keys.cc b/src/components/application_manager/src/smart_object_keys.cc index 87ff3fb05b..5ee74c376d 100644 --- a/src/components/application_manager/src/smart_object_keys.cc +++ b/src/components/application_manager/src/smart_object_keys.cc @@ -197,6 +197,8 @@ const char* policy_type = "policyType"; const char* property = "property"; const char* displays = "displays"; const char* seat_location = "seatLocation"; +const char* app_capability = "appCapability"; +const char* app_capability_type = "appCapabilityType"; // PutFile const char* sync_file_name = "syncFileName"; @@ -445,6 +447,8 @@ const char* const haptic_spatial_data_supported = "hapticSpatialDataSupported"; const char* const diagonal_screen_size = "diagonalScreenSize"; const char* const pixel_per_inch = "pixelPerInch"; const char* const scale = "scale"; +const char* const additional_video_streaming_capabilities = + "additionalVideoStreamingCapabilities"; const char* const haptic_rect_data = "hapticRectData"; const char* const rect = "rect"; const char* const x = "x"; diff --git a/src/components/application_manager/test/application_impl_test.cc b/src/components/application_manager/test/application_impl_test.cc index c3d02271cf..5f23e97391 100644 --- a/src/components/application_manager/test/application_impl_test.cc +++ b/src/components/application_manager/test/application_impl_test.cc @@ -840,6 +840,7 @@ TEST_F(ApplicationImplTest, StartStreaming_StreamingApproved) { TEST_F(ApplicationImplTest, SuspendNaviStreaming) { protocol_handler::ServiceType type = protocol_handler::ServiceType::kMobileNav; + EXPECT_CALL(mock_application_manager_, OnAppStreaming(app_id, type, false)); EXPECT_CALL(mock_application_manager_, ProcessOnDataStreamingNotification(type, app_id, false)); app_impl->SuspendStreaming(type); @@ -847,6 +848,7 @@ TEST_F(ApplicationImplTest, SuspendNaviStreaming) { TEST_F(ApplicationImplTest, SuspendAudioStreaming) { protocol_handler::ServiceType type = protocol_handler::ServiceType::kAudio; + EXPECT_CALL(mock_application_manager_, OnAppStreaming(app_id, type, false)); EXPECT_CALL(mock_application_manager_, ProcessOnDataStreamingNotification(type, app_id, false)); app_impl->SuspendStreaming(type); @@ -855,16 +857,12 @@ TEST_F(ApplicationImplTest, SuspendAudioStreaming) { // TODO {AKozoriz} : Fix tests with streaming (APPLINK-19289) TEST_F(ApplicationImplTest, DISABLED_Suspend_WakeUpAudioStreaming) { protocol_handler::ServiceType type = protocol_handler::ServiceType::kAudio; - EXPECT_CALL( - mock_application_manager_, - OnAppStreaming(app_id, type, Application::StreamingState::kSuspended)); + EXPECT_CALL(mock_application_manager_, OnAppStreaming(app_id, type, false)); EXPECT_CALL(*MockMessageHelper::message_helper_mock(), SendOnDataStreaming(type, false, _)); app_impl->SuspendStreaming(type); - EXPECT_CALL( - mock_application_manager_, - OnAppStreaming(app_id, type, Application::StreamingState::kStarted)); + EXPECT_CALL(mock_application_manager_, OnAppStreaming(app_id, type, true)); EXPECT_CALL(*MockMessageHelper::message_helper_mock(), SendOnDataStreaming(type, true, _)); app_impl->WakeUpStreaming(type); @@ -873,16 +871,12 @@ TEST_F(ApplicationImplTest, DISABLED_Suspend_WakeUpAudioStreaming) { TEST_F(ApplicationImplTest, DISABLED_Suspend_WakeUpNaviStreaming) { protocol_handler::ServiceType type = protocol_handler::ServiceType::kMobileNav; - EXPECT_CALL( - mock_application_manager_, - OnAppStreaming(app_id, type, Application::StreamingState::kSuspended)); + EXPECT_CALL(mock_application_manager_, OnAppStreaming(app_id, type, false)); EXPECT_CALL(*MockMessageHelper::message_helper_mock(), SendOnDataStreaming(type, false, _)); app_impl->SuspendStreaming(type); - EXPECT_CALL( - mock_application_manager_, - OnAppStreaming(app_id, type, Application::StreamingState::kStarted)); + EXPECT_CALL(mock_application_manager_, OnAppStreaming(app_id, type, true)); EXPECT_CALL(*MockMessageHelper::message_helper_mock(), SendOnDataStreaming(type, true, _)); app_impl->WakeUpStreaming(type); @@ -894,9 +888,7 @@ TEST_F(ApplicationImplTest, StopStreaming_StreamingApproved) { protocol_handler::ServiceType::kMobileNav; app_impl->set_video_streaming_approved(true); - EXPECT_CALL( - mock_application_manager_, - OnAppStreaming(app_id, type, Application::StreamingState::kStopped)); + EXPECT_CALL(mock_application_manager_, OnAppStreaming(app_id, type, false)); EXPECT_CALL(mock_application_manager_, ProcessOnDataStreamingNotification(type, app_id, false)); EXPECT_CALL(*MockMessageHelper::message_helper_mock(), @@ -908,9 +900,7 @@ TEST_F(ApplicationImplTest, StopStreaming_StreamingApproved) { // Stop audio streaming app_impl->set_audio_streaming_approved(true); type = protocol_handler::ServiceType::kAudio; - EXPECT_CALL( - mock_application_manager_, - OnAppStreaming(app_id, type, Application::StreamingState::kStopped)); + EXPECT_CALL(mock_application_manager_, OnAppStreaming(app_id, type, false)); EXPECT_CALL(mock_application_manager_, ProcessOnDataStreamingNotification(type, app_id, false)); EXPECT_CALL(*MockMessageHelper::message_helper_mock(), diff --git a/src/components/application_manager/test/hmi_capabilities_test.cc b/src/components/application_manager/test/hmi_capabilities_test.cc index 1377b0bc22..34680027eb 100644 --- a/src/components/application_manager/test/hmi_capabilities_test.cc +++ b/src/components/application_manager/test/hmi_capabilities_test.cc @@ -530,16 +530,16 @@ TEST_F( 800, vs_capability_so[strings::preferred_resolution][strings::resolution_width] .asInt()); - EXPECT_EQ(350, + EXPECT_EQ(380, vs_capability_so[strings::preferred_resolution] [strings::resolution_height] .asInt()); EXPECT_TRUE(vs_capability_so.keyExists(strings::max_bitrate)); - EXPECT_EQ(10000, vs_capability_so[strings::max_bitrate].asInt()); + EXPECT_EQ(20000, vs_capability_so[strings::max_bitrate].asInt()); EXPECT_TRUE(vs_capability_so.keyExists(strings::supported_formats)); const size_t supported_formats_len = vs_capability_so[strings::supported_formats].length(); - EXPECT_EQ(1ull, supported_formats_len); + EXPECT_EQ(5u, supported_formats_len); EXPECT_TRUE(vs_capability_so[strings::supported_formats][0].keyExists( strings::protocol)); @@ -554,9 +554,21 @@ TEST_F( EXPECT_TRUE( vs_capability_so.keyExists(strings::haptic_spatial_data_supported)); - EXPECT_FALSE( + EXPECT_TRUE( vs_capability_so[strings::haptic_spatial_data_supported].asBool()); + EXPECT_TRUE(vs_capability_so.keyExists(strings::diagonal_screen_size)); + EXPECT_EQ(8, vs_capability_so[strings::diagonal_screen_size].asInt()); + EXPECT_TRUE(vs_capability_so.keyExists(strings::pixel_per_inch)); + EXPECT_EQ(96, vs_capability_so[strings::pixel_per_inch].asInt()); + EXPECT_TRUE(vs_capability_so.keyExists(strings::scale)); + EXPECT_EQ(1, vs_capability_so[strings::scale].asInt()); EXPECT_TRUE(vs_capability_so.keyExists(strings::preferred_fps)); + EXPECT_TRUE(vs_capability_so.keyExists( + strings::additional_video_streaming_capabilities)); + const size_t additional_video_streaming_capabilities_len = + vs_capability_so[strings::additional_video_streaming_capabilities] + .length(); + EXPECT_EQ(7u, additional_video_streaming_capabilities_len); EXPECT_TRUE(hmi_capabilities_->video_streaming_supported()); } diff --git a/src/components/application_manager/test/include/application_manager/commands/commands_test.h b/src/components/application_manager/test/include/application_manager/commands/commands_test.h index fdaef2c716..18afa01a88 100644 --- a/src/components/application_manager/test/include/application_manager/commands/commands_test.h +++ b/src/components/application_manager/test/include/application_manager/commands/commands_test.h @@ -53,6 +53,7 @@ namespace components { namespace commands_test { namespace am = ::application_manager; +namespace strings = am::strings; using ::testing::_; using ::testing::Mock; @@ -179,6 +180,30 @@ class CommandsTest : public ::testing::Test { InitHMIToMobileResultConverter(); } + void FillVideoStreamingCapability( + smart_objects::SmartObject& video_streaming_capability) { + video_streaming_capability[strings::preferred_resolution] = + smart_objects::SmartObject(smart_objects::SmartType_Map); + video_streaming_capability[strings::preferred_resolution] + [strings::resolution_width] = 800; + video_streaming_capability[strings::preferred_resolution] + [strings::resolution_height] = 354; + video_streaming_capability[strings::max_bitrate] = 10000; + video_streaming_capability[strings::supported_formats] = + smart_objects::SmartObject(smart_objects::SmartType_Array); + video_streaming_capability[strings::supported_formats][0] = + smart_objects::SmartObject(smart_objects::SmartType_Map); + video_streaming_capability[strings::supported_formats][0] + [strings::protocol] = + hmi_apis::Common_VideoStreamingProtocol::RAW; + video_streaming_capability[strings::supported_formats][0][strings::codec] = + hmi_apis::Common_VideoStreamingCodec::H264; + video_streaming_capability[strings::haptic_spatial_data_supported] = true; + video_streaming_capability[strings::diagonal_screen_size] = 7.47; + video_streaming_capability[strings::pixel_per_inch] = 117.f; + video_streaming_capability[strings::scale] = 1.f; + } + void InitHMIToMobileResultConverter() { namespace MobileResult = mobile_apis::Result; namespace HMIResult = hmi_apis::Common_Result; diff --git a/src/components/application_manager/test/include/application_manager/mock_application.h b/src/components/application_manager/test/include/application_manager/mock_application.h index 9c28d321fa..2c9fe688b4 100644 --- a/src/components/application_manager/test/include/application_manager/mock_application.h +++ b/src/components/application_manager/test/include/application_manager/mock_application.h @@ -88,8 +88,9 @@ class MockApplication : public ::application_manager::Application { void(protocol_handler::ServiceType service_type)); MOCK_METHOD1(SuspendStreaming, void(protocol_handler::ServiceType service_type)); - MOCK_METHOD1(WakeUpStreaming, - void(protocol_handler::ServiceType service_type)); + MOCK_METHOD2(WakeUpStreaming, + void(protocol_handler::ServiceType service_type, + uint32_t timer_len)); MOCK_CONST_METHOD0(is_voice_communication_supported, bool()); MOCK_METHOD1(set_voice_communication_supported, void(bool is_voice_communication_supported)); diff --git a/src/components/include/application_manager/application_manager.h b/src/components/include/application_manager/application_manager.h index ae9344634c..54f7ab9f05 100644 --- a/src/components/include/application_manager/application_manager.h +++ b/src/components/include/application_manager/application_manager.h @@ -861,10 +861,15 @@ class ApplicationManager { * @brief Callback calls when application starts/stops data streaming * @param app_id Streaming application id * @param service_type Streaming service type - * @param new_state Defines new streaming state + * @param state True if streaming started, false if streaming stopped. */ virtual void OnAppStreaming(uint32_t app_id, protocol_handler::ServiceType service_type, + bool state) = 0; + + DEPRECATED + virtual void OnAppStreaming(uint32_t app_id, + protocol_handler::ServiceType service_type, const Application::StreamingState new_state) = 0; /** diff --git a/src/components/include/media_manager/media_manager.h b/src/components/include/media_manager/media_manager.h index 0729adc7d8..2d2201a949 100644 --- a/src/components/include/media_manager/media_manager.h +++ b/src/components/include/media_manager/media_manager.h @@ -70,6 +70,14 @@ class MediaManager { */ virtual const MediaManagerSettings& settings() const = 0; + /** + * \brief Convert an amount of audio bytes to an estimated time in ms + * \param data_size number of bytes to be played + * \return milliseconds required to play <data_size> many bytes with + * the current pcm stream capabilities + */ + virtual uint32_t DataSizeToMilliseconds(uint64_t data_size) const = 0; + virtual ~MediaManager() {} }; diff --git a/src/components/include/test/application_manager/mock_application_manager.h b/src/components/include/test/application_manager/mock_application_manager.h index 6a035a01d1..fd7ddeac15 100644 --- a/src/components/include/test/application_manager/mock_application_manager.h +++ b/src/components/include/test/application_manager/mock_application_manager.h @@ -315,11 +315,16 @@ class MockApplicationManager : public application_manager::ApplicationManager { MOCK_METHOD1(OnAppUnauthorized, void(const uint32_t& app_id)); MOCK_METHOD1(ActivateApplication, bool(application_manager::ApplicationSharedPtr app)); + MOCK_METHOD3(OnAppStreaming, + void(uint32_t app_id, + protocol_handler::ServiceType service_type, + bool state)); + DEPRECATED MOCK_METHOD3( OnAppStreaming, void(uint32_t app_id, protocol_handler::ServiceType service_type, - application_manager::Application::StreamingState new_state)); + const application_manager::Application::StreamingState new_state)); MOCK_CONST_METHOD6(CreateRegularState, application_manager::HmiStatePtr( application_manager::ApplicationSharedPtr app, diff --git a/src/components/include/test/media_manager/mock_media_manager.h b/src/components/include/test/media_manager/mock_media_manager.h index 36e35352d6..364c495236 100644 --- a/src/components/include/test/media_manager/mock_media_manager.h +++ b/src/components/include/test/media_manager/mock_media_manager.h @@ -64,6 +64,7 @@ class MockMediaManager : public media_manager::MediaManager { MOCK_METHOD2(FramesProcessed, void(int32_t application_key, int32_t frame_number)); MOCK_CONST_METHOD0(settings, const media_manager::MediaManagerSettings&()); + MOCK_CONST_METHOD1(DataSizeToMilliseconds, uint32_t(uint64_t data_size)); }; } // namespace media_manager_test diff --git a/src/components/interfaces/HMI_API.xml b/src/components/interfaces/HMI_API.xml index c18448281f..0afd4d132d 100644 --- a/src/components/interfaces/HMI_API.xml +++ b/src/components/interfaces/HMI_API.xml @@ -847,6 +847,11 @@ </element> </enum> +<enum name="AppCapabilityType"> + <description>Enumerations of all available app capability types</description> + <element name="VIDEO_STREAMING"/> +</enum> + <!--IVI part--> <enum name="ElectronicParkBrakeStatus"> <element name="CLOSED"> @@ -3703,6 +3708,20 @@ <param name="preferredFPS" type="Integer" minvalue="0" maxvalue="2147483647" mandatory="false"> <description>The preferred frame rate per second of the head unit. The mobile application / app library may take other factors into account that constrain the frame rate lower than this value, but it should not perform streaming at a higher frame rate than this value.</description> </param> + <param name="additionalVideoStreamingCapabilities" type="VideoStreamingCapability" array="true" minsize="1" maxsize="100" mandatory="false"> + </param> + </struct> + + <struct name="AppCapability"> + <param name="appCapabilityType" type="AppCapabilityType" mandatory="true"> + <description> + Used as a descriptor of what data to expect in this struct. + The corresponding param to this enum should be included and the only other param included. + </description> + </param> + <param name="videoStreamingCapability" type="VideoStreamingCapability" mandatory="false"> + <description>Describes supported capabilities for video streaming </description> + </param> </struct> <struct name="DynamicUpdateCapabilities"> @@ -5021,6 +5040,15 @@ <description>The new application properties</description> </param> </function> + + <function name="OnAppCapabilityUpdated" messagetype="notification"> + <description>A notification to inform HMI that a specific app capability has changed.</description> + <param name="appCapability" type="Common.AppCapability" mandatory="true"> + <description>The app capability that has been updated</description> + </param> + <param name="appID" type="Integer" mandatory="true"> + </param> + </function> </interface> <interface name="VR" version="1.1.0" date="2017-04-27"> diff --git a/src/components/media_manager/include/media_manager/media_manager_impl.h b/src/components/media_manager/include/media_manager/media_manager_impl.h index 8d60cd0e54..3e24212ed5 100644 --- a/src/components/media_manager/include/media_manager/media_manager_impl.h +++ b/src/components/media_manager/include/media_manager/media_manager_impl.h @@ -33,6 +33,7 @@ #ifndef SRC_COMPONENTS_MEDIA_MANAGER_INCLUDE_MEDIA_MANAGER_MEDIA_MANAGER_IMPL_H_ #define SRC_COMPONENTS_MEDIA_MANAGER_INCLUDE_MEDIA_MANAGER_MEDIA_MANAGER_IMPL_H_ +#include <chrono> #include <map> #include <string> #include "interfaces/MOBILE_API.h" @@ -79,6 +80,7 @@ class MediaManagerImpl : public MediaManager, protocol_handler::ServiceType service_type); virtual void StopStreaming(int32_t application_key, protocol_handler::ServiceType service_type); + virtual void SetProtocolHandler( protocol_handler::ProtocolHandler* protocol_handler); virtual void OnMessageReceived( @@ -89,6 +91,8 @@ class MediaManagerImpl : public MediaManager, virtual const MediaManagerSettings& settings() const OVERRIDE; + virtual uint32_t DataSizeToMilliseconds(uint64_t data_size) const OVERRIDE; + #ifdef BUILD_TESTS void set_mock_a2dp_player(MediaAdapter* media_adapter); void set_mock_mic_listener(MediaListenerPtr media_listener); @@ -114,6 +118,12 @@ class MediaManagerImpl : public MediaManager, std::map<protocol_handler::ServiceType, MediaAdapterImplPtr> streamer_; std::map<protocol_handler::ServiceType, MediaListenerPtr> streamer_listener_; + uint32_t bits_per_sample_; + uint32_t sampling_rate_; + uint64_t stream_data_size_; + std::chrono::time_point<std::chrono::system_clock> + socket_audio_stream_start_time_; + application_manager::ApplicationManager& application_manager_; private: diff --git a/src/components/media_manager/src/media_manager_impl.cc b/src/components/media_manager/src/media_manager_impl.cc index 6f0a67b0c9..4fc8b38d87 100644 --- a/src/components/media_manager/src/media_manager_impl.cc +++ b/src/components/media_manager/src/media_manager_impl.cc @@ -35,6 +35,8 @@ #include "application_manager/application_impl.h" #include "application_manager/application_manager.h" #include "application_manager/message_helper.h" +#include "application_manager/smart_object_keys.h" +#include "interfaces/MOBILE_API.h" #include "media_manager/audio/from_mic_recorder_listener.h" #include "media_manager/streamer_listener.h" #include "protocol_handler/protocol_handler.h" @@ -64,6 +66,9 @@ MediaManagerImpl::MediaManagerImpl( , protocol_handler_(NULL) , a2dp_player_(NULL) , from_mic_recorder_(NULL) + , bits_per_sample_(16) + , sampling_rate_(16000) + , stream_data_size_(0ull) , application_manager_(application_manager) { Init(); } @@ -160,6 +165,23 @@ void MediaManagerImpl::Init() { streamer_[ServiceType::kAudio]->AddListener( streamer_listener_[ServiceType::kAudio]); } + + if (application_manager_.hmi_capabilities().pcm_stream_capabilities()) { + const auto pcm_caps = + application_manager_.hmi_capabilities().pcm_stream_capabilities(); + + if (pcm_caps->keyExists(application_manager::strings::bits_per_sample)) { + bits_per_sample_ = + pcm_caps->getElement(application_manager::strings::bits_per_sample) + .asUInt(); + } + + if (pcm_caps->keyExists(application_manager::strings::sampling_rate)) { + sampling_rate_ = + pcm_caps->getElement(application_manager::strings::sampling_rate) + .asUInt(); + } + } } void MediaManagerImpl::PlayA2DPSource(int32_t application_key) { @@ -276,6 +298,8 @@ void MediaManagerImpl::StopStreaming( int32_t application_key, protocol_handler::ServiceType service_type) { SDL_LOG_AUTO_TRACE(); + stream_data_size_ = 0ull; + if (streamer_[service_type]) { streamer_[service_type]->StopActivity(application_key); } @@ -313,7 +337,24 @@ void MediaManagerImpl::OnMessageReceived( ApplicationSharedPtr app = application_manager_.application(streaming_app_id); if (app) { - app->WakeUpStreaming(service_type); + if (ServiceType::kAudio == service_type) { + if (stream_data_size_ == 0) { + socket_audio_stream_start_time_ = std::chrono::system_clock::now(); + } + + stream_data_size_ += message->data_size(); + uint32_t ms_for_all_data = DataSizeToMilliseconds(stream_data_size_); + uint32_t ms_since_stream_start = + std::chrono::duration_cast<std::chrono::milliseconds>( + std::chrono::system_clock::now() - + socket_audio_stream_start_time_) + .count(); + uint32_t ms_stream_remaining = ms_for_all_data - ms_since_stream_start; + + app->WakeUpStreaming(service_type, ms_stream_remaining); + } else { + app->WakeUpStreaming(service_type); + } streamer_[service_type]->SendData(streaming_app_id, message); } } @@ -326,36 +367,16 @@ void MediaManagerImpl::FramesProcessed(int32_t application_key, if (protocol_handler_) { protocol_handler_->SendFramesNumber(application_key, frame_number); } - - application_manager::ApplicationSharedPtr app = - application_manager_.application(application_key); - - if (app) { - auto audio_stream = std::dynamic_pointer_cast<StreamerAdapter>( - streamer_[protocol_handler::ServiceType::kAudio]); - auto video_stream = std::dynamic_pointer_cast<StreamerAdapter>( - streamer_[protocol_handler::ServiceType::kMobileNav]); - - if (audio_stream.use_count() != 0) { - size_t audio_queue_size = audio_stream->GetMsgQueueSize(); - SDL_LOG_DEBUG("# Messages in audio queue = " << audio_queue_size); - if (audio_queue_size > 0) { - app->WakeUpStreaming(protocol_handler::ServiceType::kAudio); - } - } - - if (video_stream.use_count() != 0) { - size_t video_queue_size = video_stream->GetMsgQueueSize(); - SDL_LOG_DEBUG("# Messages in video queue = " << video_queue_size); - if (video_queue_size > 0) { - app->WakeUpStreaming(protocol_handler::ServiceType::kMobileNav); - } - } - } } const MediaManagerSettings& MediaManagerImpl::settings() const { return settings_; } +uint32_t MediaManagerImpl::DataSizeToMilliseconds(uint64_t data_size) const { + constexpr uint16_t latency_compensation = 500; + return 1000 * data_size / (sampling_rate_ * bits_per_sample_ / 8) + + latency_compensation; +} + } // namespace media_manager diff --git a/src/components/media_manager/src/streamer_adapter.cc b/src/components/media_manager/src/streamer_adapter.cc index 8dedd56ea5..808b9715af 100644 --- a/src/components/media_manager/src/streamer_adapter.cc +++ b/src/components/media_manager/src/streamer_adapter.cc @@ -59,6 +59,7 @@ void StreamerAdapter::StartActivity(int32_t application_key) { << " has been already started"); return; } + messages_.Reset(); DCHECK(thread_); const size_t kStackSize = 16384; @@ -86,7 +87,6 @@ void StreamerAdapter::StopActivity(int32_t application_key) { DCHECK(streamer_); streamer_->exitThreadMain(); - messages_.Reset(); for (std::set<MediaListenerPtr>::iterator it = media_listeners_.begin(); media_listeners_.end() != it; diff --git a/src/components/media_manager/test/media_manager_impl_test.cc b/src/components/media_manager/test/media_manager_impl_test.cc index a64faabe91..ab0a9cf494 100644 --- a/src/components/media_manager/test/media_manager_impl_test.cc +++ b/src/components/media_manager/test/media_manager_impl_test.cc @@ -35,6 +35,7 @@ #include "application_manager/message.h" #include "application_manager/mock_application.h" #include "application_manager/mock_application_manager.h" +#include "application_manager/mock_hmi_capabilities.h" #include "application_manager/resumption/resume_ctrl.h" #include "application_manager/state_controller.h" #include "gmock/gmock.h" @@ -109,6 +110,10 @@ class MediaManagerImplTest : public ::testing::Test { .WillByDefault(ReturnRef(kDefaultValue)); ON_CALL(mock_media_manager_settings_, audio_server_type()) .WillByDefault(ReturnRef(kDefaultValue)); + ON_CALL(mock_hmi_capabilities_, pcm_stream_capabilities()) + .WillByDefault(Return(nullptr)); + ON_CALL(app_mngr_, hmi_capabilities()) + .WillByDefault(ReturnRef(mock_hmi_capabilities_)); mock_app_ = std::make_shared<MockApp>(); media_manager_impl_.reset( new MediaManagerImpl(app_mngr_, mock_media_manager_settings_)); @@ -176,7 +181,7 @@ class MediaManagerImplTest : public ::testing::Test { .WillOnce(Return(true)); EXPECT_CALL(app_mngr_, application(kConnectionKey)) .WillOnce(Return(mock_app_)); - EXPECT_CALL(*mock_app_, WakeUpStreaming(service_type)); + EXPECT_CALL(*mock_app_, WakeUpStreaming(service_type, _)); MockMediaAdapterImplPtr mock_media_streamer = std::make_shared<MockMediaAdapterImpl>(); media_manager_impl_->set_mock_streamer(service_type, mock_media_streamer); @@ -206,6 +211,7 @@ class MediaManagerImplTest : public ::testing::Test { const ::testing::NiceMock<MockMediaManagerSettings> mock_media_manager_settings_; std::shared_ptr<MediaManagerImpl> media_manager_impl_; + application_manager_test::MockHMICapabilities mock_hmi_capabilities_; }; TEST_F(MediaManagerImplTest, @@ -410,17 +416,11 @@ TEST_F(MediaManagerImplTest, TEST_F(MediaManagerImplTest, CheckFramesProcessed_WithCorrectFramesNumber_SUCCESS) { - ON_CALL(mock_media_manager_settings_, video_server_type()) - .WillByDefault(ReturnRef(kDefaultValue)); - ON_CALL(mock_media_manager_settings_, audio_server_type()) - .WillByDefault(ReturnRef(kDefaultValue)); protocol_handler_test::MockProtocolHandler mock_protocol_handler; media_manager_impl_->SetProtocolHandler(&mock_protocol_handler); const int32_t frame_number = 10; EXPECT_CALL(mock_protocol_handler, SendFramesNumber(kApplicationKey, frame_number)); - EXPECT_CALL(app_mngr_, application(kConnectionKey)) - .WillOnce(Return(mock_app_)); media_manager_impl_->FramesProcessed(kApplicationKey, frame_number); } diff --git a/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py b/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py index bec5912d54..736a95f7ac 100755 --- a/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py +++ b/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py @@ -564,6 +564,7 @@ class CodeGenerator(object): struct_name=struct.name, code=self._indent_code( self._struct_impl_code_tempate.substitute( + struct_name=struct.name, schema_loc_decl=self._gen_schema_loc_decls( struct.members.values(), processed_enums), schema_items_decl=self._gen_schema_items_decls( @@ -1879,11 +1880,9 @@ class CodeGenerator(object): _struct_schema_item_template = string.Template( u'''std::shared_ptr<ISchemaItem> struct_schema_item_${name} = ''' u'''InitStructSchemaItem_${name}(struct_schema_items);\n''' - u'''struct_schema_items.insert(std::make_pair(''' - u'''StructIdentifiers::${name}, struct_schema_item_${name}));\n''' u'''structs_schemes_.insert(std::make_pair(''' u'''StructIdentifiers::${name}, CSmartSchema(''' - u'''struct_schema_item_${name})));''') + u'''struct_schema_item_${name})));\n''') _function_schema_template = string.Template( u'''functions_schemes_.insert(std::make_pair(ns_smart_device_link::''' @@ -1896,17 +1895,21 @@ class CodeGenerator(object): _struct_impl_template = string.Template( u'''std::shared_ptr<ISchemaItem> $namespace::$class_name::''' u'''InitStructSchemaItem_${struct_name}(\n''' - u''' const TStructsSchemaItems &struct_schema_items) {\n''' + u''' TStructsSchemaItems &struct_schema_items) {\n''' u'''$code''' u'''}\n''') _struct_impl_code_tempate = string.Template( + u'''Members ''' + u'''schema_members;\n''' + u'''std::shared_ptr<ISchemaItem> struct_schema = CObjectSchemaItem::create(schema_members);\n''' + u'''struct_schema_items.insert(std::make_pair(StructIdentifiers::${struct_name}, CObjectSchemaItem::create(schema_members)));\n''' + u'''struct_schema_items[StructIdentifiers::${struct_name}] = struct_schema;\n\n''' u'''${schema_loc_decl}''' u'''${schema_items_decl}''' - u'''Members ''' - u'''schema_members;\n\n''' u'''${schema_item_fill}''' - u'''return CObjectSchemaItem::create(schema_members);''') + u'''for(auto& member : schema_members) {struct_schema->AddMemberSchemaItem(member.first, member.second);}\n''' + u'''return struct_schema;''') _impl_code_loc_decl_enum_template = string.Template( u'''std::set<${type}::eType> ${var_name};''') @@ -2113,7 +2116,7 @@ class CodeGenerator(object): u'''static ''' u'''std::shared_ptr<ns_smart_device_link::ns_smart_objects::ISchemaItem> ''' u'''InitStructSchemaItem_${struct_name}(\n''' - u''' const TStructsSchemaItems &struct_schema_items);''') + u''' TStructsSchemaItems &struct_schema_items);''') _class_comment_template = string.Template( u'''/**\n''' diff --git a/tools/rpc_spec b/tools/rpc_spec -Subproject 02f592fe191cd4886d6e88b71b834d1ac2f49f0 +Subproject 6b98355357b5b1893bbb59cb668d28545023457 |