diff options
5 files changed, 189 insertions, 0 deletions
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 888cd53c0a..00c5861043 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 @@ -175,6 +175,8 @@ extern const char* video_streaming_state; extern const char* system_context; extern const char* window_name; extern const char* window_type; +extern const char* window_type_supported; +extern const char* maximum_number_of_windows; extern const char* window_capabilities; extern const char* associated_service_type; extern const char* duplicate_updates_from_window_id; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/create_window_request.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/create_window_request.h index 7a851b4d84..cfbfc460b7 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/create_window_request.h +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/create_window_request.h @@ -79,6 +79,28 @@ class CreateWindowRequest : public app_mngr::commands::CommandRequestImpl { const std::string& window_name) const; /** + * @brief ValidateWindowCreation checks whether window can be created + * @return true if window can be created, otherwise returns false + */ + bool ValidateWindowCreation(app_mngr::ApplicationSharedPtr app, + const app_mngr::WindowID window_id); + + /** + * @brief IsWindowForAssociatedServiceCreated check whether a window with + * current associated type has already been created + * @return true if window has been created, otherwise returns false + */ + bool IsWindowForAssociatedServiceCreated( + app_mngr::ApplicationSharedPtr app) const; + + /** + * @brief DoesExceedMaxAllowedWindows check wheter max allowed amount of + * windows is exceeded + * @return true if amount us exceeded, otherwise returns false + */ + bool DoesExceedMaxAllowedWindows(app_mngr::ApplicationSharedPtr app) const; + + /** * @brief ApplyWindowInitialState apply changes related to window HMI state * initialization * @param app pointer to application owns affected window diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_window_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_window_request.cc index 83406a549d..21b54b4e9f 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_window_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_window_request.cc @@ -186,6 +186,10 @@ void CreateWindowRequest::Run() { return; } + if (!ValidateWindowCreation(application, window_id)) { + return; + } + smart_objects::SmartObject msg_params = (*message_)[strings::msg_params]; msg_params[strings::app_id] = application->hmi_app_id(); @@ -241,6 +245,126 @@ bool CreateWindowRequest::Init() { return true; } +bool CreateWindowRequest::IsWindowForAssociatedServiceCreated( + app_mngr::ApplicationSharedPtr app) const { + LOG4CXX_AUTO_TRACE(logger_); + + const auto window_optional_params_map = + app->window_optional_params_map().GetData(); + + if (!(*message_)[strings::msg_params].keyExists( + strings::associated_service_type)) { + return false; + } + + const auto associated_service_type = + (*message_)[strings::msg_params][strings::associated_service_type] + .asString(); + + const auto find_res = std::find_if( + window_optional_params_map.begin(), + window_optional_params_map.end(), + [&associated_service_type]( + const std::pair<WindowID, smart_objects::SmartObjectSPtr>& element) { + LOG4CXX_DEBUG(logger_, + "Searching for " << associated_service_type + << " in window info for id " + << element.first); + if (element.second->keyExists(strings::associated_service_type) && + associated_service_type == + (*element.second)[strings::associated_service_type] + .asString()) { + return true; + } + + return false; + }); + + return find_res != window_optional_params_map.end(); +} + +bool CreateWindowRequest::DoesExceedMaxAllowedWindows( + app_mngr::ApplicationSharedPtr app) const { + LOG4CXX_AUTO_TRACE(logger_); + + auto get_current_number_of_windows = + [&app](const mobile_apis::WindowType::eType window_type) -> size_t { + switch (window_type) { + case mobile_apis::WindowType::MAIN: { + return 1u; + } + case mobile_apis::WindowType::WIDGET: { + return app->window_optional_params_map().GetData().size(); + } + + default: { + LOG4CXX_WARN(logger_, "Unknown window type"); + return 0u; + } + } + }; + + const auto window_type = static_cast<mobile_apis::WindowType::eType>( + (*message_)[strings::msg_params][strings::window_type].asInt()); + + const auto display_capabilities = app->display_capabilities(); + + if (!display_capabilities) { + LOG4CXX_WARN(logger_, "Application has no capabilities"); + return false; + } + + MessageHelper::PrintSmartObject(*display_capabilities); + + const auto windowTypeSupported = + (*display_capabilities)[0][strings::window_type_supported].asArray(); + + DCHECK(windowTypeSupported); + + const auto find_res = std::find_if( + windowTypeSupported->begin(), + windowTypeSupported->end(), + [&window_type](const smart_objects::SmartObject& element) { + if (window_type == static_cast<mobile_apis::WindowType::eType>( + element[strings::window_type].asInt())) { + return true; + } + + return false; + }); + + DCHECK(find_res != windowTypeSupported->end()); + + if (get_current_number_of_windows(window_type) + 1 > + (*find_res)[strings::maximum_number_of_windows].asUInt()) { + return true; + } + + return false; +} + +bool CreateWindowRequest::ValidateWindowCreation( + app_mngr::ApplicationSharedPtr app, const WindowID window_id) { + LOG4CXX_AUTO_TRACE(logger_); + + if (DoesExceedMaxAllowedWindows(app)) { + std::string info("Maximum allowed amount of windows is exceeded"); + LOG4CXX_WARN(logger_, info); + SendResponse(false, mobile_apis::Result::REJECTED, info.c_str()); + return false; + } + + if (IsWindowForAssociatedServiceCreated(app)) { + std::string info( + "Window for this associated service type is already created"); + LOG4CXX_WARN(logger_, info); + SendResponse(false, mobile_apis::Result::REJECTED, info.c_str()); + return false; + } + + return true; +} + } // namespace commands } // namespace sdl_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/create_window_request_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/create_window_request_test.cc index 9c74196f06..02a6591a2d 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/create_window_request_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/create_window_request_test.cc @@ -142,8 +142,41 @@ class CreateWindowRequestTest .WillByDefault(Return()); } + void SetUp() OVERRIDE { + using namespace application_manager; + display_capabilities_ = std::make_shared<smart_objects::SmartObject>( + smart_objects::SmartType_Array); + + smart_objects::SmartObject window_type_supported( + smart_objects::SmartType_Array); + + const uint32_t maximum_widgets_amount = 4; + smart_objects::SmartObject maximum_widgets(smart_objects::SmartType_Map); + maximum_widgets[strings::window_type] = mobile_apis::WindowType::WIDGET; + maximum_widgets[strings::maximum_number_of_windows] = + maximum_widgets_amount; + + window_type_supported[window_type_supported.length()] = maximum_widgets; + + (*display_capabilities_)[0][strings::window_type_supported] = + window_type_supported; + + ON_CALL(*mock_app_, display_capabilities()) + .WillByDefault(Return(display_capabilities_)); + + window_params_map_lock_ptr_ = std::make_shared<sync_primitives::Lock>(); + + DataAccessor<am::WindowParamsMap> window_params_map( + test_window_params_map_, window_params_map_lock_ptr_); + ON_CALL(*mock_app_, window_optional_params_map()) + .WillByDefault(Return(window_params_map)); + } + MockAppPtr mock_app_; NiceMock<MockStateController> mock_state_controller; + std::shared_ptr<sync_primitives::Lock> window_params_map_lock_ptr_; + application_manager::WindowParamsMap test_window_params_map_; + smart_objects::SmartObjectSPtr display_capabilities_; }; TEST_F(CreateWindowRequestTest, WindowID_ExpectDefaultWindowID) { @@ -249,6 +282,8 @@ TEST_F( (*msg)[am::strings::msg_params][am::strings::window_id] = kTestWindowId; (*msg)[am::strings::msg_params] [am::strings::duplicate_updates_from_window_id] = kDuplicateWindowID; + (*msg)[am::strings::msg_params][am::strings::window_type] = + mobile_apis::WindowType::WIDGET; auto command = CreateCommand<CreateWindowRequest>(msg); EXPECT_TRUE(command->Init()); @@ -299,6 +334,8 @@ TEST_F(CreateWindowRequestTest, [am::strings::duplicate_updates_from_window_id] = kDuplicateWindowID; (*msg)[am::strings::msg_params][am::strings::associated_service_type] = "MEDIA"; + (*msg)[am::strings::msg_params][am::strings::window_type] = + mobile_apis::WindowType::WIDGET; auto command = CreateCommand<CreateWindowRequest>(msg); EXPECT_TRUE(command->Init()); @@ -327,6 +364,8 @@ TEST_F( [am::strings::duplicate_updates_from_window_id] = kDuplicateWindowID; (*msg)[am::strings::msg_params][am::strings::associated_service_type] = "MEDIA"; + (*msg)[am::strings::msg_params][am::strings::window_type] = + mobile_apis::WindowType::WIDGET; auto command = CreateCommand<CreateWindowRequest>(msg); EXPECT_TRUE(command->Init()); diff --git a/src/components/application_manager/src/smart_object_keys.cc b/src/components/application_manager/src/smart_object_keys.cc index 4074de8486..0c149e93e0 100644 --- a/src/components/application_manager/src/smart_object_keys.cc +++ b/src/components/application_manager/src/smart_object_keys.cc @@ -142,6 +142,8 @@ const char* video_streaming_state = "videoStreamingState"; const char* system_context = "systemContext"; const char* window_name = "windowName"; const char* window_type = "type"; +const char* window_type_supported = "windowTypeSupported"; +const char* maximum_number_of_windows = "maximumNumberOfWindows"; const char* window_capabilities = "windowCapabilities"; const char* associated_service_type = "associatedServiceType"; const char* duplicate_updates_from_window_id = "duplicateUpdatesFromWindowID"; |