diff options
Diffstat (limited to 'src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile')
108 files changed, 17376 insertions, 0 deletions
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/add_command_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/add_command_request.cc new file mode 100644 index 0000000000..69948b8122 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/add_command_request.cc @@ -0,0 +1,616 @@ +/* + + Copyright (c) 2016, 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 <string> +#include "application_manager/commands/mobile/add_command_request.h" + +#include "application_manager/application.h" +#include "application_manager/message_helper.h" +#include "utils/file_system.h" +#include "utils/helpers.h" +#include "utils/custom_string.h" + +namespace application_manager { + +namespace commands { + +namespace custom_str = utils::custom_string; + +AddCommandRequest::AddCommandRequest(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) + , send_ui_(false) + , send_vr_(false) + , is_ui_received_(false) + , is_vr_received_(false) + , ui_result_(hmi_apis::Common_Result::INVALID_ENUM) + , vr_result_(hmi_apis::Common_Result::INVALID_ENUM) {} + +AddCommandRequest::~AddCommandRequest() {} + +void AddCommandRequest::onTimeOut() { + LOG4CXX_AUTO_TRACE(logger_); + RemoveCommand(); + CommandRequestImpl::onTimeOut(); +} + +bool AddCommandRequest::Init() { + hash_update_mode_ = HashUpdateMode::kDoHashUpdate; + return true; +} + +void AddCommandRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application( + (*message_)[strings::params][strings::connection_key].asUInt()); + + if (!app) { + LOG4CXX_ERROR(logger_, "No application associated with session key"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + if ((*message_)[strings::msg_params].keyExists(strings::cmd_icon)) { + mobile_apis::Result::eType verification_result = MessageHelper::VerifyImage( + (*message_)[strings::msg_params][strings::cmd_icon], + app, + application_manager_); + + if (mobile_apis::Result::SUCCESS != verification_result) { + LOG4CXX_ERROR( + logger_, "MessageHelper::VerifyImage return " << verification_result); + SendResponse(false, verification_result); + return; + } + } + + if (!((*message_)[strings::msg_params].keyExists(strings::cmd_id))) { + LOG4CXX_ERROR(logger_, "INVALID_DATA"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + if (app->FindCommand( + (*message_)[strings::msg_params][strings::cmd_id].asUInt())) { + LOG4CXX_ERROR(logger_, "INVALID_ID"); + SendResponse(false, mobile_apis::Result::INVALID_ID); + return; + } + + bool data_exist = false; + + if ((*message_)[strings::msg_params].keyExists(strings::menu_params)) { + if (!CheckCommandName(app)) { + SendResponse(false, mobile_apis::Result::DUPLICATE_NAME); + return; + } + if (((*message_)[strings::msg_params][strings::menu_params].keyExists( + hmi_request::parent_id)) && + (0 != + (*message_)[strings::msg_params][strings::menu_params] + [hmi_request::parent_id].asUInt())) { + if (!CheckCommandParentId(app)) { + SendResponse( + false, mobile_apis::Result::INVALID_ID, "Parent ID doesn't exist"); + return; + } + } + data_exist = true; + } + + if (((*message_)[strings::msg_params].keyExists(strings::vr_commands)) && + ((*message_)[strings::msg_params][strings::vr_commands].length() > 0)) { + if (!CheckCommandVRSynonym(app)) { + SendResponse(false, mobile_apis::Result::DUPLICATE_NAME); + return; + } + + data_exist = true; + } + + if (!data_exist) { + LOG4CXX_ERROR(logger_, "INVALID_DATA"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + if (IsWhiteSpaceExist()) { + LOG4CXX_ERROR(logger_, "Incoming add command has contains \t\n \\t \\n"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + app->AddCommand((*message_)[strings::msg_params][strings::cmd_id].asUInt(), + (*message_)[strings::msg_params]); + + smart_objects::SmartObject ui_msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + if ((*message_)[strings::msg_params].keyExists(strings::menu_params)) { + ui_msg_params[strings::cmd_id] = + (*message_)[strings::msg_params][strings::cmd_id]; + ui_msg_params[strings::menu_params] = + (*message_)[strings::msg_params][strings::menu_params]; + + ui_msg_params[strings::app_id] = app->app_id(); + + if (((*message_)[strings::msg_params].keyExists(strings::cmd_icon)) && + ((*message_)[strings::msg_params][strings::cmd_icon].keyExists( + strings::value)) && + (0 < (*message_)[strings::msg_params][strings::cmd_icon][strings::value] + .length())) { + ui_msg_params[strings::cmd_icon] = + (*message_)[strings::msg_params][strings::cmd_icon]; + } + + send_ui_ = true; + } + + smart_objects::SmartObject vr_msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + if ((*message_)[strings::msg_params].keyExists(strings::vr_commands)) { + vr_msg_params[strings::cmd_id] = + (*message_)[strings::msg_params][strings::cmd_id]; + vr_msg_params[strings::vr_commands] = + (*message_)[strings::msg_params][strings::vr_commands]; + vr_msg_params[strings::app_id] = app->app_id(); + + vr_msg_params[strings::type] = hmi_apis::Common_VRCommandType::Command; + vr_msg_params[strings::grammar_id] = app->get_grammar_id(); + + send_vr_ = true; + } + + if (send_ui_) { + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + SendHMIRequest(hmi_apis::FunctionID::UI_AddCommand, &ui_msg_params, true); + } + + if (send_vr_) { + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VR); + SendHMIRequest(hmi_apis::FunctionID::VR_AddCommand, &vr_msg_params, true); + } +} + +bool AddCommandRequest::CheckCommandName(ApplicationConstSharedPtr app) { + if (!app) { + return false; + } + + const DataAccessor<CommandsMap> accessor = app->commands_map(); + const CommandsMap& commands = accessor.GetData(); + CommandsMap::const_iterator i = commands.begin(); + uint32_t saved_parent_id = 0; + uint32_t parent_id = 0; + if ((*message_)[strings::msg_params][strings::menu_params].keyExists( + hmi_request::parent_id)) { + parent_id = (*message_)[strings::msg_params][strings::menu_params] + [hmi_request::parent_id].asUInt(); + } + + for (; commands.end() != i; ++i) { + if (!(*i->second).keyExists(strings::menu_params)) { + continue; + } + + saved_parent_id = 0; + if ((*i->second)[strings::menu_params].keyExists(hmi_request::parent_id)) { + saved_parent_id = + (*i->second)[strings::menu_params][hmi_request::parent_id].asUInt(); + } + if (((*i->second)[strings::menu_params][strings::menu_name].asString() == + (*message_)[strings::msg_params][strings::menu_params] + [strings::menu_name].asString()) && + (saved_parent_id == parent_id)) { + LOG4CXX_INFO(logger_, + "AddCommandRequest::CheckCommandName received" + " command name already exist in same level menu"); + return false; + } + } + return true; +} + +bool AddCommandRequest::CheckCommandVRSynonym(ApplicationConstSharedPtr app) { + if (!app) { + return false; + } + + const DataAccessor<CommandsMap> accessor = app->commands_map(); + const CommandsMap& commands = accessor.GetData(); + CommandsMap::const_iterator it = commands.begin(); + + for (; commands.end() != it; ++it) { + if (!(*it->second).keyExists(strings::vr_commands)) { + continue; + } + + for (size_t i = 0; i < (*it->second)[strings::vr_commands].length(); ++i) { + for (size_t j = 0; + j < (*message_)[strings::msg_params][strings::vr_commands].length(); + ++j) { + const custom_str::CustomString& vr_cmd_i = + (*it->second)[strings::vr_commands][i].asCustomString(); + const custom_str::CustomString& vr_cmd_j = + (*message_)[strings::msg_params][strings::vr_commands][j] + .asCustomString(); + + if (vr_cmd_i.CompareIgnoreCase(vr_cmd_j)) { + LOG4CXX_INFO(logger_, + "AddCommandRequest::CheckCommandVRSynonym" + " received command vr synonym already exist"); + return false; + } + } + } + } + return true; +} + +bool AddCommandRequest::CheckCommandParentId(ApplicationConstSharedPtr app) { + if (!app) { + return false; + } + + const int32_t parent_id = + (*message_)[strings::msg_params][strings::menu_params] + [hmi_request::parent_id].asInt(); + smart_objects::SmartObject* parent = app->FindSubMenu(parent_id); + + if (!parent) { + LOG4CXX_INFO(logger_, + "AddCommandRequest::CheckCommandParentId received" + " submenu doesn't exist"); + return false; + } + return true; +} + +// TODO(AKUTSAN) APPLINK-26973: Refactor AddCommandRequest +void AddCommandRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace helpers; + + const smart_objects::SmartObject& message = event.smart_object(); + + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + + if (!application) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + return; + } + + smart_objects::SmartObject msg_param(smart_objects::SmartType_Map); + msg_param[strings::cmd_id] = + (*message_)[strings::msg_params][strings::cmd_id]; + msg_param[strings::app_id] = application->app_id(); + + switch (event.id()) { + case hmi_apis::FunctionID::UI_AddCommand: { + LOG4CXX_INFO(logger_, "Received UI_AddCommand event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + is_ui_received_ = true; + ui_result_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + GetInfo(message, ui_info_); + if (hmi_apis::Common_Result::SUCCESS != ui_result_) { + (*message_)[strings::msg_params].erase(strings::menu_params); + } + break; + } + case hmi_apis::FunctionID::VR_AddCommand: { + LOG4CXX_INFO(logger_, "Received VR_AddCommand event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VR); + is_vr_received_ = true; + vr_result_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + GetInfo(message, vr_info_); + if (hmi_apis::Common_Result::SUCCESS != vr_result_) { + (*message_)[strings::msg_params].erase(strings::vr_commands); + } + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } + + if (IsPendingResponseExist()) { + return; + } + + smart_objects::SmartObject msg_params(smart_objects::SmartType_Map); + msg_params[strings::cmd_id] = + (*message_)[strings::msg_params][strings::cmd_id]; + msg_params[strings::app_id] = application->app_id(); + + mobile_apis::Result::eType result_code = mobile_apis::Result::INVALID_ENUM; + + const bool is_vr_invalid_unsupported = + Compare<hmi_apis::Common_Result::eType, EQ, ONE>( + vr_result_, + hmi_apis::Common_Result::INVALID_ENUM, + hmi_apis::Common_Result::UNSUPPORTED_RESOURCE); + + const bool is_ui_invalid_unsupported = + Compare<hmi_apis::Common_Result::eType, EQ, ONE>( + ui_result_, + hmi_apis::Common_Result::INVALID_ENUM, + hmi_apis::Common_Result::UNSUPPORTED_RESOURCE); + const bool is_vr_unsupported = + vr_result_ == hmi_apis::Common_Result::UNSUPPORTED_RESOURCE; + const bool is_ui_unsupported = + ui_result_ == hmi_apis::Common_Result::UNSUPPORTED_RESOURCE; + + const bool is_no_ui_error = Compare<hmi_apis::Common_Result::eType, EQ, ONE>( + ui_result_, + hmi_apis::Common_Result::SUCCESS, + hmi_apis::Common_Result::WARNINGS, + hmi_apis::Common_Result::WRONG_LANGUAGE, + hmi_apis::Common_Result::RETRY, + hmi_apis::Common_Result::SAVED, + hmi_apis::Common_Result::UNSUPPORTED_RESOURCE); + + const bool is_no_vr_error = Compare<hmi_apis::Common_Result::eType, EQ, ONE>( + vr_result_, + hmi_apis::Common_Result::SUCCESS, + hmi_apis::Common_Result::WARNINGS, + hmi_apis::Common_Result::WRONG_LANGUAGE, + hmi_apis::Common_Result::RETRY, + hmi_apis::Common_Result::SAVED, + hmi_apis::Common_Result::UNSUPPORTED_RESOURCE); + + bool result = (is_no_ui_error && is_no_vr_error) || + (is_no_ui_error && is_vr_invalid_unsupported) || + (is_no_vr_error && is_ui_invalid_unsupported); + + LOG4CXX_DEBUG(logger_, + "calculated result " << ui_result_ << " " << is_no_ui_error + << " " << is_no_vr_error); + const bool is_vr_or_ui_warning = + Compare<hmi_apis::Common_Result::eType, EQ, ONE>( + hmi_apis::Common_Result::WARNINGS, ui_result_, vr_result_); + + const bool is_vr_or_ui_unsupported = + Compare<hmi_apis::Common_Result::eType, EQ, ONE>( + hmi_apis::Common_Result::UNSUPPORTED_RESOURCE, + ui_result_, + vr_result_); + + const bool is_vr_and_ui_unsupported = + Compare<hmi_apis::Common_Result::eType, EQ, ALL>( + hmi_apis::Common_Result::UNSUPPORTED_RESOURCE, + ui_result_, + vr_result_); + + if (!result && hmi_apis::Common_Result::REJECTED == ui_result_) { + result_code = MessageHelper::HMIToMobileResult(ui_result_); + } else if (result && is_vr_or_ui_unsupported) { + result_code = mobile_apis::Result::UNSUPPORTED_RESOURCE; + } else if (is_vr_or_ui_warning) { + result_code = mobile_apis::Result::WARNINGS; + } else { + result_code = + MessageHelper::HMIToMobileResult(std::max(ui_result_, vr_result_)); + if (hmi_apis::Common_Result::UNSUPPORTED_RESOURCE == ui_result_) { + result_code = MessageHelper::HMIToMobileResult(vr_result_); + } + if (hmi_apis::Common_Result::UNSUPPORTED_RESOURCE == vr_result_) { + result_code = MessageHelper::HMIToMobileResult(ui_result_); + } + LOG4CXX_DEBUG(logger_, "HMIToMobileResult " << result_code); + } + + if (BothSend() && hmi_apis::Common_Result::SUCCESS == vr_result_) { + const bool is_ui_not_ok = Compare<hmi_apis::Common_Result::eType, NEQ, ALL>( + ui_result_, + hmi_apis::Common_Result::SUCCESS, + hmi_apis::Common_Result::WARNINGS, + hmi_apis::Common_Result::UNSUPPORTED_RESOURCE); + + if (is_ui_not_ok) { + result_code = ui_result_ == hmi_apis::Common_Result::REJECTED + ? mobile_apis::Result::REJECTED + : mobile_apis::Result::GENERIC_ERROR; + + msg_params[strings::grammar_id] = application->get_grammar_id(); + msg_params[strings::type] = hmi_apis::Common_VRCommandType::Command; + + SendHMIRequest(hmi_apis::FunctionID::VR_DeleteCommand, &msg_params); + application->RemoveCommand( + (*message_)[strings::msg_params][strings::cmd_id].asUInt()); + result = false; + LOG4CXX_DEBUG(logger_, "Result " << result); + } + } + + if (BothSend() && hmi_apis::Common_Result::SUCCESS == ui_result_ && + !is_no_vr_error && + hmi_apis::Common_Result::UNSUPPORTED_RESOURCE != vr_result_) { + result_code = vr_result_ == hmi_apis::Common_Result::REJECTED + ? mobile_apis::Result::REJECTED + : mobile_apis::Result::GENERIC_ERROR; + + SendHMIRequest(hmi_apis::FunctionID::UI_DeleteCommand, &msg_params); + + application->RemoveCommand( + (*message_)[strings::msg_params][strings::cmd_id].asUInt()); + result = false; + LOG4CXX_DEBUG(logger_, "Result " << result); + } + + HmiInterfaces::InterfaceState ui_interface_state = + application_manager_.hmi_interfaces().GetInterfaceState( + HmiInterfaces::HMI_INTERFACE_UI); + HmiInterfaces::InterfaceState vr_interface_state = + application_manager_.hmi_interfaces().GetInterfaceState( + HmiInterfaces::HMI_INTERFACE_VR); + + if (!BothSend() && + ((is_vr_unsupported && + HmiInterfaces::STATE_NOT_AVAILABLE == vr_interface_state) || + (is_ui_unsupported && + HmiInterfaces::STATE_NOT_AVAILABLE == ui_interface_state))) { + LOG4CXX_DEBUG(logger_, "!BothSend() && is_vr_or_ui_unsupported"); + result = false; + } + + if (is_vr_and_ui_unsupported) { + LOG4CXX_DEBUG(logger_, "UI and VR interface both unsupported"); + result = false; + } + + if (!result) { + RemoveCommand(); + } + + const std::string info = GenerateMobileResponseInfo(); + SendResponse(result, + result_code, + info.empty() ? NULL : info.c_str(), + &(message[strings::msg_params])); +} + +bool AddCommandRequest::IsPendingResponseExist() { + return send_ui_ != is_ui_received_ || send_vr_ != is_vr_received_; +} + +bool AddCommandRequest::IsWhiteSpaceExist() { + LOG4CXX_AUTO_TRACE(logger_); + const char* str = NULL; + + if ((*message_)[strings::msg_params].keyExists(strings::menu_params)) { + str = (*message_)[strings::msg_params][strings::menu_params] + [strings::menu_name].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid menu name syntax check failed."); + return true; + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::vr_commands)) { + const size_t len = + (*message_)[strings::msg_params][strings::vr_commands].length(); + + for (size_t i = 0; i < len; ++i) { + str = (*message_)[strings::msg_params][strings::vr_commands][i] + .asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid vr_commands syntax check failed"); + return true; + } + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::cmd_icon)) { + str = (*message_)[strings::msg_params][strings::cmd_icon][strings::value] + .asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid cmd_icon value syntax check failed"); + return true; + } + } + return false; +} + +bool AddCommandRequest::BothSend() const { + return send_vr_ && send_ui_; +} + +const std::string AddCommandRequest::GenerateMobileResponseInfo() { + // In case if vr_result_ is UNSUPPORTED_RESOURCE vr_info should be on the + // first place + // In case if ui_result_ is UNSUPPORTED_RESOURCE ui_info should be on the + // first place + // Other way order is doesn't matter + + HmiInterfaces& hmi_interfaces = application_manager_.hmi_interfaces(); + HmiInterfaces::InterfaceState ui_interface_state = + hmi_interfaces.GetInterfaceState(HmiInterfaces::HMI_INTERFACE_UI); + + HmiInterfaces::InterfaceState vr_interface_state = + hmi_interfaces.GetInterfaceState(HmiInterfaces::HMI_INTERFACE_VR); + + if ((ui_interface_state == HmiInterfaces::STATE_NOT_AVAILABLE) && + (vr_interface_state != HmiInterfaces::STATE_NOT_AVAILABLE) && + !vr_info_.empty()) { + return vr_info_; + } + + if ((vr_interface_state == HmiInterfaces::STATE_NOT_AVAILABLE) && + (ui_interface_state != HmiInterfaces::STATE_NOT_AVAILABLE) && + !ui_info_.empty()) { + return ui_info_; + } + + return MergeInfos(ui_info_, vr_info_); +} + +void AddCommandRequest::RemoveCommand() { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr app = application_manager_.application(connection_key()); + if (!app.valid()) { + LOG4CXX_ERROR(logger_, "No application associated with session key"); + return; + } + + smart_objects::SmartObject msg_params(smart_objects::SmartType_Map); + msg_params[strings::cmd_id] = + (*message_)[strings::msg_params][strings::cmd_id]; + msg_params[strings::app_id] = app->app_id(); + + app->RemoveCommand( + (*message_)[strings::msg_params][strings::cmd_id].asUInt()); + + if (BothSend() && !(is_vr_received_ || is_ui_received_)) { + // in case we have send bth UI and VR and no one respond + // we have nothing to remove from HMI so no DeleteCommand expected + return; + } + + if (BothSend() && !is_vr_received_) { + SendHMIRequest(hmi_apis::FunctionID::UI_DeleteCommand, &msg_params); + } + + if (BothSend() && !is_ui_received_) { + msg_params[strings::grammar_id] = app->get_grammar_id(); + msg_params[strings::type] = hmi_apis::Common_VRCommandType::Command; + SendHMIRequest(hmi_apis::FunctionID::VR_DeleteCommand, &msg_params); + } +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/add_command_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/add_command_response.cc new file mode 100644 index 0000000000..944b2883e8 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/add_command_response.cc @@ -0,0 +1,55 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/add_command_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +AddCommandResponse::AddCommandResponse(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +AddCommandResponse::~AddCommandResponse() {} + +void AddCommandResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/add_sub_menu_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/add_sub_menu_request.cc new file mode 100644 index 0000000000..fe44e5a41f --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/add_sub_menu_request.cc @@ -0,0 +1,161 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/add_sub_menu_request.h" + +#include "application_manager/message_helper.h" +#include "application_manager/application.h" +#include "utils/helpers.h" + +namespace application_manager { + +namespace commands { + +AddSubMenuRequest::AddSubMenuRequest(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +AddSubMenuRequest::~AddSubMenuRequest() {} + +void AddSubMenuRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + const int32_t menu_id = + (*message_)[strings::msg_params][strings::menu_id].asInt(); + if (app->FindSubMenu(menu_id)) { + LOG4CXX_ERROR(logger_, "Menu with id " << menu_id << " is not found."); + SendResponse(false, mobile_apis::Result::INVALID_ID); + return; + } + + const std::string& menu_name = + (*message_)[strings::msg_params][strings::menu_name].asString(); + + if (app->IsSubMenuNameAlreadyExist(menu_name)) { + LOG4CXX_ERROR(logger_, "Menu name " << menu_name << " is duplicated."); + SendResponse(false, mobile_apis::Result::DUPLICATE_NAME); + return; + } + + if (!CheckSubMenuName()) { + LOG4CXX_ERROR(logger_, "Sub-menu name is not valid."); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::menu_id] = + (*message_)[strings::msg_params][strings::menu_id]; + if ((*message_)[strings::msg_params].keyExists(strings::position)) { + msg_params[strings::menu_params][strings::position] = + (*message_)[strings::msg_params][strings::position]; + } + msg_params[strings::menu_params][strings::menu_name] = + (*message_)[strings::msg_params][strings::menu_name]; + msg_params[strings::app_id] = app->app_id(); + + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + SendHMIRequest(hmi_apis::FunctionID::UI_AddSubMenu, &msg_params, true); +} + +void AddSubMenuRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::UI_AddSubMenu: { + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + std::string response_info; + GetInfo(message, response_info); + const bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_UI); + + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + + if (!application) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + return; + } + + if (result) { + application->AddSubMenu( + (*message_)[strings::msg_params][strings::menu_id].asInt(), + (*message_)[strings::msg_params]); + } + SendResponse(result, + MessageHelper::HMIToMobileResult(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } +} + +bool AddSubMenuRequest::Init() { + hash_update_mode_ = HashUpdateMode::kDoHashUpdate; + return true; +} + +bool AddSubMenuRequest::CheckSubMenuName() { + LOG4CXX_AUTO_TRACE(logger_); + const char* str = NULL; + + str = (*message_)[strings::msg_params][strings::menu_name].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_INFO(logger_, "Invalid subMenu name."); + return false; + } + return true; +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/add_sub_menu_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/add_sub_menu_response.cc new file mode 100644 index 0000000000..de8739d871 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/add_sub_menu_response.cc @@ -0,0 +1,56 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/add_sub_menu_response.h" +#include "application_manager/rpc_service.h" +#include "application_manager/application_impl.h" + +namespace application_manager { + +namespace commands { + +AddSubMenuResponse::AddSubMenuResponse(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +AddSubMenuResponse::~AddSubMenuResponse() {} + +void AddSubMenuResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/alert_maneuver_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/alert_maneuver_request.cc new file mode 100644 index 0000000000..dee364cb99 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/alert_maneuver_request.cc @@ -0,0 +1,282 @@ +/* + Copyright (c) 2016, 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 <cstring> +#include <string> +#include "application_manager/commands/mobile/alert_maneuver_request.h" +#include "application_manager/application_impl.h" +#include "application_manager/policies/policy_handler.h" +#include "application_manager/message_helper.h" + +namespace application_manager { + +namespace commands { + +AlertManeuverRequest::AlertManeuverRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) + , tts_speak_result_code_(hmi_apis::Common_Result::INVALID_ENUM) + , navi_alert_maneuver_result_code_(hmi_apis::Common_Result::INVALID_ENUM) { + subscribe_on_event(hmi_apis::FunctionID::TTS_OnResetTimeout); +} + +AlertManeuverRequest::~AlertManeuverRequest() {} + +void AlertManeuverRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + if ((!(*message_)[strings::msg_params].keyExists(strings::soft_buttons)) && + (!(*message_)[strings::msg_params].keyExists(strings::tts_chunks))) { + LOG4CXX_ERROR(logger_, "AlertManeuverRequest::Request without parameters!"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + ApplicationSharedPtr app = application_manager_.application( + (*message_)[strings::params][strings::connection_key].asUInt()); + + if (NULL == app.get()) { + LOG4CXX_ERROR(logger_, "Application is not registered"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + if (IsWhiteSpaceExist()) { + LOG4CXX_ERROR(logger_, + "Incoming alert maneuver has contains \\t\\n \\\\t \\\\n" + "text contains only whitespace in ttsChunks"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + // ProcessSoftButtons checks strings on the contents incorrect character + + mobile_apis::Result::eType processing_result = + MessageHelper::ProcessSoftButtons((*message_)[strings::msg_params], + app, + application_manager_.GetPolicyHandler(), + application_manager_); + + if (mobile_apis::Result::SUCCESS != processing_result) { + LOG4CXX_ERROR(logger_, "Wrong soft buttons parameters!"); + SendResponse(false, processing_result); + return; + } + + // Checking parameters and how many HMI requests should be sent + bool tts_is_ok = false; + + // check TTSChunk parameter + if ((*message_)[strings::msg_params].keyExists(strings::tts_chunks)) { + smart_objects::SmartObject& tts_chunks = + (*message_)[strings::msg_params][strings::tts_chunks]; + mobile_apis::Result::eType verification_result = + MessageHelper::VerifyTtsFiles(tts_chunks, app, application_manager_); + + if (mobile_apis::Result::FILE_NOT_FOUND == verification_result) { + LOG4CXX_ERROR(logger_, + "MessageHelper::VerifyTtsFiles return " + << verification_result); + SendResponse(false, + mobile_apis::Result::FILE_NOT_FOUND, + "One or more files needed for tts_chunks are not present"); + return; + } + + if (0 < (*message_)[strings::msg_params][strings::tts_chunks].length()) { + pending_requests_.Add(hmi_apis::FunctionID::TTS_Speak); + tts_is_ok = true; + } + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::app_id] = app->app_id(); + + if ((*message_)[strings::msg_params].keyExists(strings::soft_buttons)) { + msg_params[hmi_request::soft_buttons] = + (*message_)[strings::msg_params][strings::soft_buttons]; + MessageHelper::SubscribeApplicationToSoftButton( + (*message_)[strings::msg_params], app, function_id()); + } + + pending_requests_.Add(hmi_apis::FunctionID::Navigation_AlertManeuver); + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_Navigation); + SendHMIRequest( + hmi_apis::FunctionID::Navigation_AlertManeuver, &msg_params, true); + + if (tts_is_ok) { + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + msg_params[hmi_request::tts_chunks] = + (*message_)[strings::msg_params][strings::tts_chunks]; + msg_params[hmi_request::speak_type] = + hmi_apis::Common_MethodName::ALERT_MANEUVER; + + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_TTS); + SendHMIRequest(hmi_apis::FunctionID::TTS_Speak, &msg_params, true); + } +} + +void AlertManeuverRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + hmi_apis::FunctionID::eType event_id = event.id(); + switch (event_id) { + case hmi_apis::FunctionID::Navigation_AlertManeuver: { + LOG4CXX_INFO(logger_, "Received Navigation_AlertManeuver event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_Navigation); + pending_requests_.Remove(event_id); + navi_alert_maneuver_result_code_ = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + GetInfo(message, info_navi_); + break; + } + case hmi_apis::FunctionID::TTS_Speak: { + LOG4CXX_INFO(logger_, "Received TTS_Speak event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_TTS); + pending_requests_.Remove(event_id); + tts_speak_result_code_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + GetInfo(message, info_tts_); + break; + } + case hmi_apis::FunctionID::TTS_OnResetTimeout: { + LOG4CXX_INFO(logger_, "Received TTS_OnResetTimeout event"); + + application_manager_.updateRequestTimeout( + connection_key(), correlation_id(), default_timeout()); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + SendResponse( + false, mobile_apis::Result::INVALID_ENUM, "Received unknown event"); + return; + } + } + + if (!pending_requests_.IsFinal(event_id)) { + LOG4CXX_DEBUG(logger_, + "There are some pending responses from HMI." + "AlertManeuverRequest still waiting."); + return; + } + std::string return_info; + mobile_apis::Result::eType result_code; + const bool result = PrepareResponseParameters(result_code, return_info); + bool must_be_empty_info = false; + if (return_info.find("\n") != std::string::npos || + return_info.find("\t") != std::string::npos) { + must_be_empty_info = true; + } + SendResponse(result, + result_code, + (must_be_empty_info) ? NULL : return_info.c_str(), + &(message[strings::msg_params])); +} + +bool AlertManeuverRequest::PrepareResponseParameters( + mobile_apis::Result::eType& result_code, std::string& return_info) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace helpers; + + application_manager::commands::ResponseInfo navigation_alert_info( + navi_alert_maneuver_result_code_, + HmiInterfaces::HMI_INTERFACE_Navigation, + application_manager_); + + application_manager::commands::ResponseInfo tts_alert_info( + tts_speak_result_code_, + HmiInterfaces::HMI_INTERFACE_TTS, + application_manager_); + const bool result = + PrepareResultForMobileResponse(navigation_alert_info, tts_alert_info); + + if (result && (hmi_apis::Common_Result::UNSUPPORTED_RESOURCE == + tts_speak_result_code_ && + (HmiInterfaces::STATE_AVAILABLE == + application_manager_.hmi_interfaces().GetInterfaceState( + HmiInterfaces::HMI_INTERFACE_TTS)))) { + result_code = mobile_apis::Result::WARNINGS; + return_info = std::string("Unsupported phoneme type sent in a prompt"); + return result; + } + result_code = + PrepareResultCodeForResponse(navigation_alert_info, tts_alert_info); + return_info = + MergeInfos(navigation_alert_info, info_navi_, tts_alert_info, info_tts_); + return result; +} + +bool AlertManeuverRequest::IsWhiteSpaceExist() { + LOG4CXX_AUTO_TRACE(logger_); + using smart_objects::SmartArray; + + if ((*message_)[strings::msg_params].keyExists(strings::tts_chunks)) { + const SmartArray* tts_chunks_arr = + (*message_)[strings::msg_params][strings::tts_chunks].asArray(); + + SmartArray::const_iterator it_tts_chunk = tts_chunks_arr->begin(); + + for (; it_tts_chunk != tts_chunks_arr->end(); ++it_tts_chunk) { + const char* tts_chunk_text = (*it_tts_chunk)[strings::text].asCharArray(); + if (strlen(tts_chunk_text) && !CheckSyntax(tts_chunk_text)) { + LOG4CXX_ERROR(logger_, "Invalid tts_chunks syntax check failed"); + return true; + } + } + } + if ((*message_)[strings::msg_params].keyExists(strings::soft_buttons)) { + DCHECK_OR_RETURN( + (*message_)[strings::msg_params][strings::soft_buttons].getType() == + smart_objects::SmartType_Array, + true); + const smart_objects::SmartArray* soft_button_array = + (*message_)[strings::msg_params][strings::soft_buttons].asArray(); + + SmartArray::const_iterator it_soft_button = soft_button_array->begin(); + + for (; it_soft_button != soft_button_array->end(); ++it_soft_button) { + const char* soft_button_text = + (*it_soft_button)[strings::text].asCharArray(); + if (!CheckSyntax(soft_button_text)) { + LOG4CXX_ERROR(logger_, "Invalid soft_buttons syntax check failed"); + return true; + } + } + } + + return false; +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/alert_maneuver_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/alert_maneuver_response.cc new file mode 100644 index 0000000000..852083e6ad --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/alert_maneuver_response.cc @@ -0,0 +1,56 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/alert_maneuver_response.h" +#include "application_manager/rpc_service.h" +#include "interfaces/HMI_API.h" + +namespace application_manager { + +namespace commands { + +AlertManeuverResponse::AlertManeuverResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +AlertManeuverResponse::~AlertManeuverResponse() {} + +void AlertManeuverResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/alert_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/alert_request.cc new file mode 100644 index 0000000000..e0cbe9e600 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/alert_request.cc @@ -0,0 +1,443 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/alert_request.h" + +#include <string.h> + +#include "application_manager/message_helper.h" +#include "application_manager/application_impl.h" + +#include "application_manager/policies/policy_handler.h" +#include "utils/helpers.h" +#include "smart_objects/smart_object.h" + +namespace application_manager { + +namespace commands { + +AlertRequest::AlertRequest(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) + , awaiting_ui_alert_response_(false) + , awaiting_tts_speak_response_(false) + , awaiting_tts_stop_speaking_response_(false) + , is_alert_succeeded_(false) + , is_ui_alert_sent_(false) + , alert_result_(hmi_apis::Common_Result::INVALID_ENUM) + , tts_speak_result_(hmi_apis::Common_Result::INVALID_ENUM) { + subscribe_on_event(hmi_apis::FunctionID::UI_OnResetTimeout); + subscribe_on_event(hmi_apis::FunctionID::TTS_OnResetTimeout); +} + +AlertRequest::~AlertRequest() {} + +bool AlertRequest::Init() { + /* Timeout in milliseconds. + If omitted a standard value of 10000 milliseconds is used.*/ + if ((*message_)[strings::msg_params].keyExists(strings::duration)) { + default_timeout_ = + (*message_)[strings::msg_params][strings::duration].asUInt(); + } else { + const int32_t def_value = 5000; + default_timeout_ = def_value; + } + + // If soft buttons are present, SDL will not use initiate timeout tracking for + // response. + if ((*message_)[strings::msg_params].keyExists(strings::soft_buttons)) { + LOG4CXX_INFO(logger_, + "Request contains soft buttons - request timeout " + "will be set to 0."); + default_timeout_ = 0; + } + + return true; +} + +void AlertRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + uint32_t app_id = + (*message_)[strings::params][strings::connection_key].asInt(); + + if (!Validate(app_id)) { + // Invalid command, abort execution + return; + } + bool tts_chunks_exists = + (*message_)[strings::msg_params].keyExists(strings::tts_chunks); + size_t length_tts_chunks = 0; + + if (tts_chunks_exists) { + length_tts_chunks = + (*message_)[strings::msg_params][strings::tts_chunks].length(); + } + + if ((tts_chunks_exists && length_tts_chunks) || + ((*message_)[strings::msg_params].keyExists(strings::play_tone) && + (*message_)[strings::msg_params][strings::play_tone].asBool())) { + awaiting_tts_speak_response_ = true; + } + + SendAlertRequest(app_id); + if (awaiting_tts_speak_response_) { + SendSpeakRequest(app_id, tts_chunks_exists, length_tts_chunks); + } +} + +void AlertRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::TTS_OnResetTimeout: + case hmi_apis::FunctionID::UI_OnResetTimeout: { + LOG4CXX_INFO(logger_, + "Received UI_OnResetTimeout event " + " or TTS_OnResetTimeout event" + << awaiting_tts_speak_response_ << " " + << awaiting_tts_stop_speaking_response_ << " " + << awaiting_ui_alert_response_); + application_manager_.updateRequestTimeout( + connection_key(), correlation_id(), default_timeout()); + break; + } + case hmi_apis::FunctionID::UI_Alert: { + LOG4CXX_INFO(logger_, "Received UI_Alert event"); + // Unsubscribe from event to avoid unwanted messages + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + unsubscribe_from_event(hmi_apis::FunctionID::UI_Alert); + awaiting_ui_alert_response_ = false; + HmiInterfaces::InterfaceState ui_interface_state = + application_manager_.hmi_interfaces().GetInterfaceState( + HmiInterfaces::HMI_INTERFACE_UI); + + if (awaiting_tts_speak_response_ && + HmiInterfaces::STATE_NOT_AVAILABLE != ui_interface_state) { + awaiting_tts_stop_speaking_response_ = true; + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_TTS); + SendHMIRequest(hmi_apis::FunctionID::TTS_StopSpeaking, NULL, true); + } + alert_result_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + + // Mobile Alert request is successful when UI_Alert is successful + alert_response_params_ = message[strings::msg_params]; + GetInfo(message, ui_response_info_); + break; + } + case hmi_apis::FunctionID::TTS_Speak: { + LOG4CXX_INFO(logger_, "Received TTS_Speak event"); + // Unsubscribe from event to avoid unwanted messages + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_TTS); + unsubscribe_from_event(hmi_apis::FunctionID::TTS_Speak); + awaiting_tts_speak_response_ = false; + tts_speak_result_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + GetInfo(message, tts_response_info_); + break; + } + case hmi_apis::FunctionID::TTS_StopSpeaking: { + LOG4CXX_INFO(logger_, "Received TTS_StopSpeaking event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_TTS); + // Unsubscribe from event to avoid unwanted messages + unsubscribe_from_event(hmi_apis::FunctionID::TTS_StopSpeaking); + awaiting_tts_stop_speaking_response_ = false; + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } + + if (HasHmiResponsesToWait()) { + return; + } + mobile_apis::Result::eType result_code = mobile_apis::Result::INVALID_ENUM; + std::string info; + const bool result = PrepareResponseParameters(result_code, info); + SendResponse(result, + result_code, + info.empty() ? NULL : info.c_str(), + &alert_response_params_); +} + +bool AlertRequest::PrepareResponseParameters( + mobile_apis::Result::eType& result_code, std::string& info) { + ResponseInfo ui_alert_info( + alert_result_, HmiInterfaces::HMI_INTERFACE_UI, application_manager_); + ResponseInfo tts_alert_info(tts_speak_result_, + HmiInterfaces::HMI_INTERFACE_TTS, + application_manager_); + + bool result = PrepareResultForMobileResponse(ui_alert_info, tts_alert_info); + + /* result=false if UI interface is ok and TTS interface = UNSUPPORTED_RESOURCE + * and sdl receive TTS.IsReady=true or SDL doesn't receive responce for + * TTS.IsReady. + */ + if (result && ui_alert_info.is_ok && tts_alert_info.is_unsupported_resource && + HmiInterfaces::STATE_NOT_AVAILABLE != tts_alert_info.interface_state) { + result = false; + } + result_code = mobile_apis::Result::WARNINGS; + if ((ui_alert_info.is_ok || ui_alert_info.is_not_used) && + tts_alert_info.is_unsupported_resource && + HmiInterfaces::STATE_AVAILABLE == tts_alert_info.interface_state) { + tts_response_info_ = "Unsupported phoneme type sent in a prompt"; + info = MergeInfos( + ui_alert_info, ui_response_info_, tts_alert_info, tts_response_info_); + return result; + } + result_code = PrepareResultCodeForResponse(ui_alert_info, tts_alert_info); + info = MergeInfos( + ui_alert_info, ui_response_info_, tts_alert_info, tts_response_info_); + // Mobile Alert request is successful when UI_Alert is successful + if (is_ui_alert_sent_ && !ui_alert_info.is_ok) { + return false; + } + return result; +} + +bool AlertRequest::Validate(uint32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr app = application_manager_.application(app_id); + + if (!app) { + LOG4CXX_ERROR(logger_, "No application associated with session key"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return false; + } + + if (mobile_apis::HMILevel::HMI_BACKGROUND == app->hmi_level() && + app->AreCommandLimitsExceeded( + static_cast<mobile_apis::FunctionID::eType>(function_id()), + application_manager::TLimitSource::POLICY_TABLE)) { + LOG4CXX_ERROR(logger_, "Alert frequency is too high."); + SendResponse(false, mobile_apis::Result::REJECTED); + return false; + } + + if (!CheckStringsOfAlertRequest()) { + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return false; + } + + // ProcessSoftButtons checks strings on the contents incorrect character + + mobile_apis::Result::eType processing_result = + MessageHelper::ProcessSoftButtons((*message_)[strings::msg_params], + app, + application_manager_.GetPolicyHandler(), + application_manager_); + + if (mobile_apis::Result::SUCCESS != processing_result) { + LOG4CXX_ERROR(logger_, "INVALID_DATA!"); + SendResponse(false, processing_result); + return false; + } + + // check if mandatory params(alertText1 and TTSChunk) specified + if ((!(*message_)[strings::msg_params].keyExists(strings::alert_text1)) && + (!(*message_)[strings::msg_params].keyExists(strings::alert_text2)) && + (!(*message_)[strings::msg_params].keyExists(strings::tts_chunks) && + (1 > (*message_)[strings::msg_params][strings::tts_chunks].length()))) { + LOG4CXX_ERROR(logger_, "Mandatory parameters are missing"); + SendResponse(false, + mobile_apis::Result::INVALID_DATA, + "Mandatory parameters are missing"); + return false; + } + + if ((*message_)[strings::msg_params].keyExists(strings::tts_chunks)) { + smart_objects::SmartObject& tts_chunks = + (*message_)[strings::msg_params][strings::tts_chunks]; + mobile_apis::Result::eType verification_result = + MessageHelper::VerifyTtsFiles(tts_chunks, app, application_manager_); + + if (mobile_apis::Result::FILE_NOT_FOUND == verification_result) { + LOG4CXX_ERROR(logger_, + "MessageHelper::VerifyTtsFiles return " + << verification_result); + SendResponse(false, + mobile_apis::Result::FILE_NOT_FOUND, + "One or more files needed for tts_chunks are not present"); + return false; + } + } + + return true; +} + +void AlertRequest::SendAlertRequest(int32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr app = application_manager_.application(app_id); + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + msg_params[hmi_request::alert_strings] = + smart_objects::SmartObject(smart_objects::SmartType_Array); + + int32_t index = 0; + if ((*message_)[strings::msg_params].keyExists(strings::alert_text1)) { + msg_params[hmi_request::alert_strings][index][hmi_request::field_name] = + hmi_apis::Common_TextFieldName::alertText1; + msg_params[hmi_request::alert_strings][index][hmi_request::field_text] = + (*message_)[strings::msg_params][strings::alert_text1]; + index++; + } + if ((*message_)[strings::msg_params].keyExists(strings::alert_text2)) { + msg_params[hmi_request::alert_strings][index][hmi_request::field_name] = + hmi_apis::Common_TextFieldName::alertText2; + msg_params[hmi_request::alert_strings][index][hmi_request::field_text] = + (*message_)[strings::msg_params][strings::alert_text2]; + index++; + } + if ((*message_)[strings::msg_params].keyExists(strings::alert_text3)) { + msg_params[hmi_request::alert_strings][index][hmi_request::field_name] = + hmi_apis::Common_TextFieldName::alertText3; + msg_params[hmi_request::alert_strings][index][hmi_request::field_text] = + (*message_)[strings::msg_params][strings::alert_text3]; + } + + // softButtons + if ((*message_)[strings::msg_params].keyExists(strings::soft_buttons)) { + msg_params[hmi_request::soft_buttons] = + (*message_)[strings::msg_params][strings::soft_buttons]; + MessageHelper::SubscribeApplicationToSoftButton( + (*message_)[strings::msg_params], app, function_id()); + } + // app_id + msg_params[strings::app_id] = app_id; + msg_params[strings::duration] = default_timeout_; + + // NAVI platform progressIndicator + if ((*message_)[strings::msg_params].keyExists(strings::progress_indicator)) { + msg_params[strings::progress_indicator] = + (*message_)[strings::msg_params][strings::progress_indicator]; + } + + // PASA Alert type + msg_params[strings::alert_type] = hmi_apis::Common_AlertType::UI; + if (awaiting_tts_speak_response_) { + msg_params[strings::alert_type] = hmi_apis::Common_AlertType::BOTH; + } + + // check out if there are alert strings or soft buttons + if (msg_params[hmi_request::alert_strings].length() > 0 || + msg_params.keyExists(hmi_request::soft_buttons)) { + awaiting_ui_alert_response_ = true; + is_ui_alert_sent_ = true; + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + SendHMIRequest(hmi_apis::FunctionID::UI_Alert, &msg_params, true); + } +} + +void AlertRequest::SendSpeakRequest(int32_t app_id, + bool tts_chunks_exists, + size_t length_tts_chunks) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace hmi_apis; + using namespace smart_objects; + // crate HMI speak request + SmartObject msg_params = smart_objects::SmartObject(SmartType_Map); + if (tts_chunks_exists && length_tts_chunks) { + msg_params[hmi_request::tts_chunks] = + smart_objects::SmartObject(SmartType_Array); + msg_params[hmi_request::tts_chunks] = + (*message_)[strings::msg_params][strings::tts_chunks]; + } + if ((*message_)[strings::msg_params].keyExists(strings::play_tone) && + (*message_)[strings::msg_params][strings::play_tone].asBool()) { + msg_params[strings::play_tone] = true; + } + msg_params[strings::app_id] = app_id; + msg_params[hmi_request::speak_type] = Common_MethodName::ALERT; + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_TTS); + SendHMIRequest(FunctionID::TTS_Speak, &msg_params, true); +} + +bool AlertRequest::CheckStringsOfAlertRequest() { + LOG4CXX_AUTO_TRACE(logger_); + const char* str = NULL; + + if ((*message_)[strings::msg_params].keyExists(strings::alert_text1)) { + str = (*message_)[strings::msg_params][strings::alert_text1].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid alert_text_1 syntax check failed"); + return false; + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::alert_text2)) { + str = (*message_)[strings::msg_params][strings::alert_text2].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid alert_text_2 syntax check failed"); + return false; + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::alert_text3)) { + str = (*message_)[strings::msg_params][strings::alert_text3].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid alert_text_3 syntax check failed"); + return false; + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::tts_chunks)) { + smart_objects::SmartObject& tts_chunks_array = + (*message_)[strings::msg_params][strings::tts_chunks]; + for (size_t i = 0; i < tts_chunks_array.length(); ++i) { + str = tts_chunks_array[i][strings::text].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid tts_chunks text syntax check failed"); + return false; + } + } + } + return true; +} + +bool AlertRequest::HasHmiResponsesToWait() { + LOG4CXX_AUTO_TRACE(logger_); + return awaiting_ui_alert_response_ || awaiting_tts_speak_response_ || + awaiting_tts_stop_speaking_response_; +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/alert_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/alert_response.cc new file mode 100644 index 0000000000..3b9e67fefa --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/alert_response.cc @@ -0,0 +1,58 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/alert_response.h" +#include "application_manager/rpc_service.h" +#include "application_manager/application_impl.h" +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" + +namespace application_manager { + +namespace commands { + +AlertResponse::AlertResponse(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +AlertResponse::~AlertResponse() {} + +void AlertResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/change_registration_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/change_registration_request.cc new file mode 100644 index 0000000000..06027a42db --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/change_registration_request.cc @@ -0,0 +1,678 @@ +/* + + Copyright (c) 2016, 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 <string.h> +#include <algorithm> +#include "application_manager/commands/mobile/change_registration_request.h" +#include "application_manager/application_manager.h" +#include "application_manager/application_impl.h" +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" +#include "application_manager/message_helper.h" + +namespace { +namespace custom_str = utils::custom_string; +struct IsSameNickname { + IsSameNickname(const custom_str::CustomString& app_id) : app_id_(app_id) {} + bool operator()(const policy::StringArray::value_type& nickname) const { + return app_id_.CompareIgnoreCase(nickname.c_str()); + } + + private: + const custom_str::CustomString& app_id_; +}; +} + +namespace application_manager { + +namespace commands { + +ChangeRegistrationRequest::ChangeRegistrationRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) + , ui_result_(hmi_apis::Common_Result::INVALID_ENUM) + , vr_result_(hmi_apis::Common_Result::INVALID_ENUM) + , tts_result_(hmi_apis::Common_Result::INVALID_ENUM) {} + +ChangeRegistrationRequest::~ChangeRegistrationRequest() {} + +void ChangeRegistrationRequest::SendVRRequest( + ApplicationSharedPtr app, smart_objects::SmartObject& msg_params) { + const HmiInterfaces& hmi_interfaces = application_manager_.hmi_interfaces(); + auto function = hmi_apis::FunctionID::VR_ChangeRegistration; + pending_requests_.Add(function); + smart_objects::SmartObject vr_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + vr_params[strings::language] = msg_params[strings::language]; + + vr_params[strings::app_id] = app->app_id(); + if (msg_params.keyExists(strings::vr_synonyms)) { + vr_params[strings::vr_synonyms] = msg_params[strings::vr_synonyms]; + app->set_vr_synonyms(msg_params[strings::vr_synonyms]); + } + StartAwaitForInterface(hmi_interfaces.GetInterfaceFromFunction(function)); + SendHMIRequest(function, &vr_params, true); +} + +void ChangeRegistrationRequest::SendTTSRequest( + ApplicationSharedPtr app, smart_objects::SmartObject& msg_params) { + const HmiInterfaces& hmi_interfaces = application_manager_.hmi_interfaces(); + auto function = hmi_apis::FunctionID::TTS_ChangeRegistration; + pending_requests_.Add(function); + + smart_objects::SmartObject tts_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + tts_params[strings::language] = msg_params[strings::language]; + + tts_params[strings::app_id] = app->app_id(); + if (msg_params.keyExists(strings::tts_name)) { + tts_params[strings::tts_name] = msg_params[strings::tts_name]; + app->set_tts_name(msg_params[strings::tts_name]); + } + StartAwaitForInterface(hmi_interfaces.GetInterfaceFromFunction(function)); + SendHMIRequest(function, &tts_params, true); +} + +void ChangeRegistrationRequest::SendUIRequest( + ApplicationSharedPtr app, + smart_objects::SmartObject& msg_params, + const int32_t hmi_language) { + const HmiInterfaces& hmi_interfaces = application_manager_.hmi_interfaces(); + auto function = hmi_apis::FunctionID::UI_ChangeRegistration; + pending_requests_.Add(function); + // UI processing + smart_objects::SmartObject ui_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + ui_params[strings::language] = hmi_language; + ui_params[strings::app_id] = app->app_id(); + if (msg_params.keyExists(strings::app_name)) { + ui_params[strings::app_name] = msg_params[strings::app_name]; + app->set_name(msg_params[strings::app_name].asCustomString()); + } + if (msg_params.keyExists(strings::ngn_media_screen_app_name)) { + ui_params[strings::ngn_media_screen_app_name] = + msg_params[strings::ngn_media_screen_app_name]; + app->set_ngn_media_screen_name( + msg_params[strings::ngn_media_screen_app_name]); + } + + StartAwaitForInterface(hmi_interfaces.GetInterfaceFromFunction(function)); + SendHMIRequest(function, &ui_params, true); +} + +void ChangeRegistrationRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + using namespace smart_objects; + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + if (IsWhiteSpaceExist()) { + LOG4CXX_INFO(logger_, + "Incoming request contains \t\n \\t \\n or whitespace"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + if (mobile_apis::Result::SUCCESS != CheckCoincidence()) { + SendResponse(false, mobile_apis::Result::DUPLICATE_NAME); + return; + } + + SmartObject& msg_params = (*message_)[strings::msg_params]; + + const int32_t hmi_language = + msg_params[strings::hmi_display_language].asInt(); + + const int32_t language = msg_params[strings::language].asInt(); + + if (false == (IsLanguageSupportedByUI(hmi_language) && + IsLanguageSupportedByVR(language) && + IsLanguageSupportedByTTS(language))) { + LOG4CXX_ERROR(logger_, "Language is not supported"); + SendResponse(false, mobile_apis::Result::REJECTED); + return; + } + + if (msg_params.keyExists(strings::app_name) && + !IsNicknameAllowed(msg_params[strings::app_name].asCustomString())) { + LOG4CXX_ERROR(logger_, "Nickname is not allowed."); + SendResponse(false, mobile_apis::Result::DISALLOWED); + return; + } + + if ((*message_)[strings::msg_params].keyExists(strings::tts_name)) { + smart_objects::SmartObject& tts_name = + (*message_)[strings::msg_params][strings::tts_name]; + mobile_apis::Result::eType verification_result = + MessageHelper::VerifyTtsFiles(tts_name, app, application_manager_); + + if (mobile_apis::Result::FILE_NOT_FOUND == verification_result) { + LOG4CXX_ERROR(logger_, + "MessageHelper::VerifyTtsFiles return " + << verification_result); + SendResponse(false, + mobile_apis::Result::FILE_NOT_FOUND, + "One or more files needed for tts_name are not present"); + return; + } + } + + const HmiInterfaces& hmi_interfaces = application_manager_.hmi_interfaces(); + + const HmiInterfaces::InterfaceState vr_state = + hmi_interfaces.GetInterfaceState( + HmiInterfaces::InterfaceID::HMI_INTERFACE_VR); + const HmiInterfaces::InterfaceState ui_state = + hmi_interfaces.GetInterfaceState( + HmiInterfaces::InterfaceID::HMI_INTERFACE_UI); + const HmiInterfaces::InterfaceState tts_state = + hmi_interfaces.GetInterfaceState( + HmiInterfaces::InterfaceID::HMI_INTERFACE_TTS); + + using helpers::Compare; + using helpers::EQ; + using helpers::ALL; + + if (Compare<HmiInterfaces::InterfaceState, EQ, ALL>( + HmiInterfaces::InterfaceState::STATE_NOT_AVAILABLE, + vr_state, + tts_state, + ui_state)) { + SendResponse(false, mobile_apis::Result::UNSUPPORTED_RESOURCE); + return; + } + if (HmiInterfaces::InterfaceState::STATE_NOT_AVAILABLE != vr_state) { + // VR processing + SendVRRequest(app, msg_params); + } + if (HmiInterfaces::InterfaceState::STATE_NOT_AVAILABLE != tts_state) { + // TTS processing + SendTTSRequest(app, msg_params); + } + + if (HmiInterfaces::InterfaceState::STATE_NOT_AVAILABLE != ui_state) { + SendUIRequest(app, msg_params, hmi_language); + } +} + +void ChangeRegistrationRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + + hmi_apis::FunctionID::eType event_id = event.id(); + + switch (event_id) { + case hmi_apis::FunctionID::UI_ChangeRegistration: { + LOG4CXX_INFO(logger_, "Received UI_ChangeRegistration event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + pending_requests_.Remove(event_id); + ui_result_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + GetInfo(message, ui_response_info_); + break; + } + case hmi_apis::FunctionID::VR_ChangeRegistration: { + LOG4CXX_INFO(logger_, "Received VR_ChangeRegistration event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VR); + pending_requests_.Remove(event_id); + vr_result_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + GetInfo(message, vr_response_info_); + break; + } + case hmi_apis::FunctionID::TTS_ChangeRegistration: { + LOG4CXX_INFO(logger_, "Received TTS_ChangeRegistration event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_TTS); + pending_requests_.Remove(event_id); + tts_result_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + GetInfo(message, tts_response_info_); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event_id); + return; + } + } + + if (pending_requests_.IsFinal(event_id)) { + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + + if (!application) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + return; + } + + if (hmi_apis::Common_Result::SUCCESS == ui_result_) { + application->set_ui_language(static_cast<mobile_api::Language::eType>( + (*message_)[strings::msg_params][strings::hmi_display_language] + .asInt())); + } + + if (hmi_apis::Common_Result::SUCCESS == vr_result_ || + hmi_apis::Common_Result::SUCCESS == tts_result_) { + application->set_language(static_cast<mobile_api::Language::eType>( + (*message_)[strings::msg_params][strings::language].asInt())); + } + mobile_apis::Result::eType result_code = mobile_apis::Result::INVALID_ENUM; + std::string response_info; + const bool result = PrepareResponseParameters(result_code, response_info); + + (*message_)[strings::params][strings::function_id] = + mobile_apis::FunctionID::eType::ChangeRegistrationID; + + SendResponse(result, + result_code, + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + } else { + LOG4CXX_INFO(logger_, + "There are some pending responses from HMI." + "ChangeRegistrationRequest still waiting."); + } +} + +namespace { +void CheckInfo(std::string& str) { + if (std::string::npos != str.find("is not supported by system")) { + str.clear(); + } +} +} // namespace + +bool ChangeRegistrationRequest::PrepareResponseParameters( + mobile_apis::Result::eType& result_code, std::string& response_info) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace helpers; + const bool is_tts_succeeded_unsupported = + Compare<hmi_apis::Common_Result::eType, EQ, ONE>( + tts_result_, + hmi_apis::Common_Result::SUCCESS, + hmi_apis::Common_Result::WARNINGS, + hmi_apis::Common_Result::WRONG_LANGUAGE, + hmi_apis::Common_Result::RETRY, + hmi_apis::Common_Result::SAVED, + hmi_apis::Common_Result::UNSUPPORTED_RESOURCE); + + const bool is_ui_succeeded_unsupported = + Compare<hmi_apis::Common_Result::eType, EQ, ONE>( + ui_result_, + hmi_apis::Common_Result::SUCCESS, + hmi_apis::Common_Result::WARNINGS, + hmi_apis::Common_Result::WRONG_LANGUAGE, + hmi_apis::Common_Result::RETRY, + hmi_apis::Common_Result::SAVED, + hmi_apis::Common_Result::UNSUPPORTED_RESOURCE); + + const bool is_vr_succeeded_unsupported = + Compare<hmi_apis::Common_Result::eType, EQ, ONE>( + vr_result_, + hmi_apis::Common_Result::SUCCESS, + hmi_apis::Common_Result::WARNINGS, + hmi_apis::Common_Result::WRONG_LANGUAGE, + hmi_apis::Common_Result::RETRY, + hmi_apis::Common_Result::SAVED, + hmi_apis::Common_Result::UNSUPPORTED_RESOURCE); + + const bool is_tts_ui_vr_unsupported = + Compare<hmi_apis::Common_Result::eType, EQ, ALL>( + hmi_apis::Common_Result::UNSUPPORTED_RESOURCE, + tts_result_, + ui_result_, + vr_result_); + + const HmiInterfaces& hmi_interfaces = application_manager_.hmi_interfaces(); + const HmiInterfaces::InterfaceState tts_state = + hmi_interfaces.GetInterfaceState( + HmiInterfaces::InterfaceID::HMI_INTERFACE_TTS); + const HmiInterfaces::InterfaceState vr_state = + hmi_interfaces.GetInterfaceState( + HmiInterfaces::InterfaceID::HMI_INTERFACE_VR); + const HmiInterfaces::InterfaceState ui_state = + hmi_interfaces.GetInterfaceState( + HmiInterfaces::InterfaceID::HMI_INTERFACE_UI); + + ResponseInfo ui_properties_info( + ui_result_, HmiInterfaces::HMI_INTERFACE_UI, application_manager_); + + ResponseInfo tts_properties_info( + tts_result_, HmiInterfaces::HMI_INTERFACE_TTS, application_manager_); + + ResponseInfo vr_properties_info( + ui_result_, HmiInterfaces::HMI_INTERFACE_VR, application_manager_); + + bool result = ((!is_tts_ui_vr_unsupported) && is_tts_succeeded_unsupported && + is_ui_succeeded_unsupported && is_vr_succeeded_unsupported); + + const bool is_tts_or_ui_or_vr_unsupported = + Compare<hmi_apis::Common_Result::eType, EQ, ONE>( + hmi_apis::Common_Result::UNSUPPORTED_RESOURCE, + tts_result_, + ui_result_, + vr_result_); + + if ((result && is_tts_or_ui_or_vr_unsupported)) { + result_code = mobile_apis::Result::UNSUPPORTED_RESOURCE; + result = + PrepareResultForMobileResponse(ui_properties_info, + tts_properties_info) && + PrepareResultForMobileResponse(tts_properties_info, vr_properties_info); + } else { + // If response contains erroneous result code SDL need return erroneus + // result code. + hmi_apis::Common_Result::eType ui_result = + hmi_apis::Common_Result::INVALID_ENUM; + hmi_apis::Common_Result::eType vr_result = + hmi_apis::Common_Result::INVALID_ENUM; + hmi_apis::Common_Result::eType tts_result = + hmi_apis::Common_Result::INVALID_ENUM; + if (hmi_apis::Common_Result::UNSUPPORTED_RESOURCE != ui_result_) { + ui_result = ui_result_; + } + if (hmi_apis::Common_Result::UNSUPPORTED_RESOURCE != vr_result_) { + vr_result = vr_result_; + } + if (hmi_apis::Common_Result::UNSUPPORTED_RESOURCE != tts_result_) { + tts_result = tts_result_; + } + result_code = MessageHelper::HMIToMobileResult( + std::max(std::max(ui_result, vr_result), tts_result)); + if (mobile_api::Result::INVALID_ENUM == result_code) { + result_code = mobile_api::Result::UNSUPPORTED_RESOURCE; + } + } + + const bool is_tts_state_available = + tts_state == HmiInterfaces::STATE_AVAILABLE; + const bool is_vr_state_available = vr_state == HmiInterfaces::STATE_AVAILABLE; + const bool is_ui_state_available = ui_state == HmiInterfaces::STATE_AVAILABLE; + + const bool is_tts_hmi_info = + is_tts_state_available && !tts_response_info_.empty(); + const bool is_vr_hmi_info = + is_vr_state_available && !vr_response_info_.empty(); + const bool is_ui_hmi_info = + is_ui_state_available && !ui_response_info_.empty(); + + if (is_tts_hmi_info || is_vr_hmi_info || is_ui_hmi_info) { + if (!is_tts_hmi_info) + CheckInfo(tts_response_info_); + if (!is_vr_hmi_info) + CheckInfo(ui_response_info_); + if (!is_ui_hmi_info) + CheckInfo(vr_response_info_); + } + + response_info = + MergeInfos(ui_response_info_, vr_response_info_, tts_response_info_); + return result; +} + +bool ChangeRegistrationRequest::IsLanguageSupportedByUI( + const int32_t& hmi_display_lang) { + const HMICapabilities& hmi_capabilities = + application_manager_.hmi_capabilities(); + const smart_objects::SmartObject* ui_languages = + hmi_capabilities.ui_supported_languages(); + + if (!ui_languages) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + return false; + } + + for (size_t i = 0; i < ui_languages->length(); ++i) { + if (hmi_display_lang == ui_languages->getElement(i).asInt()) { + return true; + } + } + + LOG4CXX_ERROR(logger_, "Language isn't supported by UI"); + + return false; +} + +bool ChangeRegistrationRequest::IsLanguageSupportedByVR( + const int32_t& hmi_display_lang) { + const HMICapabilities& hmi_capabilities = + application_manager_.hmi_capabilities(); + const smart_objects::SmartObject* vr_languages = + hmi_capabilities.vr_supported_languages(); + + if (!vr_languages) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + return false; + } + + for (size_t i = 0; i < vr_languages->length(); ++i) { + if (hmi_display_lang == vr_languages->getElement(i).asInt()) { + return true; + } + } + + LOG4CXX_ERROR(logger_, "Language isn't supported by VR"); + + return false; +} + +bool ChangeRegistrationRequest::IsLanguageSupportedByTTS( + const int32_t& hmi_display_lang) { + const HMICapabilities& hmi_capabilities = + application_manager_.hmi_capabilities(); + const smart_objects::SmartObject* tts_languages = + hmi_capabilities.tts_supported_languages(); + + if (!tts_languages) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + return false; + } + + for (size_t i = 0; i < tts_languages->length(); ++i) { + if (hmi_display_lang == tts_languages->getElement(i).asInt()) { + return true; + break; + } + } + + LOG4CXX_ERROR(logger_, "Language isn't supported by TTS"); + return false; +} + +bool ChangeRegistrationRequest::IsWhiteSpaceExist() { + const char* str = NULL; + + if ((*message_)[strings::msg_params].keyExists(strings::app_name)) { + str = (*message_)[strings::msg_params][strings::app_name].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid app_name syntax check failed"); + return true; + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::tts_name)) { + const smart_objects::SmartArray* tn_array = + (*message_)[strings::msg_params][strings::tts_name].asArray(); + + smart_objects::SmartArray::const_iterator it_tn = tn_array->begin(); + smart_objects::SmartArray::const_iterator it_tn_end = tn_array->end(); + + for (; it_tn != it_tn_end; ++it_tn) { + str = (*it_tn)[strings::text].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid tts_name syntax check failed"); + return true; + } + } + } + + if ((*message_)[strings::msg_params].keyExists( + strings::ngn_media_screen_app_name)) { + str = (*message_)[strings::msg_params][strings::ngn_media_screen_app_name] + .asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid ngn_media_screen_app_name syntax check failed"); + return true; + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::vr_synonyms)) { + const smart_objects::SmartArray* vs_array = + (*message_)[strings::msg_params][strings::vr_synonyms].asArray(); + + smart_objects::SmartArray::const_iterator it_vs = vs_array->begin(); + smart_objects::SmartArray::const_iterator it_vs_end = vs_array->end(); + + for (; it_vs != it_vs_end; ++it_vs) { + str = (*it_vs).asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid vr_synonyms syntax check failed"); + return true; + } + } + } + return false; +} + +mobile_apis::Result::eType ChangeRegistrationRequest::CheckCoincidence() { + LOG4CXX_AUTO_TRACE(logger_); + + const smart_objects::SmartObject& msg_params = + (*message_)[strings::msg_params]; + + ApplicationSet accessor = application_manager_.applications().GetData(); + custom_str::CustomString app_name; + uint32_t app_id = connection_key(); + if (msg_params.keyExists(strings::app_name)) { + app_name = msg_params[strings::app_name].asCustomString(); + } + + ApplicationSetConstIt it = accessor.begin(); + for (; accessor.end() != it; ++it) { + if (app_id == (*it)->app_id()) { + continue; + } + + const custom_str::CustomString& cur_name = (*it)->name(); + if (msg_params.keyExists(strings::app_name)) { + if (app_name.CompareIgnoreCase(cur_name)) { + LOG4CXX_ERROR(logger_, "Application name is known already."); + return mobile_apis::Result::DUPLICATE_NAME; + } + + const smart_objects::SmartObject* vr = (*it)->vr_synonyms(); + const std::vector<smart_objects::SmartObject>* curr_vr = NULL; + if (NULL != vr) { + curr_vr = vr->asArray(); + CoincidencePredicateVR v(app_name); + + if (0 != std::count_if(curr_vr->begin(), curr_vr->end(), v)) { + LOG4CXX_ERROR(logger_, "Application name is known already."); + return mobile_apis::Result::DUPLICATE_NAME; + } + } + } + + // vr check + if (msg_params.keyExists(strings::vr_synonyms)) { + const std::vector<smart_objects::SmartObject>* new_vr = + msg_params[strings::vr_synonyms].asArray(); + + CoincidencePredicateVR v(cur_name); + if (0 != std::count_if(new_vr->begin(), new_vr->end(), v)) { + LOG4CXX_ERROR(logger_, "vr_synonyms duplicated with app_name ."); + return mobile_apis::Result::DUPLICATE_NAME; + } + } // end vr check + } // application for end + return mobile_apis::Result::SUCCESS; +} + +bool ChangeRegistrationRequest::IsNicknameAllowed( + const custom_str::CustomString& app_name) const { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, + "Can't find appication with connection key " + << connection_key()); + return false; + } + + const std::string policy_app_id = app->policy_app_id(); + + policy::StringArray app_nicknames; + policy::StringArray app_hmi_types; + + bool init_result = application_manager_.GetPolicyHandler().GetInitialAppData( + policy_app_id, &app_nicknames, &app_hmi_types); + + if (!init_result) { + LOG4CXX_ERROR(logger_, + "Error during getting of nickname list for application " + << policy_app_id); + return false; + } + + if (!app_nicknames.empty()) { + IsSameNickname compare(app_name); + policy::StringArray::const_iterator it = + std::find_if(app_nicknames.begin(), app_nicknames.end(), compare); + if (app_nicknames.end() == it) { + LOG4CXX_WARN(logger_, + "Application name was not found in nicknames list."); + + usage_statistics::AppCounter count_of_rejections_nickname_mismatch( + application_manager_.GetPolicyHandler().GetStatisticManager(), + policy_app_id, + usage_statistics::REJECTIONS_NICKNAME_MISMATCH); + ++count_of_rejections_nickname_mismatch; + + return false; + } + } + return true; +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/change_registration_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/change_registration_response.cc new file mode 100644 index 0000000000..77c063ac9d --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/change_registration_response.cc @@ -0,0 +1,55 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/change_registration_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +ChangeRegistrationResponse::ChangeRegistrationResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +ChangeRegistrationResponse::~ChangeRegistrationResponse() {} + +void ChangeRegistrationResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_interaction_choice_set_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_interaction_choice_set_request.cc new file mode 100644 index 0000000000..20387ef230 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_interaction_choice_set_request.cc @@ -0,0 +1,442 @@ +/* + + Copyright (c) 2016, 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 <string> +#include <cstring> +#include <algorithm> +#include <vector> +#include "application_manager/commands/mobile/create_interaction_choice_set_request.h" + +#include "application_manager/application_impl.h" +#include "application_manager/message_helper.h" +#include "utils/gen_hash.h" +#include "utils/helpers.h" + +namespace application_manager { + +namespace commands { + +CreateInteractionChoiceSetRequest::CreateInteractionChoiceSetRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) + , choice_set_id_(0) + , expected_chs_count_(0) + , received_chs_count_(0) + , error_from_hmi_(false) + , is_timed_out_(false) + , vr_commands_lock_(true) {} + +CreateInteractionChoiceSetRequest::~CreateInteractionChoiceSetRequest() { + LOG4CXX_AUTO_TRACE(logger_); +} + +void CreateInteractionChoiceSetRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + using namespace mobile_apis; + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + for (uint32_t i = 0; + i < (*message_)[strings::msg_params][strings::choice_set].length(); + ++i) { + Result::eType verification_result_image = Result::SUCCESS; + Result::eType verification_result_secondary_image = Result::SUCCESS; + if ((*message_)[strings::msg_params][strings::choice_set][i].keyExists( + strings::image)) { + verification_result_image = MessageHelper::VerifyImage( + (*message_)[strings::msg_params][strings::choice_set][i] + [strings::image], + app, + application_manager_); + } + if ((*message_)[strings::msg_params][strings::choice_set][i].keyExists( + strings::secondary_image)) { + verification_result_secondary_image = MessageHelper::VerifyImage( + (*message_)[strings::msg_params][strings::choice_set][i] + [strings::secondary_image], + app, + application_manager_); + } + if (verification_result_image == Result::INVALID_DATA || + verification_result_secondary_image == Result::INVALID_DATA) { + LOG4CXX_ERROR(logger_, "Image verification failed."); + SendResponse(false, Result::INVALID_DATA); + return; + } + } + + choice_set_id_ = + (*message_)[strings::msg_params][strings::interaction_choice_set_id] + .asInt(); + + if (app->FindChoiceSet(choice_set_id_)) { + LOG4CXX_ERROR(logger_, + "Choice set with id " << choice_set_id_ << " is not found."); + SendResponse(false, Result::INVALID_ID); + return; + } + + Result::eType result = CheckChoiceSet(app); + if (Result::SUCCESS != result) { + SendResponse(false, result); + return; + } + uint32_t grammar_id = application_manager_.GenerateGrammarID(); + (*message_)[strings::msg_params][strings::grammar_id] = grammar_id; + app->AddChoiceSet(choice_set_id_, (*message_)[strings::msg_params]); + SendVRAddCommandRequests(app); +} + +mobile_apis::Result::eType CreateInteractionChoiceSetRequest::CheckChoiceSet( + ApplicationConstSharedPtr app) { + using namespace smart_objects; + LOG4CXX_AUTO_TRACE(logger_); + + std::set<uint32_t> choice_id_set; + + const SmartArray* choice_set = + (*message_)[strings::msg_params][strings::choice_set].asArray(); + + SmartArray::const_iterator current_choice_set_it = choice_set->begin(); + SmartArray::const_iterator next_choice_set_it; + + for (; choice_set->end() != current_choice_set_it; ++current_choice_set_it) { + std::pair<std::set<uint32_t>::iterator, bool> ins_res = + choice_id_set.insert( + (*current_choice_set_it)[strings::choice_id].asInt()); + if (!ins_res.second) { + LOG4CXX_ERROR(logger_, + "Choise with ID " + << (*current_choice_set_it)[strings::choice_id].asInt() + << " already exists"); + return mobile_apis::Result::INVALID_ID; + } + + if (IsWhiteSpaceExist(*current_choice_set_it)) { + LOG4CXX_ERROR(logger_, "Incoming choice set has contains \t\n \\t \\n"); + return mobile_apis::Result::INVALID_DATA; + } + for (next_choice_set_it = current_choice_set_it + 1; + choice_set->end() != next_choice_set_it; + ++next_choice_set_it) { + if (compareSynonyms(*current_choice_set_it, *next_choice_set_it)) { + return mobile_apis::Result::DUPLICATE_NAME; + } + } + } + return mobile_apis::Result::SUCCESS; +} + +bool CreateInteractionChoiceSetRequest::compareSynonyms( + const NsSmartDeviceLink::NsSmartObjects::SmartObject& choice1, + const NsSmartDeviceLink::NsSmartObjects::SmartObject& choice2) { + smart_objects::SmartArray* vr_cmds_1 = + choice1[strings::vr_commands].asArray(); + DCHECK(vr_cmds_1 != NULL); + smart_objects::SmartArray* vr_cmds_2 = + choice2[strings::vr_commands].asArray(); + DCHECK(vr_cmds_2 != NULL); + + smart_objects::SmartArray::iterator it; + it = std::find_first_of(vr_cmds_1->begin(), + vr_cmds_1->end(), + vr_cmds_2->begin(), + vr_cmds_2->end(), + CreateInteractionChoiceSetRequest::compareStr); + + if (it != vr_cmds_1->end()) { + LOG4CXX_INFO(logger_, + "Incoming choice set has duplicated VR synonyms " + << it->asString()); + return true; + } + + return false; +} + +bool CreateInteractionChoiceSetRequest::compareStr( + const NsSmartDeviceLink::NsSmartObjects::SmartObject& str1, + const NsSmartDeviceLink::NsSmartObjects::SmartObject& str2) { + return 0 == strcasecmp(str1.asCharArray(), str2.asCharArray()); +} + +bool CreateInteractionChoiceSetRequest::IsWhiteSpaceExist( + const smart_objects::SmartObject& choice_set) { + LOG4CXX_AUTO_TRACE(logger_); + const char* str = NULL; + + str = choice_set[strings::menu_name].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid menu_name syntax check failed"); + return true; + } + + if (choice_set.keyExists(strings::secondary_text)) { + str = choice_set[strings::secondary_text].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid secondary_text syntax check failed"); + return true; + } + } + + if (choice_set.keyExists(strings::tertiary_text)) { + str = choice_set[strings::tertiary_text].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid tertiary_text syntax check failed"); + return true; + } + } + + if (choice_set.keyExists(strings::vr_commands)) { + const size_t len = choice_set[strings::vr_commands].length(); + + for (size_t i = 0; i < len; ++i) { + str = choice_set[strings::vr_commands][i].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid vr_commands syntax check failed"); + return true; + } + } + } + + if (choice_set.keyExists(strings::image)) { + str = choice_set[strings::image][strings::value].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid image value syntax check failed"); + return true; + } + } + + if (choice_set.keyExists(strings::secondary_image)) { + str = choice_set[strings::secondary_image][strings::value].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid secondary_image value. " + "Syntax check failed"); + return true; + } + } + return false; +} + +void CreateInteractionChoiceSetRequest::SendVRAddCommandRequests( + application_manager::ApplicationSharedPtr const app) { + LOG4CXX_AUTO_TRACE(logger_); + + smart_objects::SmartObject& choice_set = (*message_)[strings::msg_params]; + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_params[strings::type] = hmi_apis::Common_VRCommandType::Choice; + msg_params[strings::app_id] = app->app_id(); + msg_params[strings::grammar_id] = choice_set[strings::grammar_id]; + const uint32_t choice_count = choice_set[strings::choice_set].length(); + SetAllowedToTerminate(false); + + expected_chs_count_ = choice_count; + size_t chs_num = 0; + for (; chs_num < choice_count; ++chs_num) { + { + sync_primitives::AutoLock error_lock(error_from_hmi_lock_); + if (error_from_hmi_) { + LOG4CXX_WARN(logger_, + "Error from HMI received. Stop sending VRCommands"); + break; + } + } + + msg_params[strings::cmd_id] = + choice_set[strings::choice_set][chs_num][strings::choice_id]; + msg_params[strings::vr_commands] = + smart_objects::SmartObject(smart_objects::SmartType_Array); + msg_params[strings::vr_commands] = + choice_set[strings::choice_set][chs_num][strings::vr_commands]; + + sync_primitives::AutoLock commands_lock(vr_commands_lock_); + const uint32_t vr_cmd_id = msg_params[strings::cmd_id].asUInt(); + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VR); + const uint32_t vr_corr_id = + SendHMIRequest(hmi_apis::FunctionID::VR_AddCommand, &msg_params, true); + + VRCommandInfo vr_command(vr_cmd_id); + sent_commands_map_[vr_corr_id] = vr_command; + LOG4CXX_DEBUG(logger_, + "VR_command sent corr_id " << vr_corr_id << " cmd_id " + << vr_corr_id); + } + expected_chs_count_ = chs_num; + LOG4CXX_DEBUG(logger_, "expected_chs_count_ = " << expected_chs_count_); +} + +void CreateInteractionChoiceSetRequest::ProcessHmiError( + const hmi_apis::Common_Result::eType vr_result) { + LOG4CXX_DEBUG(logger_, + "Hmi response is not Success: " + << vr_result << ". Stop sending VRAddCommand requests"); + if (!error_from_hmi_) { + error_from_hmi_ = true; + std::string info = + vr_result == hmi_apis::Common_Result::UNSUPPORTED_RESOURCE + ? "VR is not supported by system" + : ""; + SendResponse(false, GetMobileResultCode(vr_result), info.c_str()); + } +} + +bool CreateInteractionChoiceSetRequest::ProcessSuccesfulHMIResponse( + const uint32_t corr_id) { + SentCommandsMap::iterator it = sent_commands_map_.find(corr_id); + if (sent_commands_map_.end() == it) { + LOG4CXX_WARN(logger_, "HMI response for unknown VR command received"); + return false; + } + VRCommandInfo& vr_command = it->second; + vr_command.succesful_response_received_ = true; + return true; +} + +void CreateInteractionChoiceSetRequest::CountReceivedVRResponses() { + received_chs_count_++; + LOG4CXX_DEBUG(logger_, + "Got VR.AddCommand response, there are " + << expected_chs_count_ - received_chs_count_ + << " more to wait."); + if (received_chs_count_ < expected_chs_count_) { + application_manager_.updateRequestTimeout( + connection_key(), correlation_id(), default_timeout()); + LOG4CXX_DEBUG(logger_, "Timeout for request was updated"); + } else { + OnAllHMIResponsesReceived(); + } +} + +void CreateInteractionChoiceSetRequest::on_event( + const event_engine::Event& event) { + using namespace hmi_apis; + using namespace helpers; + LOG4CXX_AUTO_TRACE(logger_); + + const smart_objects::SmartObject& message = event.smart_object(); + const Common_Result::eType result = static_cast<Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + const bool is_no_error = Compare<Common_Result::eType, EQ, ONE>( + result, Common_Result::SUCCESS, Common_Result::WARNINGS); + uint32_t corr_id = static_cast<uint32_t>( + message[strings::params][strings::correlation_id].asUInt()); + if (event.id() == hmi_apis::FunctionID::VR_AddCommand) { + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VR); + { + sync_primitives::AutoLock commands_lock(vr_commands_lock_); + if (is_no_error) { + if (!ProcessSuccesfulHMIResponse(corr_id)) { + return; + } + } else { + ProcessHmiError(result); + } + } + CountReceivedVRResponses(); + } +} + +void CreateInteractionChoiceSetRequest::onTimeOut() { + LOG4CXX_AUTO_TRACE(logger_); + + if (!error_from_hmi_) { + SendResponse(false, mobile_apis::Result::GENERIC_ERROR); + } + CommandRequestImpl::onTimeOut(); + DeleteChoices(); + + // We have to keep request alive until receive all responses from HMI + // according to SDLAQ-CRS-2976 + sync_primitives::AutoLock timeout_lock_(is_timed_out_lock_); + is_timed_out_ = true; + application_manager_.TerminateRequest( + connection_key(), correlation_id(), function_id()); +} + +bool CreateInteractionChoiceSetRequest::Init() { + hash_update_mode_ = HashUpdateMode::kDoHashUpdate; + return true; +} + +void CreateInteractionChoiceSetRequest::DeleteChoices() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + if (!application) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + return; + } + application->RemoveChoiceSet(choice_set_id_); + + smart_objects::SmartObject msg_param(smart_objects::SmartType_Map); + msg_param[strings::app_id] = application->app_id(); + + sync_primitives::AutoLock commands_lock(vr_commands_lock_); + SentCommandsMap::const_iterator it = sent_commands_map_.begin(); + for (; it != sent_commands_map_.end(); ++it) { + const VRCommandInfo& vr_command_info = it->second; + if (vr_command_info.succesful_response_received_) { + msg_param[strings::cmd_id] = vr_command_info.cmd_id_; + SendHMIRequest(hmi_apis::FunctionID::VR_DeleteCommand, &msg_param); + } else { + LOG4CXX_WARN(logger_, + "succesful response has not been received for cmd_id = " + << vr_command_info.cmd_id_); + } + } + sent_commands_map_.clear(); +} + +void CreateInteractionChoiceSetRequest::OnAllHMIResponsesReceived() { + LOG4CXX_AUTO_TRACE(logger_); + + if (!error_from_hmi_) { + SendResponse(true, mobile_apis::Result::SUCCESS); + } else { + DeleteChoices(); + } + + application_manager_.TerminateRequest( + connection_key(), correlation_id(), function_id()); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_interaction_choice_set_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_interaction_choice_set_response.cc new file mode 100644 index 0000000000..0cc137d6a0 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_interaction_choice_set_response.cc @@ -0,0 +1,66 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/create_interaction_choice_set_response.h" + +#include "application_manager/application_impl.h" +#include "interfaces/MOBILE_API.h" + +namespace application_manager { + +namespace commands { + +CreateInteractionChoiceSetResponse::CreateInteractionChoiceSetResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +CreateInteractionChoiceSetResponse::~CreateInteractionChoiceSetResponse() {} + +void CreateInteractionChoiceSetResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + // check if response false + if (true == (*message_)[strings::msg_params].keyExists(strings::success)) { + if ((*message_)[strings::msg_params][strings::success].asBool() == false) { + LOG4CXX_ERROR(logger_, "Success = false"); + SendResponse(false); + return; + } + } + + SendResponse(true); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_command_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_command_request.cc new file mode 100644 index 0000000000..f894ed452c --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_command_request.cc @@ -0,0 +1,224 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/delete_command_request.h" + +#include "application_manager/application_impl.h" +#include "application_manager/message_helper.h" +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" +#include "utils/helpers.h" + +namespace application_manager { + +namespace commands { + +DeleteCommandRequest::DeleteCommandRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) + , is_ui_send_(false) + , is_vr_send_(false) + , is_ui_received_(false) + , is_vr_received_(false) + , ui_result_(hmi_apis::Common_Result::INVALID_ENUM) + , vr_result_(hmi_apis::Common_Result::INVALID_ENUM) {} + +DeleteCommandRequest::~DeleteCommandRequest() {} + +void DeleteCommandRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + + if (!application) { + LOG4CXX_ERROR(logger_, "Application is not registered"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + const int32_t cmd_id = + (*message_)[strings::msg_params][strings::cmd_id].asInt(); + + smart_objects::SmartObject* command = application->FindCommand(cmd_id); + + if (!command) { + LOG4CXX_ERROR(logger_, "Command with id " << cmd_id << " is not found."); + SendResponse(false, mobile_apis::Result::INVALID_ID); + return; + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::cmd_id] = + (*message_)[strings::msg_params][strings::cmd_id]; + msg_params[strings::app_id] = application->app_id(); + + // we should specify amount of required responses in the 1st request + uint32_t chaining_counter = 0; + if ((*command).keyExists(strings::menu_params)) { + ++chaining_counter; + } + + if ((*command).keyExists(strings::vr_commands)) { + ++chaining_counter; + } + /* Need to set all flags before sending request to HMI + * for correct processing this flags in method on_event */ + if ((*command).keyExists(strings::menu_params)) { + is_ui_send_ = true; + } + // check vr params + if ((*command).keyExists(strings::vr_commands)) { + is_vr_send_ = true; + } + if (is_ui_send_) { + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + SendHMIRequest(hmi_apis::FunctionID::UI_DeleteCommand, &msg_params, true); + } + if (is_vr_send_) { + // VR params + msg_params[strings::grammar_id] = application->get_grammar_id(); + msg_params[strings::type] = hmi_apis::Common_VRCommandType::Command; + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VR); + SendHMIRequest(hmi_apis::FunctionID::VR_DeleteCommand, &msg_params, true); + } +} + +bool DeleteCommandRequest::PrepareResponseParameters( + mobile_apis::Result::eType& result_code, std::string& info) { + using namespace helpers; + ResponseInfo ui_delete_info( + ui_result_, HmiInterfaces::HMI_INTERFACE_UI, application_manager_); + ResponseInfo vr_delete_info( + vr_result_, HmiInterfaces::HMI_INTERFACE_VR, application_manager_); + const bool result = + PrepareResultForMobileResponse(ui_delete_info, vr_delete_info); + + const bool is_vr_or_ui_warning = + Compare<hmi_apis::Common_Result::eType, EQ, ONE>( + hmi_apis::Common_Result::WARNINGS, ui_result_, vr_result_); + info = MergeInfos(ui_delete_info, ui_info_, vr_delete_info, vr_info_); + if (is_vr_or_ui_warning && !ui_delete_info.is_unsupported_resource && + !vr_delete_info.is_unsupported_resource) { + LOG4CXX_DEBUG(logger_, "VR or UI result is warning"); + result_code = mobile_apis::Result::WARNINGS; + return result; + } + result_code = PrepareResultCodeForResponse(ui_delete_info, vr_delete_info); + LOG4CXX_DEBUG(logger_, "Result is " << (result ? "true" : "false")); + return result; +} + +void DeleteCommandRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + + const smart_objects::SmartObject& message = event.smart_object(); + switch (event.id()) { + case hmi_apis::FunctionID::UI_DeleteCommand: { + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + is_ui_received_ = true; + ui_result_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + LOG4CXX_DEBUG(logger_, + "Received UI_DeleteCommand event with result " + << MessageHelper::HMIResultToString(ui_result_)); + GetInfo(message, ui_info_); + break; + } + case hmi_apis::FunctionID::VR_DeleteCommand: { + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VR); + is_vr_received_ = true; + vr_result_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + LOG4CXX_DEBUG(logger_, + "Received VR_DeleteCommand event with result " + << MessageHelper::HMIResultToString(vr_result_)); + GetInfo(message, vr_info_); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } + + if (IsPendingResponseExist()) { + LOG4CXX_DEBUG(logger_, "Still awaiting for other responses."); + return; + } + + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + + if (!application) { + LOG4CXX_ERROR(logger_, "Application is not registered"); + return; + } + smart_objects::SmartObject& msg_params = (*message_)[strings::msg_params]; + + const int32_t cmd_id = msg_params[strings::cmd_id].asInt(); + + smart_objects::SmartObject* command = application->FindCommand(cmd_id); + + if (!command) { + LOG4CXX_ERROR(logger_, + "Command id " << cmd_id << " not found for " + "application with connection key " + << connection_key()); + return; + } + mobile_apis::Result::eType result_code = mobile_apis::Result::INVALID_ENUM; + std::string info; + const bool result = PrepareResponseParameters(result_code, info); + if (result) { + application->RemoveCommand(msg_params[strings::cmd_id].asInt()); + } + SendResponse( + result, result_code, info.empty() ? NULL : info.c_str(), &msg_params); +} + +bool DeleteCommandRequest::Init() { + hash_update_mode_ = HashUpdateMode::kDoHashUpdate; + return true; +} + +bool DeleteCommandRequest::IsPendingResponseExist() { + LOG4CXX_AUTO_TRACE(logger_); + return is_ui_send_ != is_ui_received_ || is_vr_send_ != is_vr_received_; +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_command_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_command_response.cc new file mode 100644 index 0000000000..bbcdcfe57f --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_command_response.cc @@ -0,0 +1,55 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/delete_command_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +DeleteCommandResponse::DeleteCommandResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +DeleteCommandResponse::~DeleteCommandResponse() {} + +void DeleteCommandResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_file_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_file_request.cc new file mode 100644 index 0000000000..984c7a1725 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_file_request.cc @@ -0,0 +1,121 @@ +/* + + Copyright (c) 2016, 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 "application_manager/commands/mobile/delete_file_request.h" + +#include "application_manager/application_impl.h" + +#include "utils/file_system.h" + +namespace application_manager { + +namespace commands { + +DeleteFileRequest::DeleteFileRequest(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +DeleteFileRequest::~DeleteFileRequest() {} + +void DeleteFileRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + + if (!application) { + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + LOG4CXX_ERROR(logger_, "Application is not registered"); + return; + } + + if ((mobile_api::HMILevel::HMI_NONE == application->hmi_level()) && + (application_manager_.get_settings().delete_file_in_none() <= + application->delete_file_in_none_count())) { + // If application is in the HMI_NONE level the quantity of allowed + // DeleteFile request is limited by the configuration profile + LOG4CXX_ERROR(logger_, + "Too many requests from the app with HMILevel HMI_NONE "); + SendResponse(false, mobile_apis::Result::REJECTED); + return; + } + + const std::string& sync_file_name = + (*message_)[strings::msg_params][strings::sync_file_name].asString(); + + if (!file_system::IsFileNameValid(sync_file_name)) { + const std::string err_msg = "Sync file name contains forbidden symbols."; + LOG4CXX_ERROR(logger_, err_msg); + SendResponse(false, mobile_apis::Result::INVALID_DATA, err_msg.c_str()); + return; + } + + std::string full_file_path = + application_manager_.get_settings().app_storage_folder() + "/"; + full_file_path += application->folder_name(); + full_file_path += "/"; + full_file_path += sync_file_name; + + if (file_system::FileExists(full_file_path)) { + if (file_system::DeleteFile(full_file_path)) { + const AppFile* file = application->GetFile(full_file_path); + if (file) { + SendFileRemovedNotification(file); + } + + application->DeleteFile(full_file_path); + application->increment_delete_file_in_none_count(); + SendResponse(true, mobile_apis::Result::SUCCESS); + } else { + SendResponse(false, mobile_apis::Result::GENERIC_ERROR); + } + } else { + SendResponse(false, mobile_apis::Result::REJECTED); + } +} + +void DeleteFileRequest::SendFileRemovedNotification(const AppFile* file) const { + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::app_id] = connection_key(); + msg_params[strings::file_name] = file->file_name; + msg_params[strings::file_type] = file->file_type; + + CreateHMINotification(hmi_apis::FunctionID::BasicCommunication_OnFileRemoved, + msg_params); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_file_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_file_response.cc new file mode 100644 index 0000000000..8ed6f7ba2e --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_file_response.cc @@ -0,0 +1,66 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/delete_file_response.h" + +#include "application_manager/application_impl.h" + +namespace application_manager { + +namespace commands { + +DeleteFileResponse::DeleteFileResponse(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +DeleteFileResponse::~DeleteFileResponse() {} + +void DeleteFileResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + uint32_t app_id = + (*message_)[strings::params][strings::connection_key].asUInt(); + ApplicationSharedPtr app = application_manager_.application(app_id); + if (!app) { + LOG4CXX_ERROR(logger_, "Application not registered"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + (*message_)[strings::msg_params][strings::space_available] = + static_cast<uint32_t>(app->GetAvailableDiskSpace()); + SendResponse((*message_)[strings::msg_params][strings::success].asBool()); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_interaction_choice_set_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_interaction_choice_set_request.cc new file mode 100644 index 0000000000..bfbb2429ac --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_interaction_choice_set_request.cc @@ -0,0 +1,159 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/delete_interaction_choice_set_request.h" + +#include "application_manager/application_impl.h" +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" +#include "application_manager/message_helper.h" + +namespace application_manager { + +namespace commands { + +DeleteInteractionChoiceSetRequest::DeleteInteractionChoiceSetRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +DeleteInteractionChoiceSetRequest::~DeleteInteractionChoiceSetRequest() {} + +void DeleteInteractionChoiceSetRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, + "No application associated with connection key " + << connection_key()); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + const int32_t choice_set_id = + (*message_)[strings::msg_params][strings::interaction_choice_set_id] + .asInt(); + + if (!app->FindChoiceSet(choice_set_id)) { + LOG4CXX_ERROR(logger_, + "Choice set with id " << choice_set_id << " is not found."); + SendResponse(false, mobile_apis::Result::INVALID_ID); + return; + } + + if (ChoiceSetInUse(app)) { + LOG4CXX_ERROR(logger_, "Choice set currently in use."); + SendResponse(false, mobile_apis::Result::IN_USE); + return; + } + SendVrDeleteCommand(app); + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::interaction_choice_set_id] = choice_set_id; + msg_params[strings::app_id] = app->app_id(); + + app->RemoveChoiceSet(choice_set_id); + + // Checking of HMI responses will be implemented with APPLINK-14600 + const bool result = true; + SendResponse(result, mobile_apis::Result::SUCCESS); +} + +bool DeleteInteractionChoiceSetRequest::Init() { + hash_update_mode_ = HashUpdateMode::kDoHashUpdate; + return true; +} + +bool DeleteInteractionChoiceSetRequest::ChoiceSetInUse( + ApplicationConstSharedPtr app) { + LOG4CXX_AUTO_TRACE(logger_); + if (!app->is_perform_interaction_active()) { + return false; + } + const DataAccessor<PerformChoiceSetMap> accessor = + app->performinteraction_choice_set_map(); + const PerformChoiceSetMap& choice_set_map = accessor.GetData(); + + const uint32_t choice_set_id = + (*message_)[strings::msg_params][strings::interaction_choice_set_id] + .asUInt(); + + PerformChoiceSetMap::const_iterator it = choice_set_map.begin(); + for (; choice_set_map.end() != it; ++it) { + const PerformChoice& choice = it->second; + PerformChoice::const_iterator choice_it = choice.begin(); + for (; choice.end() != choice_it; ++choice_it) { + if (choice_it->first == choice_set_id) { + LOG4CXX_ERROR(logger_, + "Choice set with id " << choice_set_id << " is in use."); + return true; + } + } + } + return true; +} + +void DeleteInteractionChoiceSetRequest::SendVrDeleteCommand( + application_manager::ApplicationSharedPtr app) { + LOG4CXX_AUTO_TRACE(logger_); + + const uint32_t choice_set_id = + (*message_)[strings::msg_params][strings::interaction_choice_set_id] + .asUInt(); + + smart_objects::SmartObject* choice_set = app->FindChoiceSet(choice_set_id); + + if (!choice_set) { + LOG4CXX_ERROR(logger_, + "Choice set with id " << choice_set_id << " is not found."); + return; + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_params[strings::app_id] = app->app_id(); + msg_params[strings::type] = hmi_apis::Common_VRCommandType::Choice; + msg_params[strings::grammar_id] = (*choice_set)[strings::grammar_id]; + choice_set = &((*choice_set)[strings::choice_set]); + for (uint32_t i = 0; i < (*choice_set).length(); ++i) { + msg_params[strings::cmd_id] = (*choice_set)[i][strings::choice_id]; + SendHMIRequest(hmi_apis::FunctionID::VR_DeleteCommand, &msg_params); + } +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_interaction_choice_set_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_interaction_choice_set_response.cc new file mode 100644 index 0000000000..97e07529af --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_interaction_choice_set_response.cc @@ -0,0 +1,75 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/delete_interaction_choice_set_response.h" + +#include "application_manager/application_impl.h" +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" + +namespace application_manager { + +namespace commands { + +DeleteInteractionChoiceSetResponse::DeleteInteractionChoiceSetResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +DeleteInteractionChoiceSetResponse::~DeleteInteractionChoiceSetResponse() {} + +void DeleteInteractionChoiceSetResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + // check if response false + if (true == (*message_)[strings::msg_params].keyExists(strings::success)) { + if ((*message_)[strings::msg_params][strings::success].asBool() == false) { + LOG4CXX_ERROR(logger_, "Success = false"); + SendResponse(false); + return; + } + } + + const int32_t code = + (*message_)[strings::msg_params][strings::result_code].asInt(); + + if (hmi_apis::Common_Result::SUCCESS == code) { + SendResponse(true); + } else { + // TODO(DK): Some logic + SendResponse(false); + } +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_sub_menu_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_sub_menu_request.cc new file mode 100644 index 0000000000..09f3139245 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_sub_menu_request.cc @@ -0,0 +1,192 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/delete_sub_menu_request.h" + +#include "application_manager/message_helper.h" +#include "application_manager/application_impl.h" +#include "interfaces/HMI_API.h" +#include "utils/helpers.h" + +namespace application_manager { + +namespace commands { + +DeleteSubMenuRequest::DeleteSubMenuRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +DeleteSubMenuRequest::~DeleteSubMenuRequest() {} + +void DeleteSubMenuRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + LOG4CXX_ERROR(logger_, "Application is not registered"); + return; + } + + const int32_t menu_id = + (*message_)[strings::msg_params][strings::menu_id].asInt(); + + if (!app->FindSubMenu(menu_id)) { + LOG4CXX_ERROR(logger_, "Menu with id " << menu_id << " is not found."); + SendResponse(false, mobile_apis::Result::INVALID_ID); + return; + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::menu_id] = + (*message_)[strings::msg_params][strings::menu_id]; + msg_params[strings::app_id] = app->app_id(); + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + + SendHMIRequest(hmi_apis::FunctionID::UI_DeleteSubMenu, &msg_params, true); +} + +void DeleteSubMenuRequest::DeleteSubMenuVRCommands( + ApplicationConstSharedPtr app) { + LOG4CXX_AUTO_TRACE(logger_); + + const DataAccessor<CommandsMap> accessor = app->commands_map(); + const CommandsMap& commands = accessor.GetData(); + CommandsMap::const_iterator it = commands.begin(); + + for (; commands.end() != it; ++it) { + if (!(*it->second).keyExists(strings::vr_commands)) { + continue; + } + + if ((*message_)[strings::msg_params][strings::menu_id].asInt() == + (*it->second)[strings::menu_params][hmi_request::parent_id].asInt()) { + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_params[strings::cmd_id] = (*it->second)[strings::cmd_id].asInt(); + msg_params[strings::app_id] = app->app_id(); + msg_params[strings::grammar_id] = app->get_grammar_id(); + msg_params[strings::type] = hmi_apis::Common_VRCommandType::Command; + + SendHMIRequest(hmi_apis::FunctionID::VR_DeleteCommand, &msg_params); + } + } +} + +void DeleteSubMenuRequest::DeleteSubMenuUICommands( + ApplicationSharedPtr const app) { + LOG4CXX_AUTO_TRACE(logger_); + + const DataAccessor<CommandsMap> accessor(app->commands_map()); + const CommandsMap& commands = accessor.GetData(); + CommandsMap::const_iterator it = commands.begin(); + + while (commands.end() != it) { + if (!(*it->second).keyExists(strings::menu_params)) { + LOG4CXX_ERROR(logger_, "menu_params not exist"); + ++it; + continue; + } + + if ((*message_)[strings::msg_params][strings::menu_id].asInt() == + (*it->second)[strings::menu_params][hmi_request::parent_id].asInt()) { + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_params[strings::app_id] = app->app_id(); + msg_params[strings::cmd_id] = (*it->second)[strings::cmd_id].asInt(); + app->RemoveCommand((*it->second)[strings::cmd_id].asInt()); + it = commands.begin(); // Can not relay on + // iterators after erase was called + + SendHMIRequest(hmi_apis::FunctionID::UI_DeleteCommand, &msg_params); + } else { + ++it; + } + } +} + +void DeleteSubMenuRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::UI_DeleteSubMenu: { + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + std::string response_info; + GetInfo(message, response_info); + const bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_UI); + + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + + if (!application) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + return; + } + + if (result) { + // delete sub menu items from SDL and HMI + DeleteSubMenuVRCommands(application); + DeleteSubMenuUICommands(application); + application->RemoveSubMenu( + (*message_)[strings::msg_params][strings::menu_id].asInt()); + } + + SendResponse(result, + MessageHelper::HMIToMobileResult(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } +} + +bool DeleteSubMenuRequest::Init() { + hash_update_mode_ = HashUpdateMode::kDoHashUpdate; + return true; +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_sub_menu_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_sub_menu_response.cc new file mode 100644 index 0000000000..06a63c5bf5 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/delete_sub_menu_response.cc @@ -0,0 +1,55 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/delete_sub_menu_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +DeleteSubMenuResponse::DeleteSubMenuResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +DeleteSubMenuResponse::~DeleteSubMenuResponse() {} + +void DeleteSubMenuResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/diagnostic_message_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/diagnostic_message_request.cc new file mode 100644 index 0000000000..7704d700f9 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/diagnostic_message_request.cc @@ -0,0 +1,121 @@ +/* + + Copyright (c) 2013, 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 <algorithm> +#include "application_manager/commands/mobile/diagnostic_message_request.h" + +#include "application_manager/application_impl.h" + +#include "interfaces/HMI_API.h" +#include "application_manager/message_helper.h" + +namespace application_manager { + +namespace commands { + +DiagnosticMessageRequest::DiagnosticMessageRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +DiagnosticMessageRequest::~DiagnosticMessageRequest() {} + +void DiagnosticMessageRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "Application is not registered."); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + const std::vector<uint32_t>& supported_diag_modes = + application_manager_.get_settings().supported_diag_modes(); + + smart_objects::SmartObject& msg_data = + (*message_)[strings::msg_params][strings::message_data]; + + const uint8_t mode_position = 0; + const uint32_t msg_diagnostic_mode = msg_data[mode_position].asUInt(); + if (supported_diag_modes.end() == std::find(supported_diag_modes.begin(), + supported_diag_modes.end(), + msg_diagnostic_mode)) { + LOG4CXX_ERROR(logger_, + "Received diagnostic mode " << msg_diagnostic_mode + << " is not supported."); + SendResponse(false, + mobile_apis::Result::REJECTED, + "Received diagnostic mode is not supported."); + return; + } + + // Add app_id for HMI request + (*message_)[strings::msg_params][strings::app_id] = app->app_id(); + + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VehicleInfo); + SendHMIRequest(hmi_apis::FunctionID::VehicleInfo_DiagnosticMessage, + &(*message_)[strings::msg_params], + true); +} + +void DiagnosticMessageRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::VehicleInfo_DiagnosticMessage: { + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VehicleInfo); + hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + const bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_VehicleInfo); + std::string response_info; + GetInfo(message, response_info); + SendResponse(result, + MessageHelper::HMIToMobileResult(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/diagnostic_message_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/diagnostic_message_response.cc new file mode 100644 index 0000000000..28c8fa512c --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/diagnostic_message_response.cc @@ -0,0 +1,55 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/diagnostic_message_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +DiagnosticMessageResponse::DiagnosticMessageResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +DiagnosticMessageResponse::~DiagnosticMessageResponse() {} + +void DiagnosticMessageResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/dial_number_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/dial_number_request.cc new file mode 100644 index 0000000000..d0ab42e266 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/dial_number_request.cc @@ -0,0 +1,147 @@ +/* + Copyright (c) 2016, 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 <algorithm> +#include <string> +#include "application_manager/commands/mobile/dial_number_request.h" + +#include "application_manager/application_impl.h" + +namespace application_manager { + +namespace commands { + +DialNumberRequest::DialNumberRequest(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +DialNumberRequest::~DialNumberRequest() {} + +bool DialNumberRequest::Init() { + LOG4CXX_AUTO_TRACE(logger_); + + default_timeout_ = 0; + + return true; +} + +void DialNumberRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + + if (!application) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + std::string number = + (*message_)[strings::msg_params][strings::number].asString(); + if (!CheckSyntax(number)) { + LOG4CXX_ERROR(logger_, "Invalid incoming data"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + StripNumberParam(number); + if (number.empty()) { + LOG4CXX_ERROR(logger_, + "After strip number param is empty. Invalid incoming data"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_params[strings::number] = + (*message_)[strings::msg_params][strings::number].asString(); + msg_params[strings::app_id] = application->hmi_app_id(); + + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_BasicCommunication); + SendHMIRequest( + hmi_apis::FunctionID::BasicCommunication_DialNumber, &msg_params, true); +} + +void DialNumberRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + + if (!application) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + return; + } + + const smart_objects::SmartObject& message = event.smart_object(); + mobile_apis::Result::eType result_code = mobile_apis::Result::SUCCESS; + switch (event.id()) { + case hmi_apis::FunctionID::BasicCommunication_DialNumber: { + LOG4CXX_INFO(logger_, "Received DialNumber event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_BasicCommunication); + result_code = CommandRequestImpl::GetMobileResultCode( + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt())); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } + + const bool is_success = mobile_apis::Result::SUCCESS == result_code; + const bool is_info_valid = + message[strings::msg_params].keyExists(strings::info); + + if (is_info_valid) { + const char* info_char_array = + message[strings::msg_params][strings::info].asCharArray(); + SendResponse(is_success, result_code, info_char_array); + return; + } + + SendResponse(is_success, result_code); +} + +void DialNumberRequest::StripNumberParam(std::string& number) { + std::size_t found = 0; + while (std::string::npos != + (found = number.find_first_not_of("0123456789*#,;+"))) { + number.erase(number.begin() + found); + } + (*message_)[strings::msg_params][strings::number] = number; +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/dial_number_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/dial_number_response.cc new file mode 100644 index 0000000000..ee9bbd0e08 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/dial_number_response.cc @@ -0,0 +1,54 @@ +/* + Copyright (c) 2016, 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 "application_manager/commands/mobile/dial_number_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +DialNumberResponse::DialNumberResponse(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +DialNumberResponse::~DialNumberResponse() {} + +void DialNumberResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/end_audio_pass_thru_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/end_audio_pass_thru_request.cc new file mode 100644 index 0000000000..fb168e4256 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/end_audio_pass_thru_request.cc @@ -0,0 +1,91 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/end_audio_pass_thru_request.h" +#include "application_manager/message_helper.h" + +namespace application_manager { + +namespace commands { + +EndAudioPassThruRequest::EndAudioPassThruRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +EndAudioPassThruRequest::~EndAudioPassThruRequest() {} + +void EndAudioPassThruRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + SendHMIRequest(hmi_apis::FunctionID::UI_EndAudioPassThru, NULL, true); +} + +void EndAudioPassThruRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::UI_EndAudioPassThru: { + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asUInt()); + std::string response_info; + GetInfo(message, response_info); + const bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_UI); + if (result) { + uint32_t app_id = connection_key(); + bool ended_successfully = application_manager_.EndAudioPassThru(app_id); + if (ended_successfully) { + application_manager_.StopAudioPassThru(app_id); + } + } + + SendResponse(result, + MessageHelper::HMIToMobileResult(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/end_audio_pass_thru_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/end_audio_pass_thru_response.cc new file mode 100644 index 0000000000..ca52aeee65 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/end_audio_pass_thru_response.cc @@ -0,0 +1,55 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/end_audio_pass_thru_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +EndAudioPassThruResponse::EndAudioPassThruResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +EndAudioPassThruResponse::~EndAudioPassThruResponse() {} + +void EndAudioPassThruResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/generic_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/generic_response.cc new file mode 100644 index 0000000000..20f6931bb9 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/generic_response.cc @@ -0,0 +1,65 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/generic_response.h" + +#include "application_manager/application_impl.h" + +namespace application_manager { + +namespace commands { + +void GenericResponse::Run() { + /*NsSmartDeviceLink::NsSmartObjects::SmartObject response; + + response[strings::params][strings::correlation_id] = + (*message_)[strings::params][strings::correlation_id]; + response[strings::params][strings::protocol_version] = + (*message_)[strings::params][strings::protocol_version]; + response[strings::params][strings::connection_key] = + (*message_)[strings::params][strings::connection_key]; + + response[strings::msg_params][strings::success] = false; + */ + + (*message_)[strings::params][strings::message_type] = MessageType::kResponse; + (*message_)[strings::msg_params][strings::success] = false; + (*message_)[strings::msg_params][strings::result_code] = + mobile_apis::Result::INVALID_DATA; + + SendResponse(false); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_dtcs_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_dtcs_request.cc new file mode 100644 index 0000000000..88fd07234a --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_dtcs_request.cc @@ -0,0 +1,110 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/get_dtcs_request.h" + +#include "application_manager/application_impl.h" +#include "interfaces/HMI_API.h" +#include "application_manager/message_helper.h" + +namespace application_manager { + +namespace commands { + +GetDTCsRequest::GetDTCsRequest(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +GetDTCsRequest::~GetDTCsRequest() {} + +void GetDTCsRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application( + (*message_)[strings::params][strings::connection_key].asUInt()); + + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::ecu_name] = + (*message_)[strings::msg_params][strings::ecu_name]; + + if ((*message_)[strings::msg_params].keyExists(strings::dtc_mask)) { + msg_params[strings::dtc_mask] = + (*message_)[strings::msg_params][strings::dtc_mask]; + } + + msg_params[strings::app_id] = app->app_id(); + + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VehicleInfo); + SendHMIRequest(hmi_apis::FunctionID::VehicleInfo_GetDTCs, &msg_params, true); +} + +void GetDTCsRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::VehicleInfo_GetDTCs: { + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VehicleInfo); + hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + + const bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_VehicleInfo); + std::string response_info; + GetInfo(message, response_info); + + SendResponse(result, + MessageHelper::HMIToMobileResult(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_dtcs_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_dtcs_response.cc new file mode 100644 index 0000000000..a8111b5e6e --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_dtcs_response.cc @@ -0,0 +1,55 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/get_dtcs_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +GetDTCsResponse::GetDTCsResponse(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +GetDTCsResponse::~GetDTCsResponse() {} + +void GetDTCsResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager 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 new file mode 100644 index 0000000000..71cde5158d --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_system_capability_request.cc @@ -0,0 +1,95 @@ +#include "application_manager/commands/mobile/get_system_capability_request.h" + +namespace application_manager { + +namespace commands { + +GetSystemCapabilityRequest::GetSystemCapabilityRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +GetSystemCapabilityRequest::~GetSystemCapabilityRequest() {} + +void GetSystemCapabilityRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "Application is not registered"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + if ((*message_)[strings::msg_params].empty()) { + LOG4CXX_ERROR(logger_, strings::msg_params << " is empty."); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + smart_objects::SmartObject response_params(smart_objects::SmartType_Map); + mobile_apis::SystemCapabilityType::eType response_type = + static_cast<mobile_apis::SystemCapabilityType::eType>( + (*message_)[strings::msg_params][strings::system_capability_type] + .asInt()); + response_params[strings::system_capability][strings::system_capability_type] = + response_type; + + const HMICapabilities& hmi_capabilities = + application_manager_.hmi_capabilities(); + + switch (response_type) { + case mobile_apis::SystemCapabilityType::NAVIGATION: { + if (hmi_capabilities.navigation_capability()) { + response_params[strings::system_capability] + [strings::navigation_capability] = + *hmi_capabilities.navigation_capability(); + } else { + SendResponse(false, mobile_apis::Result::DATA_NOT_AVAILABLE); + return; + } + break; + } + case mobile_apis::SystemCapabilityType::PHONE_CALL: { + if (hmi_capabilities.phone_capability()) { + response_params[strings::system_capability][strings::phone_capability] = + *hmi_capabilities.phone_capability(); + } else { + SendResponse(false, mobile_apis::Result::DATA_NOT_AVAILABLE); + return; + } + break; + } + case mobile_apis::SystemCapabilityType::REMOTE_CONTROL: { + if (hmi_capabilities.rc_capability()) { + response_params[strings::system_capability][strings::rc_capability] = + *hmi_capabilities.rc_capability(); + } else { + SendResponse(false, mobile_apis::Result::DATA_NOT_AVAILABLE); + return; + } + break; + } + case mobile_apis::SystemCapabilityType::VIDEO_STREAMING: + if (hmi_capabilities.video_streaming_capability()) { + response_params[strings::system_capability] + [strings::video_streaming_capability] = + *hmi_capabilities.video_streaming_capability(); + } else { + SendResponse(false, mobile_apis::Result::DATA_NOT_AVAILABLE); + return; + } + break; + default: // Return unsupported resource + SendResponse(false, mobile_apis::Result::UNSUPPORTED_RESOURCE); + return; + } + SendResponse(true, mobile_apis::Result::SUCCESS, NULL, &response_params); +} + +void GetSystemCapabilityRequest::on_event(const event_engine::Event& event) { + LOG4CXX_INFO(logger_, "GetSystemCapabilityRequest on_event"); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_system_capability_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_system_capability_response.cc new file mode 100644 index 0000000000..3ac0459e71 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_system_capability_response.cc @@ -0,0 +1,23 @@ +#include "application_manager/application_manager.h" +#include "application_manager/rpc_service.h" +#include "application_manager/commands/mobile/get_system_capability_response.h" + +namespace application_manager { + +namespace commands { + +GetSystemCapabilityResponse::GetSystemCapabilityResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +GetSystemCapabilityResponse::~GetSystemCapabilityResponse() {} + +void GetSystemCapabilityResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_vehicle_data_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_vehicle_data_request.cc new file mode 100644 index 0000000000..f81d0a8c2a --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_vehicle_data_request.cc @@ -0,0 +1,306 @@ +/* + + Copyright (c) 2013, 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 <string> +#include "application_manager/commands/mobile/get_vehicle_data_request.h" + +#include "application_manager/application_impl.h" +#include "application_manager/message_helper.h" +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" + +namespace application_manager { + +namespace commands { + +namespace str = strings; + +#ifdef HMI_DBUS_API +GetVehicleDataRequest::GetVehicleDataRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +GetVehicleDataRequest::~GetVehicleDataRequest() {} + +void GetVehicleDataRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + int32_t app_id = + (*message_)[strings::params][strings::connection_key].asUInt(); + ApplicationSharedPtr app = application_manager_.application(app_id); + + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + const VehicleData& vehicle_data = MessageHelper::vehicle_data(); + VehicleData::const_iterator it = vehicle_data.begin(); + + for (; vehicle_data.end() != it; ++it) { + if (true == (*message_)[str::msg_params].keyExists(it->first) && + true == (*message_)[str::msg_params][it->first].asBool()) { + SendRequestsToHmi(app->app_id()); + return; + } + } + + SendResponse(false, mobile_apis::Result::INVALID_DATA); +} + +namespace { +struct Subrequest { + hmi_apis::FunctionID::eType func_id; + const char* str; +}; +Subrequest subrequests[] = { + {hmi_apis::FunctionID::VehicleInfo_GetGpsData, str::gps}, + {hmi_apis::FunctionID::VehicleInfo_GetSpeed, str::speed}, + {hmi_apis::FunctionID::VehicleInfo_GetRpm, str::rpm}, + {hmi_apis::FunctionID::VehicleInfo_GetFuelLevel, str::fuel_level}, + {hmi_apis::FunctionID::VehicleInfo_GetFuelLevelState, + str::fuel_level_state}, + {hmi_apis::FunctionID::VehicleInfo_GetInstantFuelConsumption, + str::instant_fuel_consumption}, + {hmi_apis::FunctionID::VehicleInfo_GetExternalTemperature, + str::external_temp}, + {hmi_apis::FunctionID::VehicleInfo_GetVin, str::vin}, + {hmi_apis::FunctionID::VehicleInfo_GetPrndl, str::prndl}, + {hmi_apis::FunctionID::VehicleInfo_GetTirePressure, str::tire_pressure}, + {hmi_apis::FunctionID::VehicleInfo_GetOdometer, str::odometer}, + {hmi_apis::FunctionID::VehicleInfo_GetBeltStatus, str::belt_status}, + {hmi_apis::FunctionID::VehicleInfo_GetBodyInformation, + str::body_information}, + {hmi_apis::FunctionID::VehicleInfo_GetDeviceStatus, str::device_status}, + {hmi_apis::FunctionID::VehicleInfo_GetDriverBraking, str::driver_braking}, + {hmi_apis::FunctionID::VehicleInfo_GetWiperStatus, str::wiper_status}, + {hmi_apis::FunctionID::VehicleInfo_GetHeadLampStatus, + str::head_lamp_status}, + {hmi_apis::FunctionID::VehicleInfo_GetEngineTorque, str::engine_torque}, + {hmi_apis::FunctionID::VehicleInfo_GetAccPedalPosition, str::acc_pedal_pos}, + {hmi_apis::FunctionID::VehicleInfo_GetSteeringWheelAngle, + str::steering_wheel_angle}, + {hmi_apis::FunctionID::VehicleInfo_GetECallInfo, str::e_call_info}, + {hmi_apis::FunctionID::VehicleInfo_GetAirbagStatus, str::airbag_status}, + {hmi_apis::FunctionID::VehicleInfo_GetEmergencyEvent, str::emergency_event}, + {hmi_apis::FunctionID::VehicleInfo_GetClusterModeStatus, + str::cluster_mode_status}, + {hmi_apis::FunctionID::VehicleInfo_GetMyKey, str::my_key}, +}; +} + +void GetVehicleDataRequest::SendRequestsToHmi(const int32_t app_id) { + smart_objects::SmartObject msg_params(smart_objects::SmartType_Map); + msg_params[strings::app_id] = app_id; + + for (size_t i = 0; i < sizeof(subrequests) / sizeof(subrequests[0]); ++i) { + const Subrequest& sr = subrequests[i]; + if (true == (*message_)[str::msg_params].keyExists(sr.str) && + true == (*message_)[str::msg_params][sr.str].asBool()) { + HmiRequest hmi_request; + hmi_request.str = sr.str; + hmi_request.func_id = sr.func_id; + hmi_request.complete = false; + hmi_requests_.push_back(hmi_request); + } + } + + LOG4CXX_INFO(logger_, + hmi_requests_.size() << " requests are going to be sent to HMI"); + + for (HmiRequests::const_iterator it = hmi_requests_.begin(); + it != hmi_requests_.end(); + ++it) { + SendHMIRequest(it->func_id, &msg_params, true); + } +} + +void GetVehicleDataRequest::on_event(const event_engine::Event& event) { + LOG4CXX_INFO(logger_, "GetVehicleDataRequest::on_event " << event.id()); + + const smart_objects::SmartObject& message = event.smart_object(); + + for (HmiRequests::iterator it = hmi_requests_.begin(); + it != hmi_requests_.end(); + ++it) { + HmiRequest& hmi_request = *it; + if (hmi_request.func_id == event.id()) { + hmi_request.status = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + if (hmi_apis::Common_Result::SUCCESS == hmi_request.status) + hmi_request.value = message[str::msg_params][hmi_request.str]; + hmi_request.complete = true; + break; + } + } + + bool all_complete = true; + bool any_arg_success = false; + mobile_api::Result::eType status = mobile_api::Result::eType::SUCCESS; + for (HmiRequests::const_iterator it = hmi_requests_.begin(); + it != hmi_requests_.end(); + ++it) { + if (!it->complete) { + all_complete = false; + break; + } + if (hmi_apis::Common_Result::SUCCESS != it->status) { + if (mobile_api::Result::SUCCESS == status) { + status = static_cast<mobile_apis::Result::eType>(it->status); + } else if (status != + static_cast<mobile_apis::Result::eType>(it->status)) { + status = mobile_api::Result::eType::GENERIC_ERROR; + } + LOG4CXX_TRACE(logger_, + "Status from HMI: " << it->status + << ", so response status become " + << status); + } else { + any_arg_success = true; + } + } + + if (all_complete) { + smart_objects::SmartObject response_params(smart_objects::SmartType_Map); + if (any_arg_success) { + for (HmiRequests::const_iterator it = hmi_requests_.begin(); + it != hmi_requests_.end(); + ++it) { + response_params[it->str] = it->value; + } + } + LOG4CXX_INFO(logger_, "All HMI requests are complete"); + const char* info = NULL; + std::string error_message; + if (true == message[strings::params].keyExists(strings::error_msg)) { + error_message = message[strings::params][strings::error_msg].asString(); + info = error_message.c_str(); + } + SendResponse(any_arg_success, status, info, &response_params); + } +} +#else +GetVehicleDataRequest::GetVehicleDataRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +GetVehicleDataRequest::~GetVehicleDataRequest() {} + +void GetVehicleDataRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + int32_t app_id = + (*message_)[strings::params][strings::connection_key].asUInt(); + ApplicationSharedPtr app = application_manager_.application(app_id); + + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + if (app->AreCommandLimitsExceeded( + static_cast<mobile_apis::FunctionID::eType>(function_id()), + application_manager::TLimitSource::CONFIG_FILE)) { + LOG4CXX_ERROR(logger_, "GetVehicleData frequency is too high."); + SendResponse(false, mobile_apis::Result::REJECTED); + return; + } + const VehicleData& vehicle_data = MessageHelper::vehicle_data(); + VehicleData::const_iterator it = vehicle_data.begin(); + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_params[strings::app_id] = app->app_id(); + const uint32_t min_length_msg_params = 1; + for (; vehicle_data.end() != it; ++it) { + if (true == (*message_)[str::msg_params].keyExists(it->first) && + true == (*message_)[str::msg_params][it->first].asBool()) { + msg_params[it->first] = (*message_)[strings::msg_params][it->first]; + } + } + if (msg_params.length() > min_length_msg_params) { + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VehicleInfo); + SendHMIRequest( + hmi_apis::FunctionID::VehicleInfo_GetVehicleData, &msg_params, true); + return; + } else if (HasDisallowedParams()) { + SendResponse(false, mobile_apis::Result::DISALLOWED); + } else { + SendResponse(false, mobile_apis::Result::INVALID_DATA); + } +} + +void GetVehicleDataRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + smart_objects::SmartObject message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::VehicleInfo_GetVehicleData: { + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VehicleInfo); + hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_VehicleInfo); + std::string response_info; + GetInfo(message, response_info); + result = result || + ((hmi_apis::Common_Result::DATA_NOT_AVAILABLE == result_code) && + (message[strings::msg_params].length() > 1)); + + if (true == + message[strings::msg_params].keyExists(hmi_response::method)) { + message[strings::msg_params].erase(hmi_response::method); + } + if (true == message[strings::params].keyExists(strings::error_msg)) { + response_info = message[strings::params][strings::error_msg].asString(); + } + SendResponse(result, + MessageHelper::HMIToMobileResult(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } +} + +#endif // #ifdef HMI_DBUS_API + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_vehicle_data_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_vehicle_data_response.cc new file mode 100644 index 0000000000..700c8adffb --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_vehicle_data_response.cc @@ -0,0 +1,56 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/get_vehicle_data_response.h" +#include "application_manager/rpc_service.h" +#include "interfaces/HMI_API.h" + +namespace application_manager { + +namespace commands { + +GetVehicleDataResponse::GetVehicleDataResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +GetVehicleDataResponse::~GetVehicleDataResponse() {} + +void GetVehicleDataResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_way_points_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_way_points_request.cc new file mode 100644 index 0000000000..da4ce38646 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_way_points_request.cc @@ -0,0 +1,75 @@ +#include "application_manager/application_manager.h" +#include "application_manager/commands/mobile/get_way_points_request.h" +#include "application_manager/message_helper.h" + +namespace application_manager { + +namespace commands { + +GetWayPointsRequest::GetWayPointsRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) { + subscribe_on_event(hmi_apis::FunctionID::UI_OnResetTimeout); +} + +GetWayPointsRequest::~GetWayPointsRequest() {} + +void GetWayPointsRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, + "An application with connection key " + << connection_key() << " is not registered."); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + msg_params = (*message_)[strings::msg_params]; + msg_params[strings::app_id] = app->app_id(); + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_Navigation); + SendHMIRequest(hmi_apis::FunctionID::Navigation_GetWayPoints, + msg_params.empty() ? NULL : &msg_params, + true); +} + +void GetWayPointsRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + switch (event.id()) { + case hmi_apis::FunctionID::UI_OnResetTimeout: { + LOG4CXX_INFO(logger_, "Received UI_OnResetTimeout event"); + application_manager_.updateRequestTimeout( + connection_key(), correlation_id(), default_timeout()); + break; + } + case hmi_apis::FunctionID::Navigation_GetWayPoints: { + LOG4CXX_INFO(logger_, "Received Navigation_GetWayPoints event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_Navigation); + const hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + std::string response_info; + GetInfo(message, response_info); + const bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_Navigation); + SendResponse(result, + MessageHelper::HMIToMobileResult(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + break; + } + } +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_way_points_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_way_points_response.cc new file mode 100644 index 0000000000..92e7720d8a --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_way_points_response.cc @@ -0,0 +1,23 @@ +#include "application_manager/application_manager.h" +#include "application_manager/commands/mobile/get_way_points_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +GetWayPointsResponse::GetWayPointsResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +GetWayPointsResponse::~GetWayPointsResponse() {} + +void GetWayPointsResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/list_files_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/list_files_request.cc new file mode 100644 index 0000000000..794fba631d --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/list_files_request.cc @@ -0,0 +1,106 @@ +/* + + Copyright (c) 2013, 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 <string> +#include "application_manager/commands/mobile/list_files_request.h" + +#include "application_manager/application_impl.h" + +#include "application_manager/mobile_command_factory.h" +#include "utils/file_system.h" + +namespace application_manager { + +namespace commands { + +ListFilesRequest::ListFilesRequest(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +ListFilesRequest::~ListFilesRequest() {} + +void ListFilesRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + + if (!application) { + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + LOG4CXX_ERROR(logger_, "Application is not registered"); + return; + } + + if ((mobile_api::HMILevel::HMI_NONE == application->hmi_level()) && + (application_manager_.get_settings().list_files_in_none() <= + application->list_files_in_none_count())) { + // If application is in the HMI_NONE level the quantity of allowed + // DeleteFile request is limited by the configuration profile + LOG4CXX_ERROR(logger_, + "Too many requests from the app with HMILevel HMI_NONE "); + SendResponse(false, mobile_apis::Result::REJECTED); + return; + } + + application->increment_list_files_in_none_count(); + + (*message_)[strings::msg_params][strings::space_available] = + static_cast<int32_t>(application->GetAvailableDiskSpace()); + // Enumarating through File system + uint32_t i = 0; + std::string directory_name = + application_manager_.get_settings().app_storage_folder(); + directory_name += "/" + application->folder_name(); + std::vector<std::string> persistent_files = + file_system::ListFiles(directory_name); + std::vector<std::string>::const_iterator it = persistent_files.begin(); + for (; it != persistent_files.end(); ++it) { + if (i < application_manager_.get_settings().list_files_response_size()) { + LOG4CXX_DEBUG(logger_, "File " + *it + " added to ListFiles response"); + (*message_)[strings::msg_params][strings::filenames][i++] = *it; + } else { + LOG4CXX_DEBUG(logger_, + "File " + *it + " not added to ListFiles response"); + } + } + (*message_)[strings::params][strings::message_type] = + application_manager::MessageType::kResponse; + SendResponse(true, + mobile_apis::Result::SUCCESS, + NULL, + &(*message_)[strings::msg_params]); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/list_files_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/list_files_response.cc new file mode 100644 index 0000000000..0b07605874 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/list_files_response.cc @@ -0,0 +1,56 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/list_files_response.h" +#include "application_manager/rpc_service.h" +#include "application_manager/application_impl.h" + +namespace application_manager { + +namespace commands { + +ListFilesResponse::ListFilesResponse(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +ListFilesResponse::~ListFilesResponse() {} + +void ListFilesResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_app_interface_unregistered_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_app_interface_unregistered_notification.cc new file mode 100644 index 0000000000..6064374dab --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_app_interface_unregistered_notification.cc @@ -0,0 +1,54 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/on_app_interface_unregistered_notification.h" +#include "application_manager/message.h" +#include "interfaces/MOBILE_API.h" + +namespace application_manager { +namespace commands { + +OnAppInterfaceUnregisteredNotification::OnAppInterfaceUnregisteredNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationImpl(message, application_manager) {} + +OnAppInterfaceUnregisteredNotification:: + ~OnAppInterfaceUnregisteredNotification() {} + +void OnAppInterfaceUnregisteredNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + SendNotification(); +} +} // namespace commands +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_audio_pass_thru_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_audio_pass_thru_notification.cc new file mode 100644 index 0000000000..d0fa3597bc --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_audio_pass_thru_notification.cc @@ -0,0 +1,51 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/on_audio_pass_thru_notification.h" + +namespace application_manager { +namespace commands { + +OnAudioPassThruNotification::OnAudioPassThruNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationImpl(message, application_manager) {} + +OnAudioPassThruNotification::~OnAudioPassThruNotification() {} + +void OnAudioPassThruNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + SendNotification(); +} +} // namespace commands +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_button_event_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_button_event_notification.cc new file mode 100644 index 0000000000..7c631d6d4b --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_button_event_notification.cc @@ -0,0 +1,174 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/on_button_event_notification.h" + +#include "application_manager/application_impl.h" +#include "interfaces/MOBILE_API.h" + +namespace application_manager { + +namespace commands { + +namespace mobile { + +OnButtonEventNotification::OnButtonEventNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationImpl(message, application_manager) {} + +OnButtonEventNotification::~OnButtonEventNotification() {} + +void OnButtonEventNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + const uint32_t btn_id = static_cast<uint32_t>( + (*message_)[strings::msg_params][hmi_response::button_name].asInt()); + + const bool is_app_id_exists = + (*message_)[strings::msg_params].keyExists(strings::app_id); + ApplicationSharedPtr app; + + // CUSTOM_BUTTON notification + if (static_cast<uint32_t>(mobile_apis::ButtonName::CUSTOM_BUTTON) == btn_id) { + // app_id is mandatory for CUSTOM_BUTTON notification + if (!is_app_id_exists) { + LOG4CXX_ERROR(logger_, "CUSTOM_BUTTON OnButtonEvent without app_id."); + return; + } + + app = application_manager_.application( + (*message_)[strings::msg_params][strings::app_id].asUInt()); + + // custom_button_id is mandatory for CUSTOM_BUTTON notification + if (false == + (*message_)[strings::msg_params].keyExists( + hmi_response::custom_button_id)) { + LOG4CXX_ERROR(logger_, + "CUSTOM_BUTTON OnButtonEvent without custom_button_id."); + return; + } + + if (!app) { + LOG4CXX_ERROR(logger_, "Application doesn't exist."); + return; + } + + uint32_t custom_btn_id = 0; + custom_btn_id = + (*message_)[strings::msg_params][hmi_response::custom_button_id] + .asUInt(); + + if (false == app->IsSubscribedToSoftButton(custom_btn_id)) { + LOG4CXX_ERROR(logger_, + "Application doesn't subscribed to this custom_button_id."); + return; + } + + if ((mobile_api::HMILevel::HMI_FULL != app->hmi_level()) && + (mobile_api::HMILevel::HMI_LIMITED != app->hmi_level())) { + LOG4CXX_WARN(logger_, + "CUSTOM_BUTTON OnButtonEvent notification is allowed only " + << "in FULL or LIMITED hmi level"); + return; + } + + SendButtonEvent(app); + return; + } + + const std::vector<ApplicationSharedPtr>& subscribed_apps = + application_manager_.applications_by_button(btn_id); + + std::vector<ApplicationSharedPtr>::const_iterator it = + subscribed_apps.begin(); + for (; subscribed_apps.end() != it; ++it) { + ApplicationSharedPtr subscribed_app = *it; + if (!subscribed_app) { + LOG4CXX_WARN(logger_, "Null pointer to subscribed app."); + continue; + } + + // Send ButtonEvent notification only in HMI_FULL or HMI_LIMITED mode + if ((mobile_api::HMILevel::HMI_FULL != subscribed_app->hmi_level()) && + (mobile_api::HMILevel::HMI_LIMITED != subscribed_app->hmi_level())) { + LOG4CXX_WARN(logger_, + "OnButtonEvent notification is allowed only" + << "in FULL or LIMITED hmi level"); + continue; + } + // if "app_id" absent send notification only in HMI_FULL mode + if (is_app_id_exists || subscribed_app->IsFullscreen()) { + SendButtonEvent(subscribed_app); + } + } +} + +void OnButtonEventNotification::SendButtonEvent(ApplicationConstSharedPtr app) { + if (!app) { + LOG4CXX_ERROR(logger_, "OnButtonEvent NULL pointer"); + return; + } + + smart_objects::SmartObjectSPtr on_btn_event = + new smart_objects::SmartObject(); + + if (!on_btn_event) { + LOG4CXX_ERROR(logger_, "OnButtonEvent NULL pointer"); + return; + } + + (*on_btn_event)[strings::params][strings::connection_key] = app->app_id(); + + (*on_btn_event)[strings::params][strings::function_id] = + static_cast<int32_t>(mobile_apis::FunctionID::eType::OnButtonEventID); + + (*on_btn_event)[strings::msg_params][strings::button_name] = + (*message_)[strings::msg_params][hmi_response::button_name]; + (*on_btn_event)[strings::msg_params][strings::button_event_mode] = + (*message_)[strings::msg_params][hmi_response::button_mode]; + + if ((*message_)[strings::msg_params].keyExists( + hmi_response::custom_button_id)) { + (*on_btn_event)[strings::msg_params][strings::custom_button_id] = + (*message_)[strings::msg_params][strings::custom_button_id]; + } + + message_ = on_btn_event; + SendNotification(); +} + +} // namespace mobile + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_button_press_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_button_press_notification.cc new file mode 100644 index 0000000000..ae6658b93a --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_button_press_notification.cc @@ -0,0 +1,181 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/on_button_press_notification.h" + +#include "application_manager/application_impl.h" +#include "interfaces/MOBILE_API.h" + +namespace application_manager { + +namespace commands { + +namespace mobile { + +OnButtonPressNotification::OnButtonPressNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationImpl(message, application_manager) {} + +OnButtonPressNotification::~OnButtonPressNotification() {} + +void OnButtonPressNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + const uint32_t btn_id = static_cast<uint32_t>( + (*message_)[strings::msg_params][hmi_response::button_name].asInt()); + + const bool is_app_id_exists = + (*message_)[strings::msg_params].keyExists(strings::app_id); + ApplicationSharedPtr app; + + // CUSTOM_BUTTON notification + if (static_cast<uint32_t>(mobile_apis::ButtonName::CUSTOM_BUTTON) == btn_id) { + // app_id is mandatory for CUSTOM_BUTTON notification + if (!is_app_id_exists) { + LOG4CXX_ERROR(logger_, "CUSTOM_BUTTON OnButtonPress without app_id."); + return; + } + + app = application_manager_.application( + (*message_)[strings::msg_params][strings::app_id].asUInt()); + + // custom_button_id is mandatory for CUSTOM_BUTTON notification + if (false == + (*message_)[strings::msg_params].keyExists( + hmi_response::custom_button_id)) { + LOG4CXX_ERROR(logger_, + "CUSTOM_BUTTON OnButtonPress without custom_button_id."); + return; + } + + if (!app) { + LOG4CXX_ERROR(logger_, "Application doesn't exist."); + return; + } + + uint32_t custom_btn_id = 0; + custom_btn_id = + (*message_)[strings::msg_params][hmi_response::custom_button_id] + .asUInt(); + + if (false == app->IsSubscribedToSoftButton(custom_btn_id)) { + LOG4CXX_ERROR(logger_, + "Application doesn't subscribed to this custom_button_id."); + return; + } + + // Send ButtonPress notification only in HMI_FULL or HMI_LIMITED mode + if ((mobile_api::HMILevel::HMI_FULL != app->hmi_level()) && + (mobile_api::HMILevel::HMI_LIMITED != app->hmi_level())) { + LOG4CXX_WARN(logger_, + "CUSTOM_BUTTON OnButtonPress notification is allowed only " + << "in FULL or LIMITED hmi level"); + return; + } + + SendButtonPress(app); + return; + } + + const std::vector<ApplicationSharedPtr>& subscribed_apps = + application_manager_.applications_by_button(btn_id); + + std::vector<ApplicationSharedPtr>::const_iterator it = + subscribed_apps.begin(); + for (; subscribed_apps.end() != it; ++it) { + ApplicationSharedPtr subscribed_app = *it; + if (!subscribed_app) { + LOG4CXX_WARN(logger_, "Null pointer to subscribed app."); + continue; + } + + // Send ButtonPress notification only in HMI_FULL or HMI_LIMITED mode + if ((mobile_api::HMILevel::HMI_FULL != subscribed_app->hmi_level()) && + (mobile_api::HMILevel::HMI_LIMITED != subscribed_app->hmi_level())) { + LOG4CXX_WARN(logger_, + "OnButtonPress notification is allowed only" + << "in FULL or LIMITED hmi level"); + continue; + } + // if "appID" is present, send it to named app only if its FULL or + // LIMITED + if (app.valid()) { + if (app->app_id() == subscribed_app->app_id()) { + SendButtonPress(subscribed_app); + } + } else if (subscribed_app->IsFullscreen()) { + // if No "appID" - send it FULL apps only. + SendButtonPress(subscribed_app); + } + } +} + +void OnButtonPressNotification::SendButtonPress(ApplicationConstSharedPtr app) { + if (!app) { + LOG4CXX_ERROR(logger_, "OnButtonPress NULL pointer"); + return; + } + + smart_objects::SmartObjectSPtr on_btn_press = + new smart_objects::SmartObject(); + + if (!on_btn_press) { + LOG4CXX_ERROR(logger_, "OnButtonPress NULL pointer"); + return; + } + + (*on_btn_press)[strings::params][strings::connection_key] = app->app_id(); + + (*on_btn_press)[strings::params][strings::function_id] = + static_cast<int32_t>(mobile_apis::FunctionID::eType::OnButtonPressID); + + (*on_btn_press)[strings::msg_params][strings::button_name] = + (*message_)[strings::msg_params][hmi_response::button_name]; + (*on_btn_press)[strings::msg_params][strings::button_press_mode] = + (*message_)[strings::msg_params][hmi_response::button_mode]; + + if ((*message_)[strings::msg_params].keyExists( + hmi_response::custom_button_id)) { + (*on_btn_press)[strings::msg_params][strings::custom_button_id] = + (*message_)[strings::msg_params][strings::custom_button_id]; + } + + message_ = on_btn_press; + SendNotification(); +} + +} // namespace mobile + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_command_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_command_notification.cc new file mode 100644 index 0000000000..ae8aeff771 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_command_notification.cc @@ -0,0 +1,78 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/on_command_notification.h" + +#include "application_manager/application_impl.h" + +namespace application_manager { + +namespace commands { + +OnCommandNotification::OnCommandNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationImpl(message, application_manager) {} + +OnCommandNotification::~OnCommandNotification() {} + +void OnCommandNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application( + (*message_)[strings::msg_params][strings::app_id].asInt()); + + if (!app) { + LOG4CXX_ERROR(logger_, "No application associated with session key"); + return; + } + + const uint32_t cmd_id = + (*message_)[strings::msg_params][strings::cmd_id].asUInt(); + + if (!app->FindCommand(cmd_id)) { + LOG4CXX_ERROR(logger_, " No applications found for the command " << cmd_id); + return; + } + + (*message_)[strings::params][strings::connection_key] = app->app_id(); + // remove app_id from notification + if ((*message_)[strings::msg_params].keyExists(strings::app_id)) { + (*message_)[strings::msg_params].erase(strings::app_id); + } + + SendNotification(); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_driver_distraction_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_driver_distraction_notification.cc new file mode 100644 index 0000000000..44ed2cf3b7 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_driver_distraction_notification.cc @@ -0,0 +1,61 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/on_driver_distraction_notification.h" + +#include "application_manager/application_impl.h" +#include "interfaces/MOBILE_API.h" + +namespace application_manager { + +namespace commands { + +namespace mobile { + +OnDriverDistractionNotification::OnDriverDistractionNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationImpl(message, application_manager) {} + +OnDriverDistractionNotification::~OnDriverDistractionNotification() {} + +void OnDriverDistractionNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + SendNotification(); +} + +} // namespace mobile + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_hash_change_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_hash_change_notification.cc new file mode 100644 index 0000000000..19b93f2cbf --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_hash_change_notification.cc @@ -0,0 +1,75 @@ + +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/on_hash_change_notification.h" + +#include "application_manager/application_impl.h" +#include "interfaces/MOBILE_API.h" +#include <string> + +namespace application_manager { + +namespace commands { + +namespace mobile { + +OnHashChangeNotification::OnHashChangeNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationImpl(message, application_manager) {} + +OnHashChangeNotification::~OnHashChangeNotification() {} + +void OnHashChangeNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + (*message_)[strings::params][strings::message_type] = + static_cast<int32_t>(application_manager::MessageType::kNotification); + + int32_t app_id; + app_id = (*message_)[strings::params][strings::connection_key].asInt(); + ApplicationSharedPtr app = application_manager_.application(app_id); + if (app) { + (*message_)[strings::msg_params][strings::hash_id] = app->curHash(); + SendNotification(); + } else { + LOG4CXX_WARN(logger_, + "Application with app_id " << app_id << " does not exist"); + } +} + +} // namespace mobile + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_hmi_status_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_hmi_status_notification.cc new file mode 100644 index 0000000000..a7453686e6 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_hmi_status_notification.cc @@ -0,0 +1,95 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/on_hmi_status_notification.h" + +#include "application_manager/message_helper.h" +#include "application_manager/message.h" +#include "interfaces/MOBILE_API.h" + +namespace application_manager { +namespace commands { + +OnHMIStatusNotification::OnHMIStatusNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationImpl(message, application_manager) {} + +OnHMIStatusNotification::~OnHMIStatusNotification() {} + +void OnHMIStatusNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + (*message_)[strings::params][strings::message_type] = + static_cast<int32_t>(application_manager::MessageType::kNotification); + ApplicationSharedPtr app = application_manager_.application(connection_key()); + if (!app.valid()) { + LOG4CXX_ERROR(logger_, "OnHMIStatusNotification application doesn't exist"); + return; + } + + // If the response has no hmi level, return and don't send the notification + if (!(*message_)[strings::msg_params].keyExists(strings::hmi_level)) { + // our notification clearly isn't well-formed + LOG4CXX_ERROR(logger_, "OnHMIStatusNotification has no hmiLevel field"); + return; + } + + // NOTE c++ maps default-construct on the [] operator, so if there is no + // hmiLevel field this will create one that is invalid + mobile_apis::HMILevel::eType hmi_level = + static_cast<mobile_apis::HMILevel::eType>( + (*message_)[strings::msg_params][strings::hmi_level].asInt()); + if ((mobile_apis::HMILevel::HMI_BACKGROUND == hmi_level) || + (mobile_apis::HMILevel::HMI_NONE == hmi_level)) { + if (!(app->tts_properties_in_none())) { + app->set_tts_properties_in_none(true); + LOG4CXX_INFO(logger_, + "OnHMIStatusNotification::Send TTS GlobalProperties" + " with empty array to HMI"); + MessageHelper::SendTTSGlobalProperties(app, false, application_manager_); + } + } else if ((mobile_apis::HMILevel::HMI_FULL == hmi_level) || + (mobile_apis::HMILevel::HMI_LIMITED == hmi_level)) { + if (!(app->tts_properties_in_full())) { + app->set_tts_properties_in_full(true); + LOG4CXX_INFO(logger_, + "OnHMIStatusNotification AddAppToTTSGlobalPropertiesList"); + application_manager_.AddAppToTTSGlobalPropertiesList(app->app_id()); + } + } + SendNotification(); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_hmi_status_notification_from_mobile.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_hmi_status_notification_from_mobile.cc new file mode 100644 index 0000000000..4bb6cfe9d5 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_hmi_status_notification_from_mobile.cc @@ -0,0 +1,126 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/on_hmi_status_notification_from_mobile.h" +#include "application_manager/message_helper.h" +#include "application_manager/message.h" + +namespace application_manager { +namespace commands { + +OnHMIStatusNotificationFromMobile::OnHMIStatusNotificationFromMobile( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationFromMobileImpl(message, application_manager) {} + +OnHMIStatusNotificationFromMobile::~OnHMIStatusNotificationFromMobile() {} + +void OnHMIStatusNotificationFromMobile::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + (*message_)[strings::params][strings::message_type] = + static_cast<int32_t>(application_manager::MessageType::kNotification); + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app.valid()) { + LOG4CXX_ERROR( + logger_, "OnHMIStatusNotificationFromMobile application doesn't exist"); + return; + } + + mobile_apis::HMILevel::eType current_hmi_state = + static_cast<mobile_apis::HMILevel::eType>( + (*message_)[strings::msg_params][strings::hmi_level].asUInt()); + + bool is_current_state_foreground = + mobile_apis::HMILevel::HMI_FULL == current_hmi_state; + + app->set_foreground(is_current_state_foreground); + + connection_handler::DeviceHandle handle = app->device(); + bool is_apps_requested_before = + application_manager_.IsAppsQueriedFrom(handle); + + LOG4CXX_DEBUG(logger_, + "Mobile HMI state notication came for connection key:" + << connection_key() << " and handle: " << handle); + + if (!is_apps_requested_before && + Message::is_sufficient_version( + protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_4, + app->protocol_version()) && + app->is_foreground()) { + // In case this notification will be received from mobile side with + // foreground level for app on mobile, this should trigger remote + // apps list query for SDL 4.0+ app + MessageHelper::SendQueryApps(connection_key(), application_manager_); + return; + } + + if (is_apps_requested_before) { + LOG4CXX_DEBUG(logger_, + "Remote apps list had been requested already " + " for handle: " + << handle); + + if (Message::is_sufficient_version( + protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_4, + app->protocol_version())) { + const ApplicationSet& accessor = + application_manager_.applications().GetData(); + + bool is_another_foreground_sdl4_app = false; + ApplicationSetConstIt it = accessor.begin(); + for (; accessor.end() != it; ++it) { + if (connection_key() != (*it)->app_id() && + Message::is_sufficient_version( + protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_4, + (*it)->protocol_version()) && + (*it)->is_foreground()) { + is_another_foreground_sdl4_app = true; + break; + } + } + + if (!is_another_foreground_sdl4_app) { + application_manager_.MarkAppsGreyOut(handle, + !is_current_state_foreground); + application_manager_.SendUpdateAppList(); + } + } + return; + } +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_keyboard_input_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_keyboard_input_notification.cc new file mode 100644 index 0000000000..427f52c12b --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_keyboard_input_notification.cc @@ -0,0 +1,87 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/on_keyboard_input_notification.h" + +#include "application_manager/application_impl.h" +#include "interfaces/MOBILE_API.h" + +namespace application_manager { + +namespace commands { + +namespace mobile { + +OnKeyBoardInputNotification::OnKeyBoardInputNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationImpl(message, application_manager) {} + +OnKeyBoardInputNotification::~OnKeyBoardInputNotification() {} + +void OnKeyBoardInputNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app_to_notify; + + DataAccessor<ApplicationSet> accessor = application_manager_.applications(); + ApplicationSetIt it = accessor.GetData().begin(); + for (; accessor.GetData().end() != it; ++it) { + // if there is app with active perform interaction use it for notification + ApplicationSharedPtr app = *it; + if (app->is_perform_interaction_active() && + (*it)->perform_interaction_layout() == + mobile_apis::LayoutMode::KEYBOARD) { + LOG4CXX_INFO(logger_, + "There is application with active PerformInteraction"); + app_to_notify = app; + break; + } + + if (mobile_apis::HMILevel::eType::HMI_FULL == app->hmi_level()) { + LOG4CXX_INFO(logger_, "There is application in HMI_FULL level"); + app_to_notify = app; + } + } + + if (app_to_notify.valid()) { + (*message_)[strings::params][strings::connection_key] = + app_to_notify->app_id(); + SendNotification(); + } +} + +} // namespace mobile + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_language_change_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_language_change_notification.cc new file mode 100644 index 0000000000..76420b85b6 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_language_change_notification.cc @@ -0,0 +1,54 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/on_language_change_notification.h" + +namespace application_manager { + +namespace commands { + +OnLanguageChangeNotification::OnLanguageChangeNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationImpl(message, application_manager) {} + +OnLanguageChangeNotification::~OnLanguageChangeNotification() {} + +void OnLanguageChangeNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + SendNotification(); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_permissions_change_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_permissions_change_notification.cc new file mode 100644 index 0000000000..09c407b8b5 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_permissions_change_notification.cc @@ -0,0 +1,56 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/on_permissions_change_notification.h" +#include "application_manager/message.h" +#include "interfaces/MOBILE_API.h" + +namespace application_manager { + +namespace commands { + +OnPermissionsChangeNotification::OnPermissionsChangeNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationImpl(message, application_manager) {} + +OnPermissionsChangeNotification::~OnPermissionsChangeNotification() {} + +void OnPermissionsChangeNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + SendNotification(); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_system_request_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_system_request_notification.cc new file mode 100644 index 0000000000..f06012893e --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_system_request_notification.cc @@ -0,0 +1,223 @@ +/* + Copyright (c) 2016, 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 <cstring> +#include <cstdio> +#include <string> +#include "application_manager/commands/mobile/on_system_request_notification.h" +#include "interfaces/MOBILE_API.h" +#include "utils/file_system.h" +#include "policy/policy_table/enums.h" +#include "application_manager/application_manager.h" +#include "application_manager/policies/policy_handler_interface.h" + +namespace application_manager { + +namespace commands { + +namespace mobile { + +OnSystemRequestNotification::OnSystemRequestNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationImpl(message, application_manager) {} + +OnSystemRequestNotification::~OnSystemRequestNotification() {} + +void OnSystemRequestNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + using namespace application_manager; + using namespace mobile_apis; + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app.valid()) { + LOG4CXX_ERROR(logger_, + "Application with connection key " << connection_key() + << " is not registered."); + return; + } + + const mobile_apis::RequestType::eType request_type = + static_cast<mobile_apis::RequestType::eType>( + (*message_)[strings::msg_params][strings::request_type].asInt()); + const policy::PolicyHandlerInterface& policy_handler = + application_manager_.GetPolicyHandler(); + + const std::string stringified_request_type = + rpc::policy_table_interface_base::EnumToJsonString( + static_cast<rpc::policy_table_interface_base::RequestType>( + request_type)); + + if (!policy_handler.IsRequestTypeAllowed(app->policy_app_id(), + request_type)) { + LOG4CXX_WARN(logger_, + "Request type " << stringified_request_type + << " is not allowed by policies"); + return; + } + + const bool request_subtype_present = + (*message_)[strings::msg_params].keyExists(strings::request_subtype); + if (request_subtype_present) { + const std::string request_subtype = + (*message_)[strings::msg_params][strings::request_subtype].asString(); + if (!policy_handler.IsRequestSubTypeAllowed(app->policy_app_id(), + request_subtype)) { + LOG4CXX_ERROR(logger_, + "Request subtype: " << request_subtype + << " is DISALLOWED by policies"); + return; + } + } + + if (mobile_apis::RequestType::PROPRIETARY == request_type) { + /* According to requirements: + "If the requestType = PROPRIETARY, add to mobile API fileType = JSON + If the requestType = HTTP, add to mobile API fileType = BINARY" + Also in Genivi SDL we don't save the PT to file - we put it directly in + binary_data */ + + const std::string filename = + (*message_)[strings::msg_params][strings::file_name].asString(); + BinaryMessage binary_data; + file_system::ReadBinaryFile(filename, binary_data); +#if defined(PROPRIETARY_MODE) + AddHeader(binary_data); +#endif // PROPRIETARY_MODE + +#if defined(PROPRIETARY_MODE) || defined(EXTERNAL_PROPRIETARY_MODE) + (*message_)[strings::params][strings::binary_data] = binary_data; +#endif // PROPRIETARY_MODE + + (*message_)[strings::msg_params][strings::file_type] = FileType::JSON; + } else if (mobile_apis::RequestType::HTTP == request_type) { + (*message_)[strings::msg_params][strings::file_type] = FileType::BINARY; + if ((*message_)[strings::msg_params].keyExists(strings::url)) { + (*message_)[strings::msg_params][strings::timeout] = + policy_handler.TimeoutExchangeSec(); + } + } + + SendNotification(); +} + +#ifdef PROPRIETARY_MODE +void OnSystemRequestNotification::AddHeader(BinaryMessage& message) const { + LOG4CXX_AUTO_TRACE(logger_); + const uint32_t timeout = + application_manager_.GetPolicyHandler().TimeoutExchangeSec(); + + size_t content_length; + char size_str[24]; + + if (0 > sprintf(size_str, "%zu", static_cast<size_t>(message.size()))) { + memset(size_str, 0, sizeof(size_str)); + } + + char timeout_str[24]; + if (0 > sprintf(timeout_str, "%d", timeout)) { + memset(timeout_str, 0, sizeof(timeout_str)); + } + + std::string policy_table_string = std::string(message.begin(), message.end()); + + /* The Content-Length to be sent in the HTTP Request header should be + calculated before additional escape characters are added to the + policy table string. The mobile proxy will remove the escape + characters after receiving this request. */ + + content_length = ParsePTString(policy_table_string); + + if (0 > sprintf(size_str, "%zu", content_length)) { + memset(size_str, 0, sizeof(size_str)); + } + + const std::string header = + + "{" + " \"HTTPRequest\": {" + "\"headers\": {" + "\"ContentType\": \"application/json\"," + "\"ConnectTimeout\": " + + std::string(timeout_str) + + "," + "\"DoOutput\": true," + "\"DoInput\": true," + "\"UseCaches\": false," + "\"RequestMethod\": \"POST\"," + "\"ReadTimeout\":" + + std::string(timeout_str) + + "," + "\"InstanceFollowRedirects\": false," + "\"charset\": \"utf-8\"," + "\"Content-Length\": " + + std::string(size_str) + + "}," + "\"body\": \"" + + policy_table_string + + "\"" + "}" + "}"; + + message.clear(); + message.assign(header.begin(), header.end()); + + LOG4CXX_DEBUG( + logger_, "Header added: " << std::string(message.begin(), message.end())); +} + +size_t OnSystemRequestNotification::ParsePTString( + std::string& pt_string) const { + std::string result; + size_t length = pt_string.length(); + size_t result_length = length; + result.reserve(length * 2); + for (size_t i = 0; i < length; ++i) { + if (pt_string[i] == '\"' || pt_string[i] == '\\') { + result += '\\'; + } else if (pt_string[i] == '\n') { + result_length--; // contentLength is adjusted when this character is + // not copied to result. + continue; + } + result += pt_string[i]; + } + pt_string = result; + return result_length; +} +#endif // PROPRIETARY_MODE + +} // namespace mobile + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_tbt_client_state_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_tbt_client_state_notification.cc new file mode 100644 index 0000000000..894469ac34 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_tbt_client_state_notification.cc @@ -0,0 +1,70 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/on_tbt_client_state_notification.h" + +#include "application_manager/application_impl.h" +#include "interfaces/MOBILE_API.h" + +namespace application_manager { + +namespace commands { + +OnTBTClientStateNotification::OnTBTClientStateNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationImpl(message, application_manager) {} + +OnTBTClientStateNotification::~OnTBTClientStateNotification() {} + +void OnTBTClientStateNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + (*message_)[strings::params][strings::message_type] = + static_cast<int32_t>(application_manager::MessageType::kNotification); + + const std::vector<ApplicationSharedPtr>& applications = + application_manager_.applications_with_navi(); + + std::vector<ApplicationSharedPtr>::const_iterator it = applications.begin(); + for (; applications.end() != it; ++it) { + ApplicationSharedPtr app = *it; + if (mobile_apis::HMILevel::eType::HMI_NONE != app->hmi_level()) { + (*message_)[strings::params][strings::connection_key] = app->app_id(); + SendNotification(); + } + } +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_touch_event_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_touch_event_notification.cc new file mode 100644 index 0000000000..2a9969eac4 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_touch_event_notification.cc @@ -0,0 +1,87 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/on_touch_event_notification.h" + +#include "application_manager/application_impl.h" + +namespace application_manager { + +namespace commands { + +namespace mobile { + +OnTouchEventNotification::OnTouchEventNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationImpl(message, application_manager) {} + +OnTouchEventNotification::~OnTouchEventNotification() {} + +void OnTouchEventNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + const std::vector<ApplicationSharedPtr>& applications_with_navi = + application_manager_.applications_with_navi(); + + const std::vector<ApplicationSharedPtr>& projection_applications = + application_manager_.applications_with_mobile_projection(); + + std::vector<ApplicationSharedPtr>::const_iterator nav_it = + applications_with_navi.begin(); + + for (; applications_with_navi.end() != nav_it; ++nav_it) { + ApplicationSharedPtr app = *nav_it; + if (app->IsFullscreen()) { + (*message_)[strings::params][strings::connection_key] = app->app_id(); + SendNotification(); + } + } + + std::vector<ApplicationSharedPtr>::const_iterator projection_it = + projection_applications.begin(); + + for (; projection_applications.end() != projection_it; ++projection_it) { + ApplicationSharedPtr projection_app = *projection_it; + if (projection_app->IsFullscreen()) { + (*message_)[strings::params][strings::connection_key] = + projection_app->app_id(); + SendNotification(); + } + } +} + +} // namespace mobile + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_vehicle_data_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_vehicle_data_notification.cc new file mode 100644 index 0000000000..37abbab351 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_vehicle_data_notification.cc @@ -0,0 +1,112 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/on_vehicle_data_notification.h" + +#include "application_manager/application_impl.h" +#include "application_manager/message_helper.h" +#include "interfaces/MOBILE_API.h" + +namespace application_manager { + +namespace commands { + +OnVehicleDataNotification::OnVehicleDataNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationImpl(message, application_manager) {} + +OnVehicleDataNotification::~OnVehicleDataNotification() {} + +void OnVehicleDataNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + std::vector<ApplicationSharedPtr> appNotification; + std::vector<ApplicationSharedPtr>::iterator appNotification_it = + appNotification.begin(); + std::vector<smart_objects::SmartObject> appSO; + + const VehicleData& vehicle_data = MessageHelper::vehicle_data(); + VehicleData::const_iterator it = vehicle_data.begin(); + + for (; vehicle_data.end() != it; ++it) { + if (true == (*message_)[strings::msg_params].keyExists(it->first)) { + const std::vector<ApplicationSharedPtr>& applications = + application_manager_.IviInfoUpdated( + it->second, (*message_)[strings::msg_params][it->first].asInt()); + + std::vector<ApplicationSharedPtr>::const_iterator app_it = + applications.begin(); + + for (; applications.end() != app_it; ++app_it) { + const ApplicationSharedPtr app = *app_it; + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + continue; + } + + appNotification_it = + find(appNotification.begin(), appNotification.end(), app); + if (appNotification_it == appNotification.end()) { + appNotification.push_back(app); + smart_objects::SmartObject msg_param = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_param[it->first] = (*message_)[strings::msg_params][it->first]; + appSO.push_back(msg_param); + } else { + size_t idx = + std::distance(appNotification.begin(), appNotification_it); + appSO[idx][it->first] = (*message_)[strings::msg_params][it->first]; + } + } + } + } + + LOG4CXX_DEBUG( + logger_, + "Number of Notifications to be send: " << appNotification.size()); + + for (size_t idx = 0; idx < appNotification.size(); idx++) { + LOG4CXX_INFO(logger_, + "Send OnVehicleData PRNDL notification to " + << appNotification[idx]->name().c_str() + << " application id " << appNotification[idx]->app_id()); + (*message_)[strings::params][strings::connection_key] = + appNotification[idx]->app_id(); + (*message_)[strings::msg_params] = appSO[idx]; + SendNotification(); + } +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_way_point_change_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_way_point_change_notification.cc new file mode 100644 index 0000000000..0b24228810 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_way_point_change_notification.cc @@ -0,0 +1,61 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/on_way_point_change_notification.h" +#include "application_manager/application_manager.h" + +namespace application_manager { +namespace commands { + +OnWayPointChangeNotification::OnWayPointChangeNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandNotificationImpl(message, application_manager) {} + +OnWayPointChangeNotification::~OnWayPointChangeNotification() {} + +void OnWayPointChangeNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + std::set<int32_t> subscribed_for_way_points = + application_manager_.GetAppsSubscribedForWayPoints(); + + for (std::set<int32_t>::const_iterator app_id = + subscribed_for_way_points.begin(); + app_id != subscribed_for_way_points.end(); + ++app_id) { + (*message_)[strings::params][strings::connection_key] = *app_id; + SendNotification(); + } +} +} // namespace commands +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/perform_audio_pass_thru_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/perform_audio_pass_thru_request.cc new file mode 100644 index 0000000000..a758f04aac --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/perform_audio_pass_thru_request.cc @@ -0,0 +1,449 @@ +/* + + Copyright (c) 2013, 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 <cstring> +#include "application_manager/commands/mobile/perform_audio_pass_thru_request.h" + +#include "application_manager/application_impl.h" +#include "application_manager/message_helper.h" +#include "utils/helpers.h" + +namespace application_manager { + +namespace commands { + +namespace str = strings; + +PerformAudioPassThruRequest::PerformAudioPassThruRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) + , result_tts_speak_(hmi_apis::Common_Result::INVALID_ENUM) + , result_ui_(hmi_apis::Common_Result::INVALID_ENUM) { + subscribe_on_event(hmi_apis::FunctionID::TTS_OnResetTimeout); +} + +PerformAudioPassThruRequest::~PerformAudioPassThruRequest() {} + +void PerformAudioPassThruRequest::onTimeOut() { + LOG4CXX_AUTO_TRACE(logger_); + + FinishTTSSpeak(); + CommandRequestImpl::onTimeOut(); +} + +bool PerformAudioPassThruRequest::Init() { + default_timeout_ += + (((*message_)[str::msg_params][str::max_duration].asUInt())); + return true; +} + +void PerformAudioPassThruRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "APPLICATION_NOT_REGISTERED"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + if (mobile_api::HMILevel::HMI_NONE == app->hmi_level()) { + LOG4CXX_ERROR(logger_, "application isn't activated"); + SendResponse(false, mobile_apis::Result::REJECTED); + return; + } + + if (IsWhiteSpaceExist()) { + LOG4CXX_ERROR(logger_, + "Incoming perform audio pass thru has contains " + "\\t\\n \\\\t \\\\n" + " text contains only whitespace in initialPrompt"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + // According with new implementation processing of UNSUPPORTE_RESOURCE + // need set flag before sending to hmi + + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + if ((*message_)[str::msg_params].keyExists(str::initial_prompt)) { + smart_objects::SmartObject& initial_prompt = + (*message_)[strings::msg_params][strings::initial_prompt]; + mobile_apis::Result::eType verification_result = + MessageHelper::VerifyTtsFiles( + initial_prompt, app, application_manager_); + + if (mobile_apis::Result::FILE_NOT_FOUND == verification_result) { + LOG4CXX_ERROR(logger_, + "MessageHelper::VerifyTtsFiles return " + << verification_result); + SendResponse( + false, + mobile_apis::Result::FILE_NOT_FOUND, + "One or more files needed for initial_prompt are not present"); + return; + } + + // In case TTS Speak, subscribe on notification + SendSpeakRequest(); + SendPerformAudioPassThruRequest(); + } else { + SendPerformAudioPassThruRequest(); + SendRecordStartNotification(); + StartMicrophoneRecording(); + } +} + +void PerformAudioPassThruRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace helpers; + + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::UI_PerformAudioPassThru: { + LOG4CXX_TRACE(logger_, "Received UI_PerformAudioPassThru"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + + result_ui_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asUInt()); + GetInfo(message, ui_info_); + + // in case perform audio is started by other request skip stopping + if (hmi_apis::Common_Result::REJECTED == result_ui_) { + LOG4CXX_ERROR(logger_, "Request was rejected"); + SendResponse(false, + MessageHelper::HMIToMobileResult(result_ui_), + NULL, + &(message[strings::msg_params])); + return; + } + FinishTTSSpeak(); + break; + } + case hmi_apis::FunctionID::TTS_Speak: { + LOG4CXX_INFO(logger_, "Received TTS_Speak event"); + result_tts_speak_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asUInt()); + GetInfo(message, tts_info_); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_TTS); + const bool is_tts_speak_success_unsuported = + Compare<hmi_apis::Common_Result::eType, EQ, ONE>( + result_tts_speak_, + hmi_apis::Common_Result::SUCCESS, + hmi_apis::Common_Result::WARNINGS, + hmi_apis::Common_Result::WRONG_LANGUAGE, + hmi_apis::Common_Result::RETRY, + hmi_apis::Common_Result::SAVED, + hmi_apis::Common_Result::UNSUPPORTED_RESOURCE); + + if (is_tts_speak_success_unsuported) { + SendRecordStartNotification(); + StartMicrophoneRecording(); + + // update request timeout to get time for perform audio recording + application_manager_.updateRequestTimeout( + connection_key(), correlation_id(), default_timeout()); + } + break; + } + case hmi_apis::FunctionID::TTS_OnResetTimeout: { + LOG4CXX_INFO(logger_, "Received TTS_OnResetTimeout event"); + + application_manager_.updateRequestTimeout( + connection_key(), correlation_id(), default_timeout()); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } + if (IsWaitingHMIResponse()) { + return; + } + + const ResponseParams response_params = PrepareResponseParameters(); + + SendResponse( + response_params.success, + response_params.result_code, + response_params.info.empty() ? NULL : response_params.info.c_str(), + &(message[strings::msg_params])); +} + +const PerformAudioPassThruRequest::ResponseParams& +PerformAudioPassThruRequest::PrepareResponseParameters() { + LOG4CXX_AUTO_TRACE(logger_); + + ResponseInfo ui_perform_info( + result_ui_, HmiInterfaces::HMI_INTERFACE_UI, application_manager_); + ResponseInfo tts_perform_info(result_tts_speak_, + HmiInterfaces::HMI_INTERFACE_TTS, + application_manager_); + + // Note(dtrunov): According to requirment "WARNINGS, success:true on getting + // UNSUPPORTED_RESOURCE for "ttsChunks" + if (ui_perform_info.is_ok && tts_perform_info.is_unsupported_resource && + HmiInterfaces::STATE_AVAILABLE == tts_perform_info.interface_state) { + response_params_.result_code = mobile_apis::Result::WARNINGS; + tts_info_ = "Unsupported phoneme type sent in a prompt"; + response_params_.info = + MergeInfos(ui_perform_info, ui_info_, tts_perform_info, tts_info_); + response_params_.success = true; + return response_params_; + } + + response_params_.success = + PrepareResultForMobileResponse(ui_perform_info, tts_perform_info); + if (IsResultCodeUnsupported(ui_perform_info, tts_perform_info)) { + response_params_.result_code = mobile_apis::Result::UNSUPPORTED_RESOURCE; + } else { + AudioPassThruResults results = PrepareAudioPassThruResultCodeForResponse( + ui_perform_info, tts_perform_info); + response_params_.success = results.second; + response_params_.result_code = results.first; + } + response_params_.info = + MergeInfos(ui_perform_info, ui_info_, tts_perform_info, tts_info_); + + return response_params_; +} + +bool PerformAudioPassThruRequest::PrepareResponseParameters( + mobile_apis::Result::eType& result_code, std::string& info) { + LOG4CXX_AUTO_TRACE(logger_); + NOTREACHED(); + return false; +} + +void PerformAudioPassThruRequest::SendSpeakRequest() { + LOG4CXX_AUTO_TRACE(logger_); + + using namespace hmi_apis; + using namespace smart_objects; + + SmartObject msg_params = smart_objects::SmartObject(SmartType_Map); + for (uint32_t i = 0; + i < (*message_)[str::msg_params][str::initial_prompt].length(); + ++i) { + msg_params[hmi_request::tts_chunks][i][str::text] = + (*message_)[str::msg_params][str::initial_prompt][i][str::text]; + msg_params[hmi_request::tts_chunks][i][str::type] = + (*message_)[str::msg_params][str::initial_prompt][i][str::type]; + } + // app_id + msg_params[strings::app_id] = connection_key(); + msg_params[hmi_request::speak_type] = Common_MethodName::AUDIO_PASS_THRU; + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_TTS); + SendHMIRequest(FunctionID::TTS_Speak, &msg_params, true); +} + +void PerformAudioPassThruRequest::SendPerformAudioPassThruRequest() { + LOG4CXX_AUTO_TRACE(logger_); + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + msg_params[str::app_id] = connection_key(); + + msg_params[hmi_request::max_duration] = + (*message_)[str::msg_params][str::max_duration]; + + msg_params[hmi_request::audio_pass_display_texts] = + smart_objects::SmartObject(smart_objects::SmartType_Array); + + if ((*message_)[str::msg_params].keyExists(str::audio_pass_display_text1)) { + msg_params[hmi_request::audio_pass_display_texts][0] + [hmi_request::field_name] = static_cast<int32_t>( + hmi_apis::Common_TextFieldName::audioPassThruDisplayText1); + msg_params[hmi_request::audio_pass_display_texts][0] + [hmi_request::field_text] = + (*message_)[str::msg_params][str::audio_pass_display_text1]; + } + + if ((*message_)[str::msg_params].keyExists(str::audio_pass_display_text2)) { + msg_params[hmi_request::audio_pass_display_texts][1] + [hmi_request::field_name] = static_cast<int32_t>( + hmi_apis::Common_TextFieldName::audioPassThruDisplayText2); + msg_params[hmi_request::audio_pass_display_texts][1] + [hmi_request::field_text] = + (*message_)[str::msg_params][str::audio_pass_display_text2]; + } + + if ((*message_)[str::msg_params].keyExists(str::mute_audio)) { + msg_params[str::mute_audio] = + (*message_)[str::msg_params][str::mute_audio].asBool(); + } else { + // If omitted, the value is set to true + msg_params[str::mute_audio] = true; + } + + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + SendHMIRequest( + hmi_apis::FunctionID::UI_PerformAudioPassThru, &msg_params, true); +} + +void PerformAudioPassThruRequest::SendRecordStartNotification() { + LOG4CXX_AUTO_TRACE(logger_); + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_params[strings::app_id] = connection_key(); + + CreateHMINotification(hmi_apis::FunctionID::UI_OnRecordStart, msg_params); +} + +void PerformAudioPassThruRequest::StartMicrophoneRecording() { + LOG4CXX_AUTO_TRACE(logger_); + + uint32_t app_id = connection_key(); + application_manager_.BeginAudioPassThru(app_id); + + application_manager_.StartAudioPassThruThread( + connection_key(), + correlation_id(), + (*message_)[str::msg_params][str::max_duration].asInt(), + (*message_)[str::msg_params][str::sampling_rate].asInt(), + (*message_)[str::msg_params][str::bits_per_sample].asInt(), + (*message_)[str::msg_params][str::audio_type].asInt()); +} + +bool PerformAudioPassThruRequest::IsWhiteSpaceExist() { + LOG4CXX_AUTO_TRACE(logger_); + const char* str = NULL; + + if ((*message_)[strings::msg_params].keyExists(strings::initial_prompt)) { + const smart_objects::SmartArray* ip_array = + (*message_)[strings::msg_params][strings::initial_prompt].asArray(); + + smart_objects::SmartArray::const_iterator it_ip = ip_array->begin(); + smart_objects::SmartArray::const_iterator it_ip_end = ip_array->end(); + + for (; it_ip != it_ip_end; ++it_ip) { + str = (*it_ip)[strings::text].asCharArray(); + if (std::strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid initial_prompt syntax check failed"); + return true; + } + } + } + + if ((*message_)[strings::msg_params].keyExists( + strings::audio_pass_display_text1)) { + str = (*message_)[strings::msg_params][strings::audio_pass_display_text1] + .asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR( + logger_, + "Invalid audio_pass_display_text1 value syntax check failed"); + return true; + } + } + + if ((*message_)[strings::msg_params].keyExists( + strings::audio_pass_display_text2)) { + str = (*message_)[strings::msg_params][strings::audio_pass_display_text2] + .asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR( + logger_, + "Invalid audio_pass_display_text2 value syntax check failed"); + return true; + } + } + return false; +} + +void PerformAudioPassThruRequest::FinishTTSSpeak() { + LOG4CXX_AUTO_TRACE(logger_); + uint32_t app_id = connection_key(); + if (application_manager_.EndAudioPassThru(app_id)) { + LOG4CXX_DEBUG(logger_, "Stop AudioPassThru."); + application_manager_.StopAudioPassThru(app_id); + } + if (!IsInterfaceAwaited(HmiInterfaces::HMI_INTERFACE_TTS)) { + LOG4CXX_WARN(logger_, "TTS Speak is inactive."); + return; + } + SendHMIRequest(hmi_apis::FunctionID::TTS_StopSpeaking, NULL); +} + +PerformAudioPassThruRequest::AudioPassThruResults +PerformAudioPassThruRequest::PrepareAudioPassThruResultCodeForResponse( + const ResponseInfo& ui_response, const ResponseInfo& tts_response) { + mobile_apis::Result::eType result_code = mobile_apis::Result::INVALID_ENUM; + + hmi_apis::Common_Result::eType common_result = + hmi_apis::Common_Result::INVALID_ENUM; + const hmi_apis::Common_Result::eType ui_result = ui_response.result_code; + const hmi_apis::Common_Result::eType tts_result = tts_response.result_code; + bool result = false; + + if ((ui_result == hmi_apis::Common_Result::SUCCESS) && + (tts_result == hmi_apis::Common_Result::SUCCESS)) { + result = true; + } + + if ((ui_result == hmi_apis::Common_Result::SUCCESS) && + (tts_result == hmi_apis::Common_Result::INVALID_ENUM)) { + result = true; + } + + if ((ui_result == hmi_apis::Common_Result::SUCCESS) && + (tts_result != hmi_apis::Common_Result::SUCCESS) && + (tts_result != hmi_apis::Common_Result::INVALID_ENUM)) { + common_result = hmi_apis::Common_Result::WARNINGS; + result = true; + } else if (ui_response.is_ok && + tts_result == hmi_apis::Common_Result::WARNINGS) { + common_result = hmi_apis::Common_Result::WARNINGS; + result = true; + } else if (ui_result == hmi_apis::Common_Result::INVALID_ENUM) { + common_result = tts_result; + } else { + common_result = ui_result; + } + result_code = MessageHelper::HMIToMobileResult(common_result); + return std::make_pair(result_code, result); +} + +bool PerformAudioPassThruRequest::IsWaitingHMIResponse() { + LOG4CXX_AUTO_TRACE(logger_); + return IsInterfaceAwaited(HmiInterfaces::HMI_INTERFACE_TTS) || + IsInterfaceAwaited(HmiInterfaces::HMI_INTERFACE_UI); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/perform_audio_pass_thru_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/perform_audio_pass_thru_response.cc new file mode 100644 index 0000000000..1bda9f5096 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/perform_audio_pass_thru_response.cc @@ -0,0 +1,55 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/perform_audio_pass_thru_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +PerformAudioPassThruResponse::PerformAudioPassThruResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +PerformAudioPassThruResponse::~PerformAudioPassThruResponse() {} + +void PerformAudioPassThruResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/perform_interaction_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/perform_interaction_request.cc new file mode 100644 index 0000000000..86ab0a97c0 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/perform_interaction_request.cc @@ -0,0 +1,1004 @@ +/* + + Copyright (c) 2016, 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 <numeric> +#include <string.h> +#include <string> +#include "application_manager/commands/mobile/perform_interaction_request.h" + +#include "application_manager/application_impl.h" +#include "application_manager/message_helper.h" + +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" +#include "utils/file_system.h" +#include "utils/helpers.h" +#include "utils/custom_string.h" +#include "utils/gen_hash.h" + +namespace application_manager { + +namespace commands { + +namespace custom_str = utils::custom_string; + +uint32_t PerformInteractionRequest::pi_requests_count_ = 0; + +PerformInteractionRequest::PerformInteractionRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) + , interaction_mode_(mobile_apis::InteractionMode::INVALID_ENUM) + , ui_response_received_(false) + , vr_response_received_(false) + , app_pi_was_active_before_(false) + , vr_result_code_(hmi_apis::Common_Result::INVALID_ENUM) + , ui_result_code_(hmi_apis::Common_Result::INVALID_ENUM) { + subscribe_on_event(hmi_apis::FunctionID::UI_OnResetTimeout); + subscribe_on_event(hmi_apis::FunctionID::VR_OnCommand); + subscribe_on_event(hmi_apis::FunctionID::Buttons_OnButtonPress); +} + +PerformInteractionRequest::~PerformInteractionRequest() {} + +bool PerformInteractionRequest::Init() { + /* Timeout in milliseconds. + If omitted a standard value of 10000 milliseconds is used.*/ + if ((*message_)[strings::msg_params].keyExists(strings::timeout)) { + default_timeout_ = + (*message_)[strings::msg_params][strings::timeout].asUInt(); + } + + interaction_mode_ = static_cast<mobile_apis::InteractionMode::eType>( + (*message_)[strings::msg_params][strings::interaction_mode].asInt()); + + if (mobile_apis::InteractionMode::BOTH == interaction_mode_ || + mobile_apis::InteractionMode::MANUAL_ONLY == interaction_mode_) { + default_timeout_ *= 2; + } + return true; +} + +void PerformInteractionRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "Application is not registered"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + if (app->is_perform_interaction_active()) { + LOG4CXX_DEBUG(logger_, "Application has active PerformInteraction"); + app_pi_was_active_before_ = true; + } + + smart_objects::SmartObject& msg_params = (*message_)[strings::msg_params]; + mobile_apis::LayoutMode::eType interaction_layout = + mobile_apis::LayoutMode::INVALID_ENUM; + + if (msg_params.keyExists(hmi_request::interaction_layout)) { + interaction_layout = static_cast<mobile_apis::LayoutMode::eType>( + msg_params[hmi_request::interaction_layout].asInt()); + } + + if ((mobile_apis::InteractionMode::VR_ONLY == interaction_mode_) && + (mobile_apis::LayoutMode::KEYBOARD == interaction_layout)) { + LOG4CXX_ERROR(logger_, + "PerformInteraction contains InteractionMode" + "=VR_ONLY and interactionLayout=KEYBOARD"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + const size_t choice_set_id_list_length = + msg_params[strings::interaction_choice_set_id_list].length(); + + if (0 == choice_set_id_list_length) { + if (mobile_apis::LayoutMode::KEYBOARD == interaction_layout) { + if (mobile_apis::InteractionMode::BOTH == interaction_mode_) { + LOG4CXX_ERROR(logger_, + "interactionChoiceSetIDList is empty," + " InteractionMode=BOTH and" + " interactionLayout=KEYBOARD"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + } else { + LOG4CXX_ERROR(logger_, + "interactionChoiceSetIDList is empty" + " and interactionLayout!=KEYBOARD"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + } + + if (!CheckChoiceIDFromRequest( + app, + choice_set_id_list_length, + msg_params[strings::interaction_choice_set_id_list])) { + LOG4CXX_ERROR(logger_, + "PerformInteraction has choice sets with " + "duplicated IDs or application does not have choice sets"); + SendResponse(false, mobile_apis::Result::INVALID_ID); + return; + } + + if (msg_params.keyExists(strings::vr_help)) { + if (mobile_apis::Result::SUCCESS != + MessageHelper::VerifyImageVrHelpItems( + msg_params[strings::vr_help], app, application_manager_)) { + LOG4CXX_ERROR(logger_, + "Verification of " << strings::vr_help << " failed."); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + } + + if (IsWhiteSpaceExist()) { + LOG4CXX_ERROR(logger_, + "Incoming perform interaction has contains \t\n \\t \\n"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + switch (interaction_mode_) { + case mobile_apis::InteractionMode::BOTH: { + LOG4CXX_DEBUG(logger_, "Interaction Mode: BOTH"); + if (!CheckChoiceSetVRSynonyms(app) || !CheckChoiceSetMenuNames(app) || + !CheckVrHelpItemPositions(app)) { + return; + } + break; + } + case mobile_apis::InteractionMode::MANUAL_ONLY: { + LOG4CXX_DEBUG(logger_, "Interaction Mode: MANUAL_ONLY"); + if (!CheckChoiceSetVRSynonyms(app) || !CheckChoiceSetMenuNames(app) || + !CheckVrHelpItemPositions(app)) { + return; + } + break; + } + case mobile_apis::InteractionMode::VR_ONLY: { + LOG4CXX_DEBUG(logger_, "Interaction Mode: VR_ONLY"); + if (!CheckChoiceSetVRSynonyms(app) || !CheckVrHelpItemPositions(app)) { + return; + } + break; + } + default: { + LOG4CXX_ERROR(logger_, "Unknown interaction mode"); + return; + } + } + + app->set_perform_interaction_mode(static_cast<int32_t>(interaction_mode_)); + app->set_perform_interaction_active(true); + app->set_perform_interaction_layout(interaction_layout); + // increment amount of active requests + ++pi_requests_count_; + SendVRPerformInteractionRequest(app); + SendUIPerformInteractionRequest(app); +} + +void PerformInteractionRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + smart_objects::SmartObject msg_param = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + switch (event.id()) { + case hmi_apis::FunctionID::UI_OnResetTimeout: { + LOG4CXX_DEBUG(logger_, "Received UI_OnResetTimeout event"); + application_manager_.updateRequestTimeout( + connection_key(), correlation_id(), default_timeout()); + break; + } + case hmi_apis::FunctionID::UI_PerformInteraction: { + LOG4CXX_DEBUG(logger_, "Received UI_PerformInteraction event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + ui_response_received_ = true; + unsubscribe_from_event(hmi_apis::FunctionID::UI_PerformInteraction); + ui_result_code_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asUInt()); + GetInfo(message, ui_info_); + ProcessUIResponse(event.smart_object(), msg_param); + break; + } + case hmi_apis::FunctionID::VR_PerformInteraction: { + LOG4CXX_DEBUG(logger_, "Received VR_PerformInteraction"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VR); + vr_response_received_ = true; + unsubscribe_from_event(hmi_apis::FunctionID::VR_PerformInteraction); + vr_result_code_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asUInt()); + GetInfo(message, vr_info_); + if (ProcessVRResponse(event.smart_object(), msg_param)) { + return; + } + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + break; + } + } + + if (!HasHMIResponsesToWait()) { + LOG4CXX_DEBUG(logger_, "Send response in BOTH iteraction mode"); + SendBothModeResponse(msg_param); + } +} + +void PerformInteractionRequest::onTimeOut() { + LOG4CXX_AUTO_TRACE(logger_); + + switch (interaction_mode_) { + case mobile_apis::InteractionMode::BOTH: { + LOG4CXX_DEBUG(logger_, "Interaction Mode: BOTH"); + if (true == vr_response_received_) { + unsubscribe_from_event(hmi_apis::FunctionID::UI_PerformInteraction); + DisablePerformInteraction(); + CommandRequestImpl::onTimeOut(); + } else { + application_manager_.updateRequestTimeout( + connection_key(), correlation_id(), default_timeout()); + } + break; + } + case mobile_apis::InteractionMode::VR_ONLY: { + LOG4CXX_DEBUG(logger_, "Interaction Mode: VR_ONLY"); + unsubscribe_from_event(hmi_apis::FunctionID::UI_PerformInteraction); + DisablePerformInteraction(); + CommandRequestImpl::onTimeOut(); + break; + } + case mobile_apis::InteractionMode::MANUAL_ONLY: { + LOG4CXX_DEBUG(logger_, "InteractionMode: MANUAL_ONLY"); + unsubscribe_from_event(hmi_apis::FunctionID::UI_PerformInteraction); + DisablePerformInteraction(); + CommandRequestImpl::onTimeOut(); + break; + } + default: { + LOG4CXX_ERROR(logger_, "INVALID ENUM"); + return; + } + }; +} + +bool PerformInteractionRequest::ProcessVRResponse( + const smart_objects::SmartObject& message, + smart_objects::SmartObject& msg_params) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace hmi_apis; + using namespace mobile_apis; + using namespace smart_objects; + using namespace helpers; + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + return false; + } + + msg_params[strings::trigger_source] = + static_cast<int32_t>(TriggerSource::TS_VR); + + const bool is_vr_aborted_timeout = Compare<Common_Result::eType, EQ, ONE>( + vr_result_code_, Common_Result::ABORTED, Common_Result::TIMED_OUT); + + if (is_vr_aborted_timeout) { + LOG4CXX_DEBUG(logger_, "VR response aborted"); + if (InteractionMode::VR_ONLY == interaction_mode_) { + LOG4CXX_DEBUG(logger_, "Aborted or Timeout Send Close Popup"); + TerminatePerformInteraction(); + SendResponse(false, MessageHelper::HMIToMobileResult(vr_result_code_)); + return true; + } + LOG4CXX_DEBUG(logger_, "Update timeout for UI"); + application_manager_.updateRequestTimeout( + connection_key(), correlation_id(), default_timeout()); + return false; + } + + if (Common_Result::SUCCESS == vr_result_code_ && + InteractionMode::MANUAL_ONLY == interaction_mode_) { + LOG4CXX_DEBUG(logger_, + "VR response SUCCESS in MANUAL_ONLY mode " + << "Wait for UI response"); + // in case MANUAL_ONLY mode VR.PI SUCCESS just return + return false; + } + + const SmartObject& hmi_msg_params = message[strings::msg_params]; + if (hmi_msg_params.keyExists(strings::choice_id)) { + const int choise_id = hmi_msg_params[strings::choice_id].asInt(); + if (!CheckChoiceIDFromResponse(app, choise_id)) { + LOG4CXX_ERROR(logger_, "Wrong choiceID was received from HMI"); + TerminatePerformInteraction(); + SendResponse( + false, Result::GENERIC_ERROR, "Wrong choiceID was received from HMI"); + return true; + } + msg_params[strings::choice_id] = choise_id; + } + return false; +} + +void PerformInteractionRequest::ProcessUIResponse( + const smart_objects::SmartObject& message, + smart_objects::SmartObject& msg_params) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace helpers; + using namespace smart_objects; + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + return; + } + + HmiInterfaces::InterfaceState ui_interface_state = + application_manager_.hmi_interfaces().GetInterfaceState( + HmiInterfaces::HMI_INTERFACE_UI); + bool result = false; + result = Compare<hmi_apis::Common_Result::eType, EQ, ONE>( + ui_result_code_, + hmi_apis::Common_Result::SUCCESS, + hmi_apis::Common_Result::WARNINGS); + + result = result || + (hmi_apis::Common_Result::UNSUPPORTED_RESOURCE == ui_result_code_ && + HmiInterfaces::STATE_NOT_AVAILABLE != ui_interface_state); + + const bool is_pi_warning = Compare<hmi_apis::Common_Result::eType, EQ, ONE>( + ui_result_code_, hmi_apis::Common_Result::WARNINGS); + + const bool is_pi_unsupported = + Compare<hmi_apis::Common_Result::eType, EQ, ONE>( + ui_result_code_, hmi_apis::Common_Result::UNSUPPORTED_RESOURCE); + + if (result) { + if (is_pi_warning) { + ui_result_code_ = hmi_apis::Common_Result::WARNINGS; + ui_info_ = message[strings::msg_params][strings::info].asString(); + if (message.keyExists(strings::params) && + message[strings::params].keyExists(strings::data)) { + msg_params = message[strings::params][strings::data]; + } + } else if (is_pi_unsupported) { + ui_result_code_ = hmi_apis::Common_Result::UNSUPPORTED_RESOURCE; + ui_info_ = message[strings::msg_params][strings::info].asString(); + } else if (message.keyExists(strings::msg_params)) { + msg_params = message[strings::msg_params]; + } + // result code must be GENERIC_ERROR in case wrong choice_id + if (msg_params.keyExists(strings::choice_id)) { + if (!CheckChoiceIDFromResponse(app, + msg_params[strings::choice_id].asInt())) { + ui_result_code_ = hmi_apis::Common_Result::GENERIC_ERROR; + ui_info_ = "Wrong choiceID was received from HMI"; + } else { + msg_params[strings::trigger_source] = + mobile_apis::TriggerSource::TS_MENU; + } + } else if (msg_params.keyExists(strings::manual_text_entry)) { + msg_params[strings::trigger_source] = + mobile_apis::TriggerSource::TS_KEYBOARD; + if (msg_params[strings::manual_text_entry].empty()) { + msg_params.erase(strings::manual_text_entry); + } + } + } +} + +void PerformInteractionRequest::SendUIPerformInteractionRequest( + application_manager::ApplicationSharedPtr const app) { + LOG4CXX_AUTO_TRACE(logger_); + smart_objects::SmartObject& choice_set_id_list = + (*message_)[strings::msg_params][strings::interaction_choice_set_id_list]; + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + mobile_apis::InteractionMode::eType mode = + static_cast<mobile_apis::InteractionMode::eType>( + (*message_)[strings::msg_params][strings::interaction_mode].asInt()); + + if (mobile_apis::InteractionMode::VR_ONLY != mode) { + msg_params[hmi_request::initial_text][hmi_request::field_name] = + static_cast<int32_t>( + hmi_apis::Common_TextFieldName::initialInteractionText); + msg_params[hmi_request::initial_text][hmi_request::field_text] = + (*message_)[strings::msg_params][hmi_request::initial_text]; + } + bool is_vr_help_item = false; + if (mobile_apis::InteractionMode::MANUAL_ONLY != mode) { + msg_params[strings::vr_help_title] = + (*message_)[strings::msg_params][strings::initial_text].asString(); + if ((*message_)[strings::msg_params].keyExists(strings::vr_help)) { + is_vr_help_item = true; + msg_params[strings::vr_help] = + (*message_)[strings::msg_params][strings::vr_help]; + } + } + + if (mobile_apis::InteractionMode::BOTH == mode || + mobile_apis::InteractionMode::MANUAL_ONLY == mode) { + msg_params[strings::timeout] = default_timeout_ / 2; + } else { + msg_params[strings::timeout] = default_timeout_; + } + msg_params[strings::app_id] = app->app_id(); + if (mobile_apis::InteractionMode::VR_ONLY != mode) { + msg_params[strings::choice_set] = + smart_objects::SmartObject(smart_objects::SmartType_Array); + } + int32_t index_array_of_vr_help = 0; + for (size_t i = 0; i < choice_set_id_list.length(); ++i) { + smart_objects::SmartObject* choice_set = + app->FindChoiceSet(choice_set_id_list[i].asInt()); + if (choice_set) { + // save perform interaction choice set + app->AddPerformInteractionChoiceSet( + correlation_id(), choice_set_id_list[i].asInt(), *choice_set); + for (size_t j = 0; j < (*choice_set)[strings::choice_set].length(); ++j) { + if (mobile_apis::InteractionMode::VR_ONLY != mode) { + size_t index = msg_params[strings::choice_set].length(); + msg_params[strings::choice_set][index] = + (*choice_set)[strings::choice_set][j]; + // vrCommands should be added via VR.AddCommand only + msg_params[strings::choice_set][index].erase(strings::vr_commands); + } + if (mobile_apis::InteractionMode::MANUAL_ONLY != mode && + !is_vr_help_item) { + smart_objects::SmartObject& vr_commands = + (*choice_set)[strings::choice_set][j][strings::vr_commands]; + if (0 < vr_commands.length()) { + // copy only first synonym + smart_objects::SmartObject item(smart_objects::SmartType_Map); + item[strings::text] = vr_commands[0].asString(); + item[strings::position] = index_array_of_vr_help + 1; + msg_params[strings::vr_help][index_array_of_vr_help++] = item; + } + } + } + } + } + if ((*message_)[strings::msg_params].keyExists( + hmi_request::interaction_layout) && + mobile_apis::InteractionMode::VR_ONLY != mode) { + msg_params[hmi_request::interaction_layout] = + (*message_)[strings::msg_params][hmi_request::interaction_layout] + .asInt(); + } + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + SendHMIRequest( + hmi_apis::FunctionID::UI_PerformInteraction, &msg_params, true); +} + +void PerformInteractionRequest::SendVRPerformInteractionRequest( + application_manager::ApplicationSharedPtr const app) { + LOG4CXX_AUTO_TRACE(logger_); + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + smart_objects::SmartObject& choice_list = + (*message_)[strings::msg_params][strings::interaction_choice_set_id_list]; + + if (mobile_apis::InteractionMode::MANUAL_ONLY != interaction_mode_) { + msg_params[strings::grammar_id] = + smart_objects::SmartObject(smart_objects::SmartType_Array); + + int32_t grammar_id_index = 0; + for (uint32_t i = 0; i < choice_list.length(); ++i) { + smart_objects::SmartObject* choice_set = + app->FindChoiceSet(choice_list[i].asInt()); + if (!choice_set) { + LOG4CXX_WARN(logger_, "Couldn't found choiset"); + continue; + } + msg_params[strings::grammar_id][grammar_id_index++] = + (*choice_set)[strings::grammar_id].asUInt(); + } + } + + std::vector<std::string> invalid_params; + if ((*message_)[strings::msg_params].keyExists(strings::help_prompt)) { + smart_objects::SmartObject& help_prompt = + (*message_)[strings::msg_params][strings::help_prompt]; + mobile_apis::Result::eType verification_result = + MessageHelper::VerifyTtsFiles(help_prompt, app, application_manager_); + + if (mobile_apis::Result::FILE_NOT_FOUND == verification_result) { + LOG4CXX_WARN(logger_, + "MessageHelper::VerifyTtsFiles return " + << verification_result); + invalid_params.push_back("help_prompt"); + } else { + msg_params[strings::help_prompt] = help_prompt; + } + } else { + if (choice_list.length() != 0) { + msg_params[strings::help_prompt] = + smart_objects::SmartObject(smart_objects::SmartType_Array); + } + int32_t index = 0; + for (uint32_t i = 0; i < choice_list.length(); ++i) { + smart_objects::SmartObject* choice_set = + app->FindChoiceSet(choice_list[i].asInt()); + + if (choice_set) { + for (uint32_t j = 0; j < (*choice_set)[strings::choice_set].length(); + ++j) { + smart_objects::SmartObject& vr_commands = + (*choice_set)[strings::choice_set][j][strings::vr_commands]; + if (0 < vr_commands.length()) { + // copy only first synonym + smart_objects::SmartObject item(smart_objects::SmartType_Map); + // Since there is no custom data from application side, SDL should + // construct prompt and append delimiter to each item + item[strings::type] = hmi_apis::Common_SpeechCapabilities::SC_TEXT; + item[strings::text] = + vr_commands[0].asString() + + application_manager_.get_settings().tts_delimiter(); + msg_params[strings::help_prompt][index++] = item; + } + } + } else { + LOG4CXX_ERROR(logger_, "Can't found choiceSet!"); + } + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::timeout_prompt)) { + smart_objects::SmartObject& timeout_prompt = + (*message_)[strings::msg_params][strings::timeout_prompt]; + mobile_apis::Result::eType verification_result = + MessageHelper::VerifyTtsFiles( + timeout_prompt, app, application_manager_); + + if (mobile_apis::Result::FILE_NOT_FOUND == verification_result) { + LOG4CXX_WARN(logger_, + "MessageHelper::VerifyTtsFiles return " + << verification_result); + invalid_params.push_back("timeout_prompt"); + } else { + msg_params[strings::timeout_prompt] = timeout_prompt; + } + } else { + if (msg_params.keyExists(strings::help_prompt)) { + msg_params[strings::timeout_prompt] = msg_params[strings::help_prompt]; + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::initial_prompt)) { + smart_objects::SmartObject& initial_prompt = + (*message_)[strings::msg_params][strings::initial_prompt]; + mobile_apis::Result::eType verification_result = + MessageHelper::VerifyTtsFiles( + initial_prompt, app, application_manager_); + + if (mobile_apis::Result::FILE_NOT_FOUND == verification_result) { + LOG4CXX_WARN(logger_, + "MessageHelper::VerifyTtsFiles return " + << verification_result); + invalid_params.push_back("initial_prompt"); + } else { + msg_params[strings::initial_prompt] = initial_prompt; + } + } + + if (!invalid_params.empty()) { + const std::string params_list = + std::accumulate(std::begin(invalid_params), + std::end(invalid_params), + std::string(""), + [](std::string& first, std::string& second) { + return first.empty() ? second : first + ", " + second; + }); + const std::string info = + "One or more files needed for " + params_list + " are not present"; + SendResponse(false, mobile_apis::Result::FILE_NOT_FOUND, info.c_str()); + return; + } + + mobile_apis::InteractionMode::eType mode = + static_cast<mobile_apis::InteractionMode::eType>( + (*message_)[strings::msg_params][strings::interaction_mode].asInt()); + + if (mobile_apis::InteractionMode::BOTH == mode || + mobile_apis::InteractionMode::MANUAL_ONLY == mode) { + msg_params[strings::timeout] = default_timeout_ / 2; + } else { + msg_params[strings::timeout] = default_timeout_; + } + msg_params[strings::app_id] = app->app_id(); + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VR); + SendHMIRequest( + hmi_apis::FunctionID::VR_PerformInteraction, &msg_params, true); +} + +bool PerformInteractionRequest::CheckChoiceSetMenuNames( + application_manager::ApplicationSharedPtr const app) { + LOG4CXX_AUTO_TRACE(logger_); + + smart_objects::SmartObject& choice_list = + (*message_)[strings::msg_params][strings::interaction_choice_set_id_list]; + + for (size_t i = 0; i < choice_list.length(); ++i) { + // choice_set contains SmartObject msg_params + smart_objects::SmartObject* i_choice_set = + app->FindChoiceSet(choice_list[i].asInt()); + + for (size_t j = 0; j < choice_list.length(); ++j) { + smart_objects::SmartObject* j_choice_set = + app->FindChoiceSet(choice_list[j].asInt()); + + if (i == j) { + // skip check the same element + continue; + } + + if (!i_choice_set || !j_choice_set) { + LOG4CXX_ERROR(logger_, "Invalid ID"); + SendResponse(false, mobile_apis::Result::INVALID_ID); + return false; + } + + size_t ii = 0; + size_t jj = 0; + for (; ii < (*i_choice_set)[strings::choice_set].length(); ++ii) { + for (; jj < (*j_choice_set)[strings::choice_set].length(); ++jj) { + const std::string& ii_menu_name = + (*i_choice_set)[strings::choice_set][ii][strings::menu_name] + .asString(); + const std::string& jj_menu_name = + (*j_choice_set)[strings::choice_set][jj][strings::menu_name] + .asString(); + + if (ii_menu_name == jj_menu_name) { + LOG4CXX_ERROR(logger_, "Choice set has duplicated menu name"); + SendResponse(false, + mobile_apis::Result::DUPLICATE_NAME, + "Choice set has duplicated menu name"); + return false; + } + } + } + } + } + + return true; +} + +bool PerformInteractionRequest::CheckChoiceSetVRSynonyms( + application_manager::ApplicationSharedPtr const app) { + LOG4CXX_AUTO_TRACE(logger_); + + smart_objects::SmartObject& choice_list = + (*message_)[strings::msg_params][strings::interaction_choice_set_id_list]; + + for (size_t i = 0; i < choice_list.length(); ++i) { + // choice_set contains SmartObject msg_params + smart_objects::SmartObject* i_choice_set = + app->FindChoiceSet(choice_list[i].asInt()); + + for (size_t j = 0; j < choice_list.length(); ++j) { + smart_objects::SmartObject* j_choice_set = + app->FindChoiceSet(choice_list[j].asInt()); + + if (i == j) { + // skip check the same element + continue; + } + + if ((!i_choice_set) || (!j_choice_set)) { + LOG4CXX_ERROR(logger_, "Invalid ID"); + SendResponse(false, mobile_apis::Result::INVALID_ID); + return false; + } + + size_t ii = 0; + size_t jj = 0; + for (; ii < (*i_choice_set)[strings::choice_set].length(); ++ii) { + for (; jj < (*j_choice_set)[strings::choice_set].length(); ++jj) { + // choice_set pointer contains SmartObject msg_params + smart_objects::SmartObject& ii_vr_commands = + (*i_choice_set)[strings::choice_set][ii][strings::vr_commands]; + + smart_objects::SmartObject& jj_vr_commands = + (*j_choice_set)[strings::choice_set][jj][strings::vr_commands]; + + for (size_t iii = 0; iii < ii_vr_commands.length(); ++iii) { + for (size_t jjj = 0; jjj < jj_vr_commands.length(); ++jjj) { + const custom_str::CustomString& vr_cmd_i = + ii_vr_commands[iii].asCustomString(); + const custom_str::CustomString& vr_cmd_j = + jj_vr_commands[jjj].asCustomString(); + if (vr_cmd_i.CompareIgnoreCase(vr_cmd_j)) { + LOG4CXX_ERROR(logger_, "Choice set has duplicated VR synonym"); + SendResponse(false, + mobile_apis::Result::DUPLICATE_NAME, + "Choice set has duplicated VR synonym"); + return false; + } + } + } + } + } + } + } + return true; +} + +bool PerformInteractionRequest::CheckVrHelpItemPositions( + application_manager::ApplicationSharedPtr const app) { + LOG4CXX_AUTO_TRACE(logger_); + + if (!(*message_)[strings::msg_params].keyExists(strings::vr_help)) { + LOG4CXX_DEBUG(logger_, strings::vr_help << " is omitted."); + return true; + } + + smart_objects::SmartObject& vr_help = + (*message_)[strings::msg_params][strings::vr_help]; + + int32_t position = 1; + for (size_t i = 0; i < vr_help.length(); ++i) { + if (position != vr_help[i][strings::position].asInt()) { + LOG4CXX_ERROR(logger_, "Non-sequential vrHelp item position"); + SendResponse(false, + mobile_apis::Result::REJECTED, + "Non-sequential vrHelp item position"); + return false; + } + ++position; + } + return true; +} + +void PerformInteractionRequest::DisablePerformInteraction() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + return; + } + + if (app->is_perform_interaction_active()) { + // decrease amount of active requests + --pi_requests_count_; + if (!pi_requests_count_) { + app->set_perform_interaction_active(false); + app->set_perform_interaction_mode(-1); + } + } + app->DeletePerformInteractionChoiceSet(correlation_id()); +} + +bool PerformInteractionRequest::IsWhiteSpaceExist() { + LOG4CXX_AUTO_TRACE(logger_); + const char* str = NULL; + + str = (*message_)[strings::msg_params][strings::initial_text].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid initial_text syntax check failed"); + return true; + } + + if ((*message_)[strings::msg_params].keyExists(strings::initial_prompt)) { + const smart_objects::SmartArray* ip_array = + (*message_)[strings::msg_params][strings::initial_prompt].asArray(); + + smart_objects::SmartArray::const_iterator it_ip = ip_array->begin(); + smart_objects::SmartArray::const_iterator it_ip_end = ip_array->end(); + + for (; it_ip != it_ip_end; ++it_ip) { + str = (*it_ip)[strings::text].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid initial_prompt syntax check failed"); + return true; + } + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::help_prompt)) { + const smart_objects::SmartArray* hp_array = + (*message_)[strings::msg_params][strings::help_prompt].asArray(); + + smart_objects::SmartArray::const_iterator it_hp = hp_array->begin(); + smart_objects::SmartArray::const_iterator it_hp_end = hp_array->end(); + + for (; it_hp != it_hp_end; ++it_hp) { + str = (*it_hp)[strings::text].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid help_prompt syntax check failed"); + return true; + } + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::timeout_prompt)) { + const smart_objects::SmartArray* tp_array = + (*message_)[strings::msg_params][strings::timeout_prompt].asArray(); + + smart_objects::SmartArray::const_iterator it_tp = tp_array->begin(); + smart_objects::SmartArray::const_iterator it_tp_end = tp_array->end(); + + for (; it_tp != it_tp_end; ++it_tp) { + str = (*it_tp)[strings::text].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid timeout_prompt syntax check failed"); + return true; + } + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::vr_help)) { + const smart_objects::SmartArray* vh_array = + (*message_)[strings::msg_params][strings::vr_help].asArray(); + + smart_objects::SmartArray::const_iterator it_vh = vh_array->begin(); + smart_objects::SmartArray::const_iterator it_vh_end = vh_array->end(); + + for (; it_vh != it_vh_end; ++it_vh) { + str = (*it_vh)[strings::text].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid vr_help syntax check failed"); + return true; + } + + if ((*it_vh).keyExists(strings::image)) { + str = (*it_vh)[strings::image][strings::value].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid vr_help image value syntax check failed"); + return true; + } + } + } + } + return false; +} + +void PerformInteractionRequest::TerminatePerformInteraction() { + LOG4CXX_AUTO_TRACE(logger_); + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_params[hmi_request::method_name] = "UI.PerformInteraction"; + SendHMIRequest(hmi_apis::FunctionID::UI_ClosePopUp, &msg_params); + DisablePerformInteraction(); +} + +bool PerformInteractionRequest::CheckChoiceIDFromResponse( + ApplicationSharedPtr app, int32_t choice_id) { + LOG4CXX_AUTO_TRACE(logger_); + const DataAccessor<PerformChoiceSetMap> accessor = + app->performinteraction_choice_set_map(); + const PerformChoiceSetMap& choice_set_map = accessor.GetData(); + + PerformChoiceSetMap::const_iterator choice_set_map_it = + choice_set_map.find(correlation_id()); + if (choice_set_map.end() != choice_set_map_it) { + const PerformChoice& choice = choice_set_map_it->second; + PerformChoice::const_iterator it = choice.begin(); + for (; choice.end() != it; ++it) { + const smart_objects::SmartObject& choice_set = + (*it->second).getElement(strings::choice_set); + for (size_t j = 0; j < choice_set.length(); ++j) { + if (choice_id == + choice_set.getElement(j).getElement(strings::choice_id).asInt()) { + return true; + } + } + } + } + return false; +} + +bool PerformInteractionRequest::CheckChoiceIDFromRequest( + ApplicationSharedPtr app, + const size_t choice_set_id_list_length, + const smart_objects::SmartObject& choice_set_id_list) const { + LOG4CXX_AUTO_TRACE(logger_); + + size_t choice_list_length = 0; + std::set<uint32_t> choice_id_set; + smart_objects::SmartObject* choice_set = 0; + std::pair<std::set<uint32_t>::iterator, bool> ins_res; + + for (size_t i = 0; i < choice_set_id_list_length; ++i) { + choice_set = app->FindChoiceSet(choice_set_id_list[i].asInt()); + if (!choice_set) { + LOG4CXX_ERROR( + logger_, + "Couldn't find choiset_id = " << choice_set_id_list[i].asInt()); + return false; + } + choice_list_length = (*choice_set)[strings::choice_set].length(); + const smart_objects::SmartObject& choices_list = + (*choice_set)[strings::choice_set]; + for (size_t k = 0; k < choice_list_length; ++k) { + ins_res = + choice_id_set.insert(choices_list[k][strings::choice_id].asInt()); + if (!ins_res.second) { + LOG4CXX_ERROR(logger_, + "Choise with ID " + << choices_list[k][strings::choice_id].asInt() + << " already exists"); + return false; + } + } + } + return true; +} + +const bool PerformInteractionRequest::HasHMIResponsesToWait() const { + LOG4CXX_AUTO_TRACE(logger_); + return !ui_response_received_ || !vr_response_received_; +} + +void PerformInteractionRequest::SendBothModeResponse( + const smart_objects::SmartObject& msg_param) { + LOG4CXX_AUTO_TRACE(logger_); + mobile_apis::Result::eType perform_interaction_result_code = + mobile_apis::Result::INVALID_ENUM; + ResponseInfo ui_perform_info( + ui_result_code_, HmiInterfaces::HMI_INTERFACE_UI, application_manager_); + ResponseInfo vr_perform_info( + vr_result_code_, HmiInterfaces::HMI_INTERFACE_VR, application_manager_); + const bool result = + PrepareResultForMobileResponse(ui_perform_info, vr_perform_info); + perform_interaction_result_code = + PrepareResultCodeForResponse(ui_perform_info, vr_perform_info); + const smart_objects::SmartObject* response_params = + msg_param.empty() ? NULL : &msg_param; + std::string info = + MergeInfos(ui_perform_info, ui_info_, vr_perform_info, vr_info_); + DisablePerformInteraction(); + SendResponse(result, + perform_interaction_result_code, + info.empty() ? NULL : info.c_str(), + response_params); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/perform_interaction_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/perform_interaction_response.cc new file mode 100644 index 0000000000..1a358e551c --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/perform_interaction_response.cc @@ -0,0 +1,55 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/perform_interaction_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +PerformInteractionResponse::PerformInteractionResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +PerformInteractionResponse::~PerformInteractionResponse() {} + +void PerformInteractionResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/put_file_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/put_file_request.cc new file mode 100644 index 0000000000..8a5e10b206 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/put_file_request.cc @@ -0,0 +1,318 @@ +/* + + Copyright (c) 2013, 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 <algorithm> +#include "application_manager/commands/mobile/put_file_request.h" + +#include "application_manager/policies/policy_handler.h" +#include "application_manager/application_impl.h" +#include "application_manager/rpc_service.h" + +#include "utils/file_system.h" +#include <boost/crc.hpp> + +namespace { +/** +* Calculates CRC32 checksum +* @param binary_data - input data for which CRC32 should be calculated +* @return calculated CRC32 checksum +*/ +uint32_t GetCrc32CheckSum(const std::vector<uint8_t>& binary_data) { + const std::size_t file_size = binary_data.size(); + boost::crc_32_type result; + result.process_bytes(&binary_data[0], file_size); + return result.checksum(); +} + +} // namespace + +namespace application_manager { + +namespace commands { + +PutFileRequest::PutFileRequest(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) + , offset_(0) + , sync_file_name_() + , length_(0) + , file_type_(mobile_apis::FileType::INVALID_ENUM) + , is_persistent_file_(false) {} + +PutFileRequest::~PutFileRequest() {} + +void PutFileRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + smart_objects::SmartObject response_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + if (!application) { + LOG4CXX_ERROR(logger_, "Application is not registered"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + if (mobile_api::HMILevel::HMI_NONE == application->hmi_level() && + application_manager_.get_settings().put_file_in_none() <= + application->put_file_in_none_count()) { + // If application is in the HMI_NONE level the quantity of allowed + // PutFile request is limited by the configuration profile + LOG4CXX_ERROR(logger_, + "Too many requests from the app with HMILevel HMI_NONE "); + SendResponse(false, + mobile_apis::Result::REJECTED, + "Too many requests from the app with HMILevel HMI_NONE", + &response_params); + return; + } + + if (!(*message_)[strings::params].keyExists(strings::binary_data)) { + LOG4CXX_ERROR(logger_, "Binary data empty"); + SendResponse(false, + mobile_apis::Result::INVALID_DATA, + "Binary data empty", + &response_params); + return; + } + + if (!(*message_)[strings::msg_params].keyExists(strings::sync_file_name)) { + LOG4CXX_ERROR(logger_, "No file name"); + SendResponse(false, + mobile_apis::Result::INVALID_DATA, + "No file name", + &response_params); + return; + } + + if (!(*message_)[strings::msg_params].keyExists(strings::file_type)) { + LOG4CXX_ERROR(logger_, "No file type"); + SendResponse(false, + mobile_apis::Result::INVALID_DATA, + "No file type", + &response_params); + return; + } + sync_file_name_ = + (*message_)[strings::msg_params][strings::sync_file_name].asString(); + + if (!file_system::IsFileNameValid(sync_file_name_)) { + const std::string err_msg = "Sync file name contains forbidden symbols."; + LOG4CXX_ERROR(logger_, err_msg); + SendResponse(false, + mobile_apis::Result::INVALID_DATA, + err_msg.c_str(), + &response_params); + return; + } + + file_type_ = static_cast<mobile_apis::FileType::eType>( + (*message_)[strings::msg_params][strings::file_type].asInt()); + const std::vector<uint8_t> binary_data = + (*message_)[strings::params][strings::binary_data].asBinary(); + + // Policy table update in json format is currently to be received via PutFile + // TODO(PV): after latest discussion has to be changed + if (mobile_apis::FileType::JSON == file_type_) { + application_manager_.GetPolicyHandler().ReceiveMessageFromSDK( + sync_file_name_, binary_data); + } + + offset_ = 0; + is_persistent_file_ = false; + bool is_system_file = false; + length_ = binary_data.size(); + bool is_download_complete = true; + bool offset_exist = + (*message_)[strings::msg_params].keyExists(strings::offset); + + if (offset_exist) { + offset_ = (*message_)[strings::msg_params][strings::offset].asInt(); + } + + if ((*message_)[strings::msg_params].keyExists(strings::persistent_file)) { + is_persistent_file_ = + (*message_)[strings::msg_params][strings::persistent_file].asBool(); + } + if ((*message_)[strings::msg_params].keyExists(strings::system_file)) { + is_system_file = + (*message_)[strings::msg_params][strings::system_file].asBool(); + } + + std::string file_path; + + if (is_system_file) { + response_params[strings::space_available] = 0; + file_path = application_manager_.get_settings().system_files_path(); + } else { + file_path = application_manager_.get_settings().app_storage_folder(); + file_path += "/" + application->folder_name(); + + uint32_t space_available = application->GetAvailableDiskSpace(); + + if (binary_data.size() > space_available) { + response_params[strings::space_available] = + static_cast<uint32_t>(space_available); + + LOG4CXX_ERROR(logger_, "Out of memory"); + SendResponse(false, + mobile_apis::Result::OUT_OF_MEMORY, + "Out of memory", + &response_params); + return; + } + } + + if (!file_system::CreateDirectoryRecursively(file_path)) { + LOG4CXX_ERROR(logger_, "Can't create folder"); + SendResponse(false, + mobile_apis::Result::GENERIC_ERROR, + "Can't create folder.", + &response_params); + return; + } + const std::string full_path = file_path + "/" + sync_file_name_; + const size_t bin_data_size = binary_data.size(); + + if ((*message_)[strings::msg_params].keyExists(strings::crc32_check_sum)) { + LOG4CXX_TRACE(logger_, "Binary Data Size: " << bin_data_size); + const uint32_t crc_received = + (*message_)[strings::msg_params][strings::crc32_check_sum].asUInt(); + LOG4CXX_TRACE(logger_, "CRC32 SUM Received: " << crc_received); + const uint32_t crc_calculated = GetCrc32CheckSum(binary_data); + LOG4CXX_TRACE(logger_, "CRC32 SUM Calculated: " << crc_calculated); + if (crc_calculated != crc_received) { + SendResponse(false, + mobile_apis::Result::CORRUPTED_DATA, + "CRC Check on file failed. File upload has been cancelled, " + "please retry.", + &response_params); + return; + } + } + + LOG4CXX_DEBUG(logger_, + "Writing " << bin_data_size << " bytes to " << full_path + << " (current size is" + << file_system::FileSize(full_path) << ")"); + + mobile_apis::Result::eType save_result = application_manager_.SaveBinary( + binary_data, file_path, sync_file_name_, offset_); + + LOG4CXX_DEBUG(logger_, + "New size of " << full_path << " is " + << file_system::FileSize(full_path) << " bytes"); + if (!is_system_file) { + response_params[strings::space_available] = + static_cast<uint32_t>(application->GetAvailableDiskSpace()); + } + + sync_file_name_ = file_path + "/" + sync_file_name_; + switch (save_result) { + case mobile_apis::Result::SUCCESS: { + LOG4CXX_INFO(logger_, "PutFile is successful"); + if (!is_system_file) { + AppFile file(sync_file_name_, + is_persistent_file_, + is_download_complete, + file_type_); + + if (0 == offset_) { + LOG4CXX_INFO(logger_, "New file downloading"); + if (!application->AddFile(file)) { + LOG4CXX_INFO(logger_, + "Couldn't add file to application (File already Exist" + << " in application and was rewritten on FS)"); + /* It can be first part of new big file, so we need to update + information about it's downloading status and persistence */ + if (!application->UpdateFile(file)) { + LOG4CXX_ERROR(logger_, "Couldn't update file"); + /* If it is impossible to update file, application doesn't + know about existing this file */ + SendResponse(false, + mobile_apis::Result::INVALID_DATA, + "Couldn't update file", + &response_params); + return; + } + } else { + /* if file added - increment it's count + ( may be application->AddFile have to incapsulate it? ) + Any way now this method evals not only in "none"*/ + application->increment_put_file_in_none_count(); + } + } + } + + SendResponse(true, save_result, "File was downloaded", &response_params); + if (is_system_file) { + SendOnPutFileNotification(); + } + break; + } + default: + LOG4CXX_WARN(logger_, + "PutFile is unsuccessful. Result = " << save_result); + SendResponse(false, save_result, "Can't save file", &response_params); + break; + } +} + +void PutFileRequest::SendOnPutFileNotification() { + LOG4CXX_INFO(logger_, "SendOnPutFileNotification"); + smart_objects::SmartObjectSPtr notification = + new smart_objects::SmartObject(smart_objects::SmartType_Map); + + smart_objects::SmartObject& message = *notification; + message[strings::params][strings::function_id] = + hmi_apis::FunctionID::BasicCommunication_OnPutFile; + + message[strings::params][strings::message_type] = MessageType::kNotification; + message[strings::msg_params][strings::app_id] = connection_key(); + message[strings::msg_params][strings::sync_file_name] = sync_file_name_; + message[strings::msg_params][strings::offset] = offset_; + if (0 == offset_) { + message[strings::msg_params][strings::file_size] = + (*message_)[strings::msg_params][strings::length]; + } + message[strings::msg_params][strings::length] = length_; + message[strings::msg_params][strings::persistent_file] = is_persistent_file_; + message[strings::msg_params][strings::file_type] = file_type_; + application_manager_.GetRPCService().ManageHMICommand(notification); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/put_file_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/put_file_response.cc new file mode 100644 index 0000000000..50c62aef7f --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/put_file_response.cc @@ -0,0 +1,64 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/put_file_response.h" +#include "utils/file_system.h" +#include "application_manager/application_impl.h" + +namespace application_manager { + +namespace commands { + +PutFileResponse::PutFileResponse(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +PutFileResponse::~PutFileResponse() {} + +void PutFileResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + uint32_t app_id = + (*message_)[strings::params][strings::connection_key].asUInt(); + ApplicationSharedPtr app = application_manager_.application(app_id); + if (!app) { + LOG4CXX_ERROR(logger_, "Application not registered"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + SendResponse((*message_)[strings::msg_params][strings::success].asBool()); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/read_did_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/read_did_request.cc new file mode 100644 index 0000000000..c51f545e7e --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/read_did_request.cc @@ -0,0 +1,125 @@ +/* + Copyright (c) 2016, 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 <string> +#include "application_manager/commands/mobile/read_did_request.h" + +#include "application_manager/application_impl.h" +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" +#include "application_manager/message_helper.h" + +namespace application_manager { + +namespace commands { + +ReadDIDRequest::ReadDIDRequest(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +ReadDIDRequest::~ReadDIDRequest() {} + +void ReadDIDRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + uint32_t app_id = + (*message_)[strings::params][strings::connection_key].asUInt(); + + ApplicationSharedPtr app = application_manager_.application(app_id); + LOG4CXX_INFO( + logger_, + "Correlation_id :" + << (*message_)[strings::params][strings::correlation_id].asUInt()); + + if (!app) { + LOG4CXX_ERROR(logger_, "An application is not registered."); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + if (app->AreCommandLimitsExceeded( + static_cast<mobile_apis::FunctionID::eType>(function_id()), + application_manager::TLimitSource::CONFIG_FILE)) { + LOG4CXX_ERROR(logger_, "ReadDID frequency is too high."); + SendResponse(false, mobile_apis::Result::REJECTED); + return; + } + + if ((*message_)[strings::msg_params][strings::did_location].empty()) { + LOG4CXX_ERROR(logger_, "INVALID_DATA"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_params[strings::app_id] = app->app_id(); + msg_params[strings::ecu_name] = + (*message_)[strings::msg_params][strings::ecu_name]; + msg_params[strings::did_location] = + (*message_)[strings::msg_params][strings::did_location]; + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VehicleInfo); + + SendHMIRequest(hmi_apis::FunctionID::VehicleInfo_ReadDID, &msg_params, true); +} + +void ReadDIDRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::VehicleInfo_ReadDID: { + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VehicleInfo); + hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + const bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_VehicleInfo); + std::string response_info; + GetInfo(message, response_info); + + SendResponse(result, + MessageHelper::HMIToMobileResult(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/read_did_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/read_did_response.cc new file mode 100644 index 0000000000..f3cdc971aa --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/read_did_response.cc @@ -0,0 +1,55 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/read_did_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +ReadDIDResponse::ReadDIDResponse(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +ReadDIDResponse::~ReadDIDResponse() {} + +void ReadDIDResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc new file mode 100644 index 0000000000..c0e46ea4e0 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc @@ -0,0 +1,1373 @@ +/* + + Copyright (c) 2015, 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 "application_manager/commands/mobile/register_app_interface_request.h" + +#include <unistd.h> +#include <algorithm> +#include <map> +#include <string.h> + +#include <utils/make_shared.h> +#include "application_manager/application_manager.h" +#include "application_manager/policies/policy_handler_interface.h" +#include "application_manager/application_impl.h" +#include "application_manager/app_launch/app_launch_ctrl.h" +#include "application_manager/message_helper.h" +#include "application_manager/resumption/resume_ctrl.h" +#include "application_manager/policies/policy_handler.h" +#include "application_manager/helpers/application_helper.h" +#include "application_manager/rpc_service.h" +#include "config_profile/profile.h" +#include "interfaces/MOBILE_API.h" +#include "interfaces/generated_msg_version.h" +#include "utils/file_system.h" + +namespace { +namespace custom_str = utils::custom_string; + +mobile_apis::AppHMIType::eType StringToAppHMIType(const std::string& str) { + if ("DEFAULT" == str) { + return mobile_apis::AppHMIType::DEFAULT; + } else if ("COMMUNICATION" == str) { + return mobile_apis::AppHMIType::COMMUNICATION; + } else if ("MEDIA" == str) { + return mobile_apis::AppHMIType::MEDIA; + } else if ("MESSAGING" == str) { + return mobile_apis::AppHMIType::MESSAGING; + } else if ("NAVIGATION" == str) { + return mobile_apis::AppHMIType::NAVIGATION; + } else if ("INFORMATION" == str) { + return mobile_apis::AppHMIType::INFORMATION; + } else if ("SOCIAL" == str) { + return mobile_apis::AppHMIType::SOCIAL; + } else if ("BACKGROUND_PROCESS" == str) { + return mobile_apis::AppHMIType::BACKGROUND_PROCESS; + } else if ("TESTING" == str) { + return mobile_apis::AppHMIType::TESTING; + } else if ("SYSTEM" == str) { + return mobile_apis::AppHMIType::SYSTEM; + } else if ("PROJECTION" == str) { + return mobile_apis::AppHMIType::PROJECTION; +#ifdef SDL_REMOTE_CONTROL + } else if ("REMOTE_CONTROL" == str) { + return mobile_apis::AppHMIType::REMOTE_CONTROL; +#endif + } else { + return mobile_apis::AppHMIType::INVALID_ENUM; + } +} + +std::string AppHMITypeToString(mobile_apis::AppHMIType::eType type) { + const std::map<mobile_apis::AppHMIType::eType, std::string> app_hmi_type_map = + {{mobile_apis::AppHMIType::DEFAULT, "DEFAULT"}, +#ifdef SDL_REMOTE_CONTROL + {mobile_apis::AppHMIType::REMOTE_CONTROL, "REMOTE_CONTROL"}, +#endif // SDL_REMOTE_CONTROL + {mobile_apis::AppHMIType::COMMUNICATION, "COMMUNICATION"}, + {mobile_apis::AppHMIType::MEDIA, "MEDIA"}, + {mobile_apis::AppHMIType::MESSAGING, "MESSAGING"}, + {mobile_apis::AppHMIType::NAVIGATION, "NAVIGATION"}, + {mobile_apis::AppHMIType::INFORMATION, "INFORMATION"}, + {mobile_apis::AppHMIType::SOCIAL, "SOCIAL"}, + {mobile_apis::AppHMIType::BACKGROUND_PROCESS, "BACKGROUND_PROCESS"}, + {mobile_apis::AppHMIType::TESTING, "TESTING"}, + {mobile_apis::AppHMIType::SYSTEM, "SYSTEM"}, + {mobile_apis::AppHMIType::PROJECTION, "PROJECTION"}}; + + std::map<mobile_apis::AppHMIType::eType, std::string>::const_iterator iter = + app_hmi_type_map.find(type); + + return app_hmi_type_map.end() != iter ? iter->second : std::string(""); +} + +struct AppHMITypeInserter { + AppHMITypeInserter(smart_objects::SmartObject& so_array) + : index_(0), so_array_(so_array) {} + + bool operator()(const std::string& app_hmi_type) { + so_array_[index_] = StringToAppHMIType(app_hmi_type); + ++index_; + return true; + } + + private: + uint32_t index_; + smart_objects::SmartObject& so_array_; +}; + +struct CheckMissedTypes { + CheckMissedTypes(const policy::StringArray& policy_app_types, + std::string& log) + : policy_app_types_(policy_app_types), log_(log) {} + + bool operator()(const smart_objects::SmartArray::value_type& value) { + std::string app_type_str = AppHMITypeToString( + static_cast<mobile_apis::AppHMIType::eType>(value.asInt())); + if (!app_type_str.empty()) { + policy::StringArray::const_iterator it = policy_app_types_.begin(); + policy::StringArray::const_iterator it_end = policy_app_types_.end(); + for (; it != it_end; ++it) { + if (app_type_str == *it) { + return true; + } + } + } + + log_ += app_type_str; + log_ += ","; + + return true; + } + + private: + const policy::StringArray& policy_app_types_; + std::string& log_; +}; + +class SmartArrayValueExtractor { + public: + AppHmiType operator()(const smart_objects::SmartObject& so) const { + return static_cast<AppHmiType>(so.asInt()); + } +}; + +struct IsSameNickname { + IsSameNickname(const custom_str::CustomString& app_id) : app_id_(app_id) {} + bool operator()(const policy::StringArray::value_type& nickname) const { + return app_id_.CompareIgnoreCase(nickname.c_str()); + } + + private: + const custom_str::CustomString& app_id_; +}; +} + +namespace application_manager { + +namespace commands { + +RegisterAppInterfaceRequest::RegisterAppInterfaceRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) + , result_code_(mobile_apis::Result::INVALID_ENUM) {} + +RegisterAppInterfaceRequest::~RegisterAppInterfaceRequest() {} + +bool RegisterAppInterfaceRequest::Init() { + LOG4CXX_AUTO_TRACE(logger_); + return true; +} + +void RegisterAppInterfaceRequest::Run() { + using namespace helpers; + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_DEBUG(logger_, "Connection key is " << connection_key()); + + // Fix problem with SDL and HMI HTML. This problem is not actual for HMI PASA. + // Flag conditional compilation specific to customer is used in order to + // exclude hit code + // to RTC + // FIXME(EZamakhov): on shutdown - get freez + + // wait till HMI started + while (!application_manager_.IsStopping() && + !application_manager_.IsHMICooperating()) { + LOG4CXX_DEBUG(logger_, + "Waiting for the HMI... conn_key=" + << connection_key() + << ", correlation_id=" << correlation_id() + << ", default_timeout=" << default_timeout() + << ", thread=" << pthread_self()); + application_manager_.updateRequestTimeout( + connection_key(), correlation_id(), default_timeout()); + sleep(1); + // TODO(DK): timer_->StartWait(1); + } + + if (application_manager_.IsStopping()) { + LOG4CXX_WARN(logger_, "The ApplicationManager is stopping!"); + return; + } + + if (IsApplicationSwitched()) { + return; + } + + const std::string mobile_app_id = + (*message_)[strings::msg_params][strings::app_id].asString(); + + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + + if (application) { + SendResponse(false, mobile_apis::Result::APPLICATION_REGISTERED_ALREADY); + return; + } + + const smart_objects::SmartObject& msg_params = + (*message_)[strings::msg_params]; + + const std::string policy_app_id = msg_params[strings::app_id].asString(); + std::string new_policy_app_id = policy_app_id; + std::transform(policy_app_id.begin(), + policy_app_id.end(), + new_policy_app_id.begin(), + ::tolower); + (*message_)[strings::msg_params][strings::app_id] = new_policy_app_id; + + if (application_manager_.IsApplicationForbidden(connection_key(), + policy_app_id)) { + SendResponse(false, mobile_apis::Result::TOO_MANY_PENDING_REQUESTS); + return; + } + + if (IsApplicationWithSameAppIdRegistered()) { + SendResponse(false, mobile_apis::Result::DISALLOWED); + return; + } + + mobile_apis::Result::eType policy_result = CheckWithPolicyData(); + + if (Compare<mobile_apis::Result::eType, NEQ, ALL>( + policy_result, + mobile_apis::Result::SUCCESS, + mobile_apis::Result::WARNINGS)) { + SendResponse(false, policy_result); + return; + } + + mobile_apis::Result::eType coincidence_result = CheckCoincidence(); + + if (mobile_apis::Result::SUCCESS != coincidence_result) { + LOG4CXX_ERROR(logger_, "Coincidence check failed."); + if (mobile_apis::Result::DUPLICATE_NAME == coincidence_result) { + usage_statistics::AppCounter count_of_rejections_duplicate_name( + GetPolicyHandler().GetStatisticManager(), + policy_app_id, + usage_statistics::REJECTIONS_DUPLICATE_NAME); + ++count_of_rejections_duplicate_name; + } + SendResponse(false, coincidence_result); + return; + } + + if (IsWhiteSpaceExist()) { + LOG4CXX_INFO(logger_, + "Incoming register app interface has contains \t\n \\t \\n"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + application = application_manager_.RegisterApplication(message_); + + if (!application) { + LOG4CXX_ERROR(logger_, "Application hasn't been registered!"); + return; + } + // For resuming application need to restore hmi_app_id from resumeCtrl + resumption::ResumeCtrl& resumer = application_manager_.resume_controller(); + const std::string& device_mac = application->mac_address(); + + // there is side affect with 2 mobile app with the same mobile app_id + if (resumer.IsApplicationSaved(policy_app_id, device_mac)) { + application->set_hmi_application_id( + resumer.GetHMIApplicationID(policy_app_id, device_mac)); + } else { + application->set_hmi_application_id( + application_manager_.GenerateNewHMIAppID()); + } + + application->set_is_media_application( + msg_params[strings::is_media_application].asBool()); + + if (msg_params.keyExists(strings::vr_synonyms)) { + application->set_vr_synonyms(msg_params[strings::vr_synonyms]); + } + + if (msg_params.keyExists(strings::ngn_media_screen_app_name)) { + application->set_ngn_media_screen_name( + msg_params[strings::ngn_media_screen_app_name]); + } + + if (msg_params.keyExists(strings::tts_name)) { + smart_objects::SmartObject& tts_name = + (*message_)[strings::msg_params][strings::tts_name]; + mobile_apis::Result::eType verification_result = + MessageHelper::VerifyTtsFiles( + tts_name, application, application_manager_); + + if (mobile_apis::Result::FILE_NOT_FOUND == verification_result) { + LOG4CXX_WARN(logger_, + "MessageHelper::VerifyTtsFiles return " + << verification_result); + response_info_ = "One or more files needed for tts_name are not present"; + result_code_ = mobile_apis::Result::WARNINGS; + } + application->set_tts_name(tts_name); + } + + if (msg_params.keyExists(strings::app_hmi_type)) { + application->set_app_types(msg_params[strings::app_hmi_type]); + + // check app type + const smart_objects::SmartObject& app_type = + msg_params.getElement(strings::app_hmi_type); + + for (size_t i = 0; i < app_type.length(); ++i) { + if (mobile_apis::AppHMIType::NAVIGATION == + static_cast<mobile_apis::AppHMIType::eType>( + app_type.getElement(i).asUInt())) { + application->set_is_navi(true); + } + if (mobile_apis::AppHMIType::COMMUNICATION == + static_cast<mobile_apis::AppHMIType::eType>( + app_type.getElement(i).asUInt())) { + application->set_voice_communication_supported(true); + } + if (mobile_apis::AppHMIType::PROJECTION == + static_cast<mobile_apis::AppHMIType::eType>( + app_type.getElement(i).asUInt())) { + application->set_mobile_projection_enabled(true); + } + } + } + + if (msg_params.keyExists(strings::day_color_scheme)) { + application->set_day_color_scheme(msg_params[strings::day_color_scheme]); + } + + if (msg_params.keyExists(strings::night_color_scheme)) { + application->set_night_color_scheme( + msg_params[strings::night_color_scheme]); + } + + // Add device to policy table and set device info, if any + policy::DeviceParams dev_params; + if (-1 == + application_manager_.connection_handler() + .get_session_observer() + .GetDataOnDeviceID(application->device(), + &dev_params.device_name, + NULL, + &dev_params.device_mac_address, + &dev_params.device_connection_type)) { + LOG4CXX_ERROR(logger_, + "Failed to extract information for device " + << application->device()); + } + policy::DeviceInfo device_info; + device_info.AdoptDeviceType(dev_params.device_connection_type); + if (msg_params.keyExists(strings::device_info)) { + FillDeviceInfo(&device_info); + } + + GetPolicyHandler().SetDeviceInfo(device_mac, device_info); + + SendRegisterAppInterfaceResponseToMobile(ApplicationType::kNewApplication); + smart_objects::SmartObjectSPtr so = + GetLockScreenIconUrlNotification(connection_key(), application); + application_manager_.GetRPCService().ManageMobileCommand( + so, commands::Command::SOURCE_SDL); +} + +smart_objects::SmartObjectSPtr +RegisterAppInterfaceRequest::GetLockScreenIconUrlNotification( + const uint32_t connection_key, ApplicationSharedPtr app) { + DCHECK_OR_RETURN(app.get(), smart_objects::SmartObjectSPtr()); + smart_objects::SmartObjectSPtr message = + utils::MakeShared<smart_objects::SmartObject>( + smart_objects::SmartType_Map); + (*message)[strings::params][strings::function_id] = + mobile_apis::FunctionID::OnSystemRequestID; + (*message)[strings::params][strings::connection_key] = connection_key; + (*message)[strings::params][strings::message_type] = + mobile_apis::messageType::notification; + (*message)[strings::params][strings::protocol_type] = + commands::CommandImpl::mobile_protocol_type_; + (*message)[strings::params][strings::protocol_version] = + commands::CommandImpl::protocol_version_; + (*message)[strings::msg_params][strings::request_type] = + mobile_apis::RequestType::LOCK_SCREEN_ICON_URL; + (*message)[strings::msg_params][strings::url] = + GetPolicyHandler().GetLockScreenIconUrl(); + return message; +} + +void FillVRRelatedFields(smart_objects::SmartObject& response_params, + const HMICapabilities& hmi_capabilities) { + response_params[strings::language] = hmi_capabilities.active_vr_language(); + if (hmi_capabilities.vr_capabilities()) { + response_params[strings::vr_capabilities] = + *hmi_capabilities.vr_capabilities(); + } +} + +void FillVIRelatedFields(smart_objects::SmartObject& response_params, + const HMICapabilities& hmi_capabilities) { + if (hmi_capabilities.vehicle_type()) { + response_params[hmi_response::vehicle_type] = + *hmi_capabilities.vehicle_type(); + } +} + +void FillTTSRelatedFields(smart_objects::SmartObject& response_params, + const HMICapabilities& hmi_capabilities) { + response_params[strings::language] = hmi_capabilities.active_tts_language(); + if (hmi_capabilities.speech_capabilities()) { + response_params[strings::speech_capabilities] = + *hmi_capabilities.speech_capabilities(); + } + if (hmi_capabilities.prerecorded_speech()) { + response_params[strings::prerecorded_speech] = + *(hmi_capabilities.prerecorded_speech()); + } +} + +void FillUIRelatedFields(smart_objects::SmartObject& response_params, + const HMICapabilities& hmi_capabilities) { + response_params[strings::hmi_display_language] = + hmi_capabilities.active_ui_language(); + if (hmi_capabilities.display_capabilities()) { + response_params[hmi_response::display_capabilities] = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + smart_objects::SmartObject& display_caps = + response_params[hmi_response::display_capabilities]; + + if (hmi_capabilities.display_capabilities()->keyExists( + hmi_response::display_type)) { + display_caps[hmi_response::display_type] = + hmi_capabilities.display_capabilities()->getElement( + hmi_response::display_type); + } + + if (hmi_capabilities.display_capabilities()->keyExists( + hmi_response::display_name)) { + display_caps[hmi_response::display_name] = + hmi_capabilities.display_capabilities()->getElement( + hmi_response::display_name); + } + + if (hmi_capabilities.display_capabilities()->keyExists( + hmi_response::text_fields)) { + display_caps[hmi_response::text_fields] = + hmi_capabilities.display_capabilities()->getElement( + hmi_response::text_fields); + } + + if (hmi_capabilities.display_capabilities()->keyExists( + hmi_response::image_fields)) { + display_caps[hmi_response::image_fields] = + hmi_capabilities.display_capabilities()->getElement( + hmi_response::image_fields); + } + + if (hmi_capabilities.display_capabilities()->keyExists( + hmi_response::media_clock_formats)) { + display_caps[hmi_response::media_clock_formats] = + hmi_capabilities.display_capabilities()->getElement( + hmi_response::media_clock_formats); + } + + if (hmi_capabilities.display_capabilities()->keyExists( + hmi_response::templates_available)) { + display_caps[hmi_response::templates_available] = + hmi_capabilities.display_capabilities()->getElement( + hmi_response::templates_available); + } + + if (hmi_capabilities.display_capabilities()->keyExists( + hmi_response::screen_params)) { + display_caps[hmi_response::screen_params] = + hmi_capabilities.display_capabilities()->getElement( + hmi_response::screen_params); + } + + if (hmi_capabilities.display_capabilities()->keyExists( + hmi_response::num_custom_presets_available)) { + display_caps[hmi_response::num_custom_presets_available] = + hmi_capabilities.display_capabilities()->getElement( + hmi_response::num_custom_presets_available); + } + + if (hmi_capabilities.display_capabilities()->keyExists( + hmi_response::image_capabilities)) { + display_caps[hmi_response::graphic_supported] = + (hmi_capabilities.display_capabilities() + ->getElement(hmi_response::image_capabilities) + .length() > 0); + } + } + + if (hmi_capabilities.audio_pass_thru_capabilities()) { + if (smart_objects::SmartType_Array == + hmi_capabilities.audio_pass_thru_capabilities()->getType()) { + // hmi_capabilities json contains array and HMI response object + response_params[strings::audio_pass_thru_capabilities] = + *hmi_capabilities.audio_pass_thru_capabilities(); + } else { + response_params[strings::audio_pass_thru_capabilities][0] = + *hmi_capabilities.audio_pass_thru_capabilities(); + } + } + response_params[strings::hmi_capabilities] = + smart_objects::SmartObject(smart_objects::SmartType_Map); + response_params[strings::hmi_capabilities][strings::navigation] = + hmi_capabilities.navigation_supported(); + response_params[strings::hmi_capabilities][strings::phone_call] = + hmi_capabilities.phone_call_supported(); + response_params[strings::hmi_capabilities][strings::video_streaming] = + hmi_capabilities.video_streaming_supported(); + response_params[strings::hmi_capabilities][strings::remote_control] = + hmi_capabilities.rc_supported(); +} + +void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile( + ApplicationType app_type) { + LOG4CXX_AUTO_TRACE(logger_); + smart_objects::SmartObject response_params(smart_objects::SmartType_Map); + + mobile_apis::Result::eType result_code = mobile_apis::Result::SUCCESS; + + const HMICapabilities& hmi_capabilities = + application_manager_.hmi_capabilities(); + + const uint32_t key = connection_key(); + ApplicationSharedPtr application = application_manager_.application(key); + + resumption::ResumeCtrl& resumer = application_manager_.resume_controller(); + + if (!application) { + LOG4CXX_ERROR(logger_, + "There is no application for such connection key" << key); + LOG4CXX_DEBUG(logger_, "Need to start resume data persistent timer"); + resumer.OnAppRegistrationEnd(); + return; + } + + response_params[strings::sync_msg_version][strings::major_version] = + major_version; // From generated file interfaces/generated_msg_version.h + response_params[strings::sync_msg_version][strings::minor_version] = + minor_version; // From generated file interfaces/generated_msg_version.h + response_params[strings::sync_msg_version][strings::patch_version] = + patch_version; // From generated file interfaces/generated_msg_version.h + + const smart_objects::SmartObject& msg_params = + (*message_)[strings::msg_params]; + + if (msg_params[strings::language_desired].asInt() != + hmi_capabilities.active_vr_language() || + msg_params[strings::hmi_display_language_desired].asInt() != + hmi_capabilities.active_ui_language()) { + LOG4CXX_WARN(logger_, + "Wrong language on registering application " + << application->name().c_str()); + + LOG4CXX_ERROR( + logger_, + "VR language desired code is " + << msg_params[strings::language_desired].asInt() + << " , active VR language code is " + << hmi_capabilities.active_vr_language() << ", UI language code is " + << msg_params[strings::hmi_display_language_desired].asInt() + << " , active UI language code is " + << hmi_capabilities.active_ui_language()); + + result_code = mobile_apis::Result::WRONG_LANGUAGE; + } + + if (HmiInterfaces::STATE_NOT_AVAILABLE != + application_manager_.hmi_interfaces().GetInterfaceState( + HmiInterfaces::HMI_INTERFACE_TTS)) { + FillTTSRelatedFields(response_params, hmi_capabilities); + } + + if (HmiInterfaces::STATE_NOT_AVAILABLE != + application_manager_.hmi_interfaces().GetInterfaceState( + HmiInterfaces::HMI_INTERFACE_VR)) { + FillVRRelatedFields(response_params, hmi_capabilities); + } + + if (HmiInterfaces::STATE_NOT_AVAILABLE != + application_manager_.hmi_interfaces().GetInterfaceState( + HmiInterfaces::HMI_INTERFACE_UI)) { + FillUIRelatedFields(response_params, hmi_capabilities); + } + + if (HmiInterfaces::STATE_NOT_AVAILABLE != + application_manager_.hmi_interfaces().GetInterfaceState( + HmiInterfaces::HMI_INTERFACE_VehicleInfo)) { + FillVIRelatedFields(response_params, hmi_capabilities); + } + + if (hmi_capabilities.button_capabilities()) { + response_params[hmi_response::button_capabilities] = + *hmi_capabilities.button_capabilities(); + } + + if (hmi_capabilities.soft_button_capabilities()) { + response_params[hmi_response::soft_button_capabilities] = + *hmi_capabilities.soft_button_capabilities(); + } + + if (hmi_capabilities.preset_bank_capabilities()) { + response_params[hmi_response::preset_bank_capabilities] = + *hmi_capabilities.preset_bank_capabilities(); + } + + if (hmi_capabilities.hmi_zone_capabilities()) { + if (smart_objects::SmartType_Array == + hmi_capabilities.hmi_zone_capabilities()->getType()) { + // hmi_capabilities json contains array and HMI response object + response_params[hmi_response::hmi_zone_capabilities] = + *hmi_capabilities.hmi_zone_capabilities(); + } else { + response_params[hmi_response::hmi_zone_capabilities][0] = + *hmi_capabilities.hmi_zone_capabilities(); + } + } + + if (hmi_capabilities.pcm_stream_capabilities()) { + response_params[strings::pcm_stream_capabilities] = + *hmi_capabilities.pcm_stream_capabilities(); + } + + const std::vector<uint32_t>& diag_modes = + application_manager_.get_settings().supported_diag_modes(); + if (!diag_modes.empty()) { + std::vector<uint32_t>::const_iterator it = diag_modes.begin(); + uint32_t index = 0; + for (; it != diag_modes.end(); ++it) { + response_params[strings::supported_diag_modes][index] = *it; + ++index; + } + } + + response_params[strings::sdl_version] = + application_manager_.get_settings().sdl_version(); + const std::string ccpu_version = + application_manager_.hmi_capabilities().ccpu_version(); + if (!ccpu_version.empty()) { + response_params[strings::system_software_version] = ccpu_version; + } + + if (ApplicationType::kSwitchedApplicationWrongHashId == app_type) { + LOG4CXX_DEBUG(logger_, + "Application has been switched from another transport, " + "but doesn't have correct hashID."); + + application_manager::DeleteApplicationData(application, + application_manager_); + + SendResponse( + true, mobile_apis::Result::RESUME_FAILED, NULL, &response_params); + return; + } + + if (ApplicationType::kSwitchedApplicationHashOk == app_type) { + LOG4CXX_DEBUG(logger_, + "Application has been switched from another transport " + "and has correct hashID."); + SendResponse(true, mobile_apis::Result::SUCCESS, NULL, &response_params); + return; + } + + bool resumption = + (*message_)[strings::msg_params].keyExists(strings::hash_id); + + bool need_restore_vr = resumption; + + std::string hash_id; + std::string add_info; + if (resumption) { + hash_id = (*message_)[strings::msg_params][strings::hash_id].asString(); + if (!resumer.CheckApplicationHash(application, hash_id)) { + LOG4CXX_WARN(logger_, + "Hash from RAI does not match to saved resume data."); + result_code = mobile_apis::Result::RESUME_FAILED; + add_info = "Hash from RAI does not match to saved resume data."; + need_restore_vr = false; + } else if (!resumer.CheckPersistenceFilesForResumption(application)) { + LOG4CXX_WARN(logger_, "Persistent data is missing."); + result_code = mobile_apis::Result::RESUME_FAILED; + add_info = "Persistent data is missing."; + need_restore_vr = false; + } else { + add_info = "Resume succeeded."; + } + } + if ((mobile_apis::Result::SUCCESS == result_code) && + (mobile_apis::Result::INVALID_ENUM != result_code_)) { + add_info += response_info_; + result_code = result_code_; + } + + // in case application exist in resumption we need to send resumeVrgrammars + if (false == resumption) { + resumption = resumer.IsApplicationSaved(application->policy_app_id(), + application->mac_address()); + } + + AppHmiTypes hmi_types; + if ((*message_)[strings::msg_params].keyExists(strings::app_hmi_type)) { + smart_objects::SmartArray* hmi_types_ptr = + (*message_)[strings::msg_params][strings::app_hmi_type].asArray(); + DCHECK_OR_RETURN_VOID(hmi_types_ptr); + SmartArrayValueExtractor extractor; + if (hmi_types_ptr && 0 < hmi_types_ptr->size()) { + std::transform(hmi_types_ptr->begin(), + hmi_types_ptr->end(), + std::back_inserter(hmi_types), + extractor); + } + } + policy::StatusNotifier notify_upd_manager = GetPolicyHandler().AddApplication( + application->policy_app_id(), hmi_types); + + response_params[strings::icon_resumed] = + file_system::FileExists(application->app_icon_path()); + + SendResponse(true, result_code, add_info.c_str(), &response_params); + SendOnAppRegisteredNotificationToHMI( + *(application.get()), resumption, need_restore_vr); +#ifdef SDL_REMOTE_CONTROL + if (msg_params.keyExists(strings::app_hmi_type)) { + GetPolicyHandler().SetDefaultHmiTypes(application->policy_app_id(), + &(msg_params[strings::app_hmi_type])); + } +#endif // SDL_REMOTE_CONTROL + + // Default HMI level should be set before any permissions validation, since it + // relies on HMI level. + application_manager_.OnApplicationRegistered(application); + (*notify_upd_manager)(); + + // Start PTU after successfull registration + // Sends OnPermissionChange notification to mobile right after RAI response + // and HMI level set-up + GetPolicyHandler().OnAppRegisteredOnMobile(application->policy_app_id()); + + if (result_code != mobile_apis::Result::RESUME_FAILED) { + resumer.StartResumption(application, hash_id); + } else { + resumer.StartResumptionOnlyHMILevel(application); + } + + // By default app subscribed to CUSTOM_BUTTON + SendSubscribeCustomButtonNotification(); + SendChangeRegistrationOnHMI(application); +} + +DEPRECATED void +RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile() { + SendRegisterAppInterfaceResponseToMobile(ApplicationType::kNewApplication); +} + +void RegisterAppInterfaceRequest::SendChangeRegistration( + const hmi_apis::FunctionID::eType function_id, + const int32_t language, + const uint32_t app_id) { + using helpers::Compare; + using helpers::EQ; + using helpers::ONE; + const HmiInterfaces& hmi_interfaces = application_manager_.hmi_interfaces(); + const HmiInterfaces::InterfaceID interface = + hmi_interfaces.GetInterfaceFromFunction(function_id); + if (hmi_interfaces.GetInterfaceState(interface) != + HmiInterfaces::STATE_NOT_AVAILABLE) { + smart_objects::SmartObject msg_params(smart_objects::SmartType_Map); + msg_params[strings::language] = language; + msg_params[strings::app_id] = app_id; + SendHMIRequest(function_id, &msg_params); + } else { + LOG4CXX_DEBUG(logger_, "Interface " << interface << "is not avaliable"); + } +} + +void RegisterAppInterfaceRequest::SendChangeRegistrationOnHMI( + ApplicationConstSharedPtr app) { + using namespace hmi_apis::FunctionID; + DCHECK_OR_RETURN_VOID(app); + DCHECK_OR_RETURN_VOID(mobile_apis::Language::INVALID_ENUM != app->language()); + SendChangeRegistration(VR_ChangeRegistration, app->language(), app->app_id()); + SendChangeRegistration( + TTS_ChangeRegistration, app->language(), app->app_id()); + SendChangeRegistration(UI_ChangeRegistration, app->language(), app->app_id()); +} + +void RegisterAppInterfaceRequest::SendOnAppRegisteredNotificationToHMI( + const Application& application_impl, + bool resumption, + bool need_restore_vr) { + using namespace smart_objects; + SmartObjectSPtr notification = utils::MakeShared<SmartObject>(SmartType_Map); + if (!notification) { + LOG4CXX_ERROR(logger_, "Failed to create smart object"); + return; + } + + (*notification)[strings::params] = SmartObject(SmartType_Map); + smart_objects::SmartObject& params = (*notification)[strings::params]; + params[strings::function_id] = static_cast<int32_t>( + hmi_apis::FunctionID::BasicCommunication_OnAppRegistered); + params[strings::message_type] = static_cast<int32_t>(kNotification); + params[strings::protocol_version] = commands::CommandImpl::protocol_version_; + params[strings::protocol_type] = commands::CommandImpl::hmi_protocol_type_; + + (*notification)[strings::msg_params] = SmartObject(SmartType_Map); + smart_objects::SmartObject& msg_params = (*notification)[strings::msg_params]; + // Due to current requirements in case when we're in resumption mode + // we have to always send resumeVRGrammar field. + if (resumption) { + msg_params[strings::resume_vr_grammars] = need_restore_vr; + } + + if (application_impl.vr_synonyms()) { + msg_params[strings::vr_synonyms] = *(application_impl.vr_synonyms()); + } + + if (application_impl.tts_name()) { + msg_params[strings::tts_name] = *(application_impl.tts_name()); + } + + const std::string policy_app_id = application_impl.policy_app_id(); + std::string priority; + GetPolicyHandler().GetPriority(policy_app_id, &priority); + + if (!priority.empty()) { + msg_params[strings::priority] = MessageHelper::GetPriorityCode(priority); + } + + msg_params[strings::msg_params] = SmartObject(SmartType_Map); + smart_objects::SmartObject& application = msg_params[strings::application]; + application[strings::app_name] = application_impl.name(); + application[strings::app_id] = application_impl.app_id(); + application[hmi_response::policy_app_id] = policy_app_id; + if (file_system::FileExists(application_impl.app_icon_path())) { + application[strings::icon] = application_impl.app_icon_path(); + } + + const smart_objects::SmartObject* ngn_media_screen_name = + application_impl.ngn_media_screen_name(); + if (ngn_media_screen_name) { + application[strings::ngn_media_screen_app_name] = *ngn_media_screen_name; + } + + application[strings::hmi_display_language_desired] = + static_cast<int32_t>(application_impl.ui_language()); + + application[strings::is_media_application] = + application_impl.is_media_application(); + + const smart_objects::SmartObject* app_type = application_impl.app_types(); + if (app_type) { + application[strings::app_type] = *app_type; + } + + const policy::RequestType::State app_request_types_state = + GetPolicyHandler().GetAppRequestTypeState(policy_app_id); + if (policy::RequestType::State::AVAILABLE == app_request_types_state) { + const auto request_types = + GetPolicyHandler().GetAppRequestTypes(policy_app_id); + application[strings::request_type] = SmartObject(SmartType_Array); + smart_objects::SmartObject& request_types_array = + application[strings::request_type]; + + size_t index = 0; + for (auto it : request_types) { + request_types_array[index] = it; + ++index; + } + } else if (policy::RequestType::State::EMPTY == app_request_types_state) { + application[strings::request_type] = SmartObject(SmartType_Array); + } + + const policy::RequestSubType::State app_request_subtypes_state = + GetPolicyHandler().GetAppRequestSubTypeState(policy_app_id); + if (policy::RequestSubType::State::AVAILABLE == app_request_subtypes_state) { + const auto request_subtypes = + GetPolicyHandler().GetAppRequestSubTypes(policy_app_id); + application[strings::request_subtype] = SmartObject(SmartType_Array); + smart_objects::SmartObject& request_subtypes_array = + application[strings::request_subtype]; + + size_t index = 0; + for (auto it : request_subtypes) { + request_subtypes_array[index] = it; + ++index; + } + } else if (policy::RequestSubType::State::EMPTY == + app_request_subtypes_state) { + application[strings::request_subtype] = SmartObject(SmartType_Array); + } + + application[strings::device_info] = SmartObject(SmartType_Map); + smart_objects::SmartObject& device_info = application[strings::device_info]; + const protocol_handler::SessionObserver& session_observer = + application_manager_.connection_handler().get_session_observer(); + std::string device_name; + std::string mac_address; + std::string transport_type; + const connection_handler::DeviceHandle handle = application_impl.device(); + if (-1 == + session_observer.GetDataOnDeviceID( + handle, &device_name, NULL, &mac_address, &transport_type)) { + LOG4CXX_ERROR(logger_, + "Failed to extract information for device " << handle); + } + + device_info[strings::name] = device_name; + device_info[strings::id] = mac_address; + + const policy::DeviceConsent device_consent = + GetPolicyHandler().GetUserConsentForDevice(mac_address); + device_info[strings::isSDLAllowed] = + policy::DeviceConsent::kDeviceAllowed == device_consent; + + device_info[strings::transport_type] = + application_manager_.GetDeviceTransportType(transport_type); + + const smart_objects::SmartObject* day_color_scheme = + application_impl.day_color_scheme(); + if (day_color_scheme) { + application[strings::day_color_scheme] = *day_color_scheme; + } + + const smart_objects::SmartObject* night_color_scheme = + application_impl.night_color_scheme(); + if (night_color_scheme) { + application[strings::night_color_scheme] = *night_color_scheme; + } + + DCHECK(application_manager_.GetRPCService().ManageHMICommand(notification)); +} + +mobile_apis::Result::eType RegisterAppInterfaceRequest::CheckCoincidence() { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& msg_params = + (*message_)[strings::msg_params]; + + ApplicationSet accessor = application_manager_.applications().GetData(); + + ApplicationSetConstIt it = accessor.begin(); + const custom_str::CustomString& app_name = + msg_params[strings::app_name].asCustomString(); + + for (; accessor.end() != it; ++it) { + // name check + const custom_str::CustomString& cur_name = (*it)->name(); + if (app_name.CompareIgnoreCase(cur_name)) { + LOG4CXX_ERROR(logger_, "Application name is known already."); + return mobile_apis::Result::DUPLICATE_NAME; + } + + const smart_objects::SmartObject* vr = (*it)->vr_synonyms(); + const std::vector<smart_objects::SmartObject>* curr_vr = NULL; + if (NULL != vr) { + curr_vr = vr->asArray(); + CoincidencePredicateVR v(app_name); + + if (0 != std::count_if(curr_vr->begin(), curr_vr->end(), v)) { + LOG4CXX_ERROR(logger_, "Application name is known already."); + return mobile_apis::Result::DUPLICATE_NAME; + } + } + + // vr check + if (msg_params.keyExists(strings::vr_synonyms)) { + const std::vector<smart_objects::SmartObject>* new_vr = + msg_params[strings::vr_synonyms].asArray(); + + CoincidencePredicateVR v(cur_name); + if (0 != std::count_if(new_vr->begin(), new_vr->end(), v)) { + LOG4CXX_ERROR(logger_, "vr_synonyms duplicated with app_name ."); + return mobile_apis::Result::DUPLICATE_NAME; + } + } // end vr check + + } // application for end + + return mobile_apis::Result::SUCCESS; +} // method end + +mobile_apis::Result::eType RegisterAppInterfaceRequest::CheckWithPolicyData() { + LOG4CXX_AUTO_TRACE(logger_); + // TODO(AOleynik): Check is necessary to allow register application in case + // of disabled policy + // Remove this check, when HMI will support policy + if (!GetPolicyHandler().PolicyEnabled()) { + return mobile_apis::Result::WARNINGS; + } + + smart_objects::SmartObject& message = *message_; + policy::StringArray app_nicknames; + policy::StringArray app_hmi_types; + + const std::string mobile_app_id = + message[strings::msg_params][strings::app_id].asString(); + const bool init_result = GetPolicyHandler().GetInitialAppData( + mobile_app_id, &app_nicknames, &app_hmi_types); + + if (!init_result) { + LOG4CXX_ERROR(logger_, "Error during initial application data check."); + return mobile_apis::Result::INVALID_DATA; + } + + if (!app_nicknames.empty()) { + IsSameNickname compare( + message[strings::msg_params][strings::app_name].asCustomString()); + policy::StringArray::const_iterator it = + std::find_if(app_nicknames.begin(), app_nicknames.end(), compare); + if (app_nicknames.end() == it) { + LOG4CXX_WARN(logger_, + "Application name was not found in nicknames list."); + // App should be unregistered, if its name is not present in nicknames + // list + usage_statistics::AppCounter count_of_rejections_nickname_mismatch( + GetPolicyHandler().GetStatisticManager(), + mobile_app_id, + usage_statistics::REJECTIONS_NICKNAME_MISMATCH); + ++count_of_rejections_nickname_mismatch; + return mobile_apis::Result::DISALLOWED; + } + } + + mobile_apis::Result::eType result = mobile_apis::Result::SUCCESS; + + // If AppHMIType is not included in policy - allow any type + if (!app_hmi_types.empty()) { + if (message[strings::msg_params].keyExists(strings::app_hmi_type)) { + // If AppHmiTypes are partially same, the system should allow those listed + // in the policy table and send warning info on missed values + smart_objects::SmartArray app_types = + *(message[strings::msg_params][strings::app_hmi_type].asArray()); + + std::string log; + CheckMissedTypes checker(app_hmi_types, log); + std::for_each(app_types.begin(), app_types.end(), checker); + if (!log.empty()) { + response_info_ = + "Following AppHmiTypes are not present in policy " + "table:" + + log; + result_code_ = mobile_apis::Result::WARNINGS; + } + } + // Replace AppHmiTypes in request with values allowed by policy table + message[strings::msg_params][strings::app_hmi_type] = + smart_objects::SmartObject(smart_objects::SmartType_Array); + + smart_objects::SmartObject& app_hmi_type = + message[strings::msg_params][strings::app_hmi_type]; + + AppHMITypeInserter inserter(app_hmi_type); + std::for_each(app_hmi_types.begin(), app_hmi_types.end(), inserter); + } + + return result; +} + +void RegisterAppInterfaceRequest::FillDeviceInfo( + policy::DeviceInfo* device_info) { + const std::string hardware = "hardware"; + const std::string firmware_rev = "firmwareRev"; + const std::string os = "os"; + const std::string os_ver = "osVersion"; + const std::string carrier = "carrier"; + const std::string max_number_rfcom_ports = "maxNumberRFCOMMPorts"; + + const smart_objects::SmartObject& msg_params = + (*message_)[strings::msg_params]; + + const smart_objects::SmartObject& device_info_so = + msg_params[strings::device_info]; + + if (device_info_so.keyExists(hardware)) { + device_info->hardware = + msg_params[strings::device_info][hardware].asString(); + } + if (device_info_so.keyExists(firmware_rev)) { + device_info->firmware_rev = + msg_params[strings::device_info][firmware_rev].asString(); + } + if (device_info_so.keyExists(os)) { + device_info->os = device_info_so[os].asString(); + } + if (device_info_so.keyExists(os_ver)) { + device_info->os_ver = device_info_so[os_ver].asString(); + } + if (device_info_so.keyExists(carrier)) { + device_info->carrier = device_info_so[carrier].asString(); + } + if (device_info_so.keyExists(max_number_rfcom_ports)) { + device_info->max_number_rfcom_ports = + device_info_so[max_number_rfcom_ports].asInt(); + } +} + +bool RegisterAppInterfaceRequest::IsApplicationWithSameAppIdRegistered() { + LOG4CXX_AUTO_TRACE(logger_); + + const custom_string::CustomString mobile_app_id = + (*message_)[strings::msg_params][strings::app_id].asCustomString(); + + const ApplicationSet& applications = + application_manager_.applications().GetData(); + + ApplicationSetConstIt it = applications.begin(); + ApplicationSetConstIt it_end = applications.end(); + + for (; it != it_end; ++it) { + if (mobile_app_id.CompareIgnoreCase((*it)->policy_app_id().c_str())) { + return true; + } + } + + return false; +} + +bool RegisterAppInterfaceRequest::IsWhiteSpaceExist() { + LOG4CXX_AUTO_TRACE(logger_); + const char* str = NULL; + + str = (*message_)[strings::msg_params][strings::app_name].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid app_name syntax check failed"); + return true; + } + + if ((*message_)[strings::msg_params].keyExists(strings::tts_name)) { + const smart_objects::SmartArray* tn_array = + (*message_)[strings::msg_params][strings::tts_name].asArray(); + + smart_objects::SmartArray::const_iterator it_tn = tn_array->begin(); + smart_objects::SmartArray::const_iterator it_tn_end = tn_array->end(); + + for (; it_tn != it_tn_end; ++it_tn) { + str = (*it_tn)[strings::text].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid tts_name syntax check failed"); + return true; + } + } + } + + if ((*message_)[strings::msg_params].keyExists( + strings::ngn_media_screen_app_name)) { + str = (*message_)[strings::msg_params][strings::ngn_media_screen_app_name] + .asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid ngn_media_screen_app_name syntax check failed"); + return true; + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::vr_synonyms)) { + const smart_objects::SmartArray* vs_array = + (*message_)[strings::msg_params][strings::vr_synonyms].asArray(); + + smart_objects::SmartArray::const_iterator it_vs = vs_array->begin(); + smart_objects::SmartArray::const_iterator it_vs_end = vs_array->end(); + + for (; it_vs != it_vs_end; ++it_vs) { + str = (*it_vs).asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid vr_synonyms syntax check failed"); + return true; + } + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::hash_id)) { + str = (*message_)[strings::msg_params][strings::hash_id].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid hash_id syntax check failed"); + return true; + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::device_info)) { + if ((*message_)[strings::msg_params][strings::device_info].keyExists( + strings::hardware)) { + str = (*message_)[strings::msg_params][strings::device_info] + [strings::hardware].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid device_info hardware syntax check failed"); + return true; + } + } + + if ((*message_)[strings::msg_params][strings::device_info].keyExists( + strings::firmware_rev)) { + str = (*message_)[strings::msg_params][strings::device_info] + [strings::firmware_rev].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid device_info firmware_rev syntax check failed"); + return true; + } + } + + if ((*message_)[strings::msg_params][strings::device_info].keyExists( + strings::os)) { + str = (*message_)[strings::msg_params][strings::device_info][strings::os] + .asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid device_info os syntax check failed"); + return true; + } + } + + if ((*message_)[strings::msg_params][strings::device_info].keyExists( + strings::os_version)) { + str = (*message_)[strings::msg_params][strings::device_info] + [strings::os_version].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid device_info os_version syntax check failed"); + return true; + } + } + + if ((*message_)[strings::msg_params][strings::device_info].keyExists( + strings::carrier)) { + str = (*message_)[strings::msg_params][strings::device_info] + [strings::carrier].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid device_info carrier syntax check failed"); + return true; + } + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::app_id)) { + str = (*message_)[strings::msg_params][strings::app_id].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid app_id syntax check failed"); + return true; + } + } + + return false; +} + +void RegisterAppInterfaceRequest::CheckResponseVehicleTypeParam( + smart_objects::SmartObject& vehicle_type, + const std::string& param, + const std::string& backup_value) { + using namespace hmi_response; + if (!vehicle_type.keyExists(param) || vehicle_type[param].empty()) { + if (!backup_value.empty()) { + LOG4CXX_DEBUG(logger_, + param << " is missing." + "Will be replaced with policy table value."); + vehicle_type[param] = backup_value; + } else { + vehicle_type.erase(param); + } + } +} + +void RegisterAppInterfaceRequest::SendSubscribeCustomButtonNotification() { + using namespace smart_objects; + using namespace hmi_apis; + + SmartObject msg_params = SmartObject(SmartType_Map); + msg_params[strings::app_id] = connection_key(); + msg_params[strings::name] = Common_ButtonName::CUSTOM_BUTTON; + msg_params[strings::is_suscribed] = true; + CreateHMINotification(FunctionID::Buttons_OnButtonSubscription, msg_params); +} + +bool RegisterAppInterfaceRequest::IsApplicationSwitched() { + const smart_objects::SmartObject& msg_params = + (*message_)[strings::msg_params]; + + const std::string& policy_app_id = msg_params[strings::app_id].asString(); + + LOG4CXX_DEBUG(logger_, "Looking for application id " << policy_app_id); + + auto app = application_manager_.application_by_policy_id(policy_app_id); + + if (!app) { + LOG4CXX_DEBUG(logger_, + "Application with policy id " << policy_app_id + << " is not found."); + return false; + } + + LOG4CXX_DEBUG(logger_, + "Application with policy id " << policy_app_id << " is found."); + if (!application_manager_.IsAppInReconnectMode(policy_app_id)) { + LOG4CXX_DEBUG(logger_, + "Policy id " << policy_app_id + << " is not found in reconnection list."); + SendResponse(false, mobile_apis::Result::APPLICATION_REGISTERED_ALREADY); + return false; + } + + LOG4CXX_DEBUG(logger_, "Application is found in reconnection list."); + + auto app_type = ApplicationType::kSwitchedApplicationWrongHashId; + if ((*message_)[strings::msg_params].keyExists(strings::hash_id)) { + const auto hash_id = + (*message_)[strings::msg_params][strings::hash_id].asString(); + + auto& resume_ctrl = application_manager_.resume_controller(); + if (resume_ctrl.CheckApplicationHash(app, hash_id)) { + app_type = ApplicationType::kSwitchedApplicationHashOk; + } + } + + application_manager_.ProcessReconnection(app, connection_key()); + SendRegisterAppInterfaceResponseToMobile(app_type); + + application_manager_.SendHMIStatusNotification(app); + + application_manager_.OnApplicationSwitched(app); + + return true; +} + +policy::PolicyHandlerInterface& +RegisterAppInterfaceRequest::GetPolicyHandler() { + return application_manager_.GetPolicyHandler(); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_response.cc new file mode 100644 index 0000000000..3e94e652d4 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_response.cc @@ -0,0 +1,99 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/register_app_interface_response.h" +#include "interfaces/MOBILE_API.h" +#include "application_manager/application_manager.h" +#include "application_manager/policies/policy_handler_interface.h" +#include "connection_handler/connection_handler.h" +#include "application_manager/policies/policy_handler_interface.h" + +namespace application_manager { + +namespace commands { + +void RegisterAppInterfaceResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + mobile_apis::Result::eType result_code = mobile_apis::Result::SUCCESS; + bool success = (*message_)[strings::msg_params][strings::success].asBool(); + bool last_message = !success; + // Do not close connection in case of APPLICATION_NOT_REGISTERED despite it is + // an error + if (!success && + (*message_)[strings::msg_params].keyExists(strings::result_code)) { + result_code = static_cast<mobile_apis::Result::eType>( + (*message_)[strings::msg_params][strings::result_code].asInt()); + if (result_code == mobile_apis::Result::APPLICATION_REGISTERED_ALREADY) { + last_message = false; + } + } + + SendResponse(success, result_code, last_message); + + if (mobile_apis::Result::SUCCESS != result_code) { + return; + } + + // Add registered application to the policy db right after response sent to + // mobile to be able to check all other API according to app permissions + application_manager::ApplicationSharedPtr application = + application_manager_.application(connection_key()); + if (!application) { + LOG4CXX_ERROR(logger_, + "Application with connection key " << connection_key() + << " is not registered."); + return; + } + + SetHeartBeatTimeout(connection_key(), application->policy_app_id()); +} + +void RegisterAppInterfaceResponse::SetHeartBeatTimeout( + uint32_t connection_key, const std::string& mobile_app_id) { + LOG4CXX_AUTO_TRACE(logger_); + policy::PolicyHandlerInterface& policy_handler = + application_manager_.GetPolicyHandler(); + if (policy_handler.PolicyEnabled()) { + const uint32_t timeout = policy_handler.HeartBeatTimeout(mobile_app_id); + if (timeout > 0) { + application_manager_.connection_handler().SetHeartBeatTimeout( + connection_key, timeout); + } + } else { + LOG4CXX_INFO(logger_, "Policy is turn off"); + } +} + +} // namespace commands +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/reset_global_properties_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/reset_global_properties_request.cc new file mode 100644 index 0000000000..a7c2db0e65 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/reset_global_properties_request.cc @@ -0,0 +1,327 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/reset_global_properties_request.h" + +#include "application_manager/application_impl.h" +#include "application_manager/message_helper.h" + +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" + +namespace application_manager { + +namespace commands { + +ResetGlobalPropertiesRequest::ResetGlobalPropertiesRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) + , ui_result_(hmi_apis::Common_Result::INVALID_ENUM) + , tts_result_(hmi_apis::Common_Result::INVALID_ENUM) {} + +ResetGlobalPropertiesRequest::~ResetGlobalPropertiesRequest() {} + +void ResetGlobalPropertiesRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + uint32_t app_id = + (*message_)[strings::params][strings::connection_key].asUInt(); + ApplicationSharedPtr app = application_manager_.application(app_id); + + if (!app) { + LOG4CXX_ERROR(logger_, "No application associated with session key"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + size_t obj_length = + (*message_)[strings::msg_params][strings::properties].length(); + // if application waits for sending ttsGlobalProperties need to remove this + // application from tts_global_properties_app_list_ + LOG4CXX_INFO(logger_, "RemoveAppFromTTSGlobalPropertiesList"); + application_manager_.RemoveAppFromTTSGlobalPropertiesList(app_id); + + bool helpt_promt = false; + bool timeout_prompt = false; + bool vr_help_title_items = false; + bool menu_name = false; + bool menu_icon = false; + bool is_key_board_properties = false; + int number_of_reset_vr = 0; + mobile_apis::GlobalProperty::eType global_property = + mobile_apis::GlobalProperty::INVALID_ENUM; + + for (size_t i = 0; i < obj_length; ++i) { + global_property = static_cast<mobile_apis::GlobalProperty::eType>( + (*message_)[strings::msg_params][strings::properties][i].asInt()); + + if (mobile_apis::GlobalProperty::HELPPROMPT == global_property) { + helpt_promt = ResetHelpPromt(app); + } else if (mobile_apis::GlobalProperty::TIMEOUTPROMPT == global_property) { + timeout_prompt = ResetTimeoutPromt(app); + } else if (((mobile_apis::GlobalProperty::VRHELPTITLE == global_property) || + (mobile_apis::GlobalProperty::VRHELPITEMS == + global_property)) && + (0 == number_of_reset_vr)) { + ++number_of_reset_vr; + vr_help_title_items = ResetVrHelpTitleItems(app); + } else if (mobile_apis::GlobalProperty::MENUNAME == global_property) { + menu_name = true; + } else if (mobile_apis::GlobalProperty::MENUICON == global_property) { + menu_icon = true; + } else if (mobile_apis::GlobalProperty::KEYBOARDPROPERTIES == + global_property) { + is_key_board_properties = true; + } + } + + if (vr_help_title_items || menu_name || menu_icon || + is_key_board_properties) { + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + } + + if (timeout_prompt || helpt_promt) { + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_TTS); + } + + app->set_reset_global_properties_active(true); + + if (vr_help_title_items || menu_name || menu_icon || + is_key_board_properties) { + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + if (vr_help_title_items) { + smart_objects::SmartObjectSPtr vr_help = + MessageHelper::CreateAppVrHelp(app); + if (!vr_help) { + return; + } + msg_params = *vr_help; + } + if (menu_name) { + msg_params[hmi_request::menu_title] = ""; + app->set_menu_title(msg_params[hmi_request::menu_title]); + } + // TODO(DT): clarify the sending parameter menuIcon + // if (menu_icon) { + //} + if (is_key_board_properties) { + smart_objects::SmartObject key_board_properties = + smart_objects::SmartObject(smart_objects::SmartType_Map); + key_board_properties[strings::language] = + static_cast<int32_t>(hmi_apis::Common_Language::EN_US); + key_board_properties[hmi_request::keyboard_layout] = + static_cast<int32_t>(hmi_apis::Common_KeyboardLayout::QWERTY); + + // Look for APPLINK-4432 for details. + /*smart_objects::SmartObject limited_character_list = + smart_objects::SmartObject( + smart_objects::SmartType_Array); + limited_character_list[0] = ""; + key_board_properties[hmi_request::limited_character_list] = + limited_character_list;*/ + + key_board_properties[hmi_request::auto_complete_text] = ""; + msg_params[hmi_request::keyboard_properties] = key_board_properties; + } + + msg_params[strings::app_id] = app->app_id(); + SendHMIRequest( + hmi_apis::FunctionID::UI_SetGlobalProperties, &msg_params, true); + } + + if (timeout_prompt || helpt_promt) { + // create ui request + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + if (helpt_promt) { + msg_params[strings::help_prompt] = (*app->help_prompt()); + } + + if (timeout_prompt) { + msg_params[strings::timeout_prompt] = (*app->timeout_prompt()); + } + + msg_params[strings::app_id] = app->app_id(); + + SendHMIRequest( + hmi_apis::FunctionID::TTS_SetGlobalProperties, &msg_params, true); + } +} + +bool ResetGlobalPropertiesRequest::ResetHelpPromt( + application_manager::ApplicationSharedPtr app) { + if (!app) { + LOG4CXX_ERROR(logger_, "Null pointer"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return false; + } + smart_objects::SmartObject so_help_prompt = + smart_objects::SmartObject(smart_objects::SmartType_Array); + app->set_help_prompt(so_help_prompt); + return true; +} + +bool ResetGlobalPropertiesRequest::ResetTimeoutPromt( + application_manager::ApplicationSharedPtr const app) { + if (!app) { + LOG4CXX_ERROR(logger_, "Null pointer"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return false; + } + + const std::vector<std::string>& time_out_promt = + application_manager_.get_settings().time_out_promt(); + + smart_objects::SmartObject so_time_out_promt = + smart_objects::SmartObject(smart_objects::SmartType_Array); + + for (uint32_t i = 0; i < time_out_promt.size(); ++i) { + smart_objects::SmartObject timeoutPrompt = + smart_objects::SmartObject(smart_objects::SmartType_Map); + timeoutPrompt[strings::text] = time_out_promt[i]; + timeoutPrompt[strings::type] = hmi_apis::Common_SpeechCapabilities::SC_TEXT; + so_time_out_promt[i] = timeoutPrompt; + } + + app->set_timeout_prompt(so_time_out_promt); + + return true; +} + +bool ResetGlobalPropertiesRequest::ResetVrHelpTitleItems( + application_manager::ApplicationSharedPtr const app) { + if (!app) { + LOG4CXX_ERROR(logger_, "Null pointer"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return false; + } + app->reset_vr_help_title(); + app->reset_vr_help(); + + return true; +} + +void ResetGlobalPropertiesRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::UI_SetGlobalProperties: { + LOG4CXX_INFO(logger_, "Received UI_SetGlobalProperties event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + ui_result_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + GetInfo(message, ui_response_info_); + break; + } + case hmi_apis::FunctionID::TTS_SetGlobalProperties: { + LOG4CXX_INFO(logger_, "Received TTS_SetGlobalProperties event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_TTS); + tts_result_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + GetInfo(message, tts_response_info_); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } + + if (IsPendingResponseExist()) { + LOG4CXX_DEBUG(logger_, "Waiting for remaining responses"); + return; + } + + mobile_apis::Result::eType result_code = mobile_apis::Result::INVALID_ENUM; + std::string response_info; + const bool result = PrepareResponseParameters(result_code, response_info); + + SendResponse(result, + static_cast<mobile_apis::Result::eType>(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); +} + +bool ResetGlobalPropertiesRequest::Init() { + hash_update_mode_ = HashUpdateMode::kDoHashUpdate; + return true; +} + +bool ResetGlobalPropertiesRequest::PrepareResponseParameters( + mobile_apis::Result::eType& out_result_code, + std::string& out_response_info) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace helpers; + + bool result = false; + ResponseInfo ui_properties_info( + ui_result_, HmiInterfaces::HMI_INTERFACE_UI, application_manager_); + ResponseInfo tts_properties_info( + tts_result_, HmiInterfaces::HMI_INTERFACE_TTS, application_manager_); + + HmiInterfaces::InterfaceState tts_interface_state = + application_manager_.hmi_interfaces().GetInterfaceState( + HmiInterfaces::HMI_INTERFACE_TTS); + + if (hmi_apis::Common_Result::SUCCESS == ui_result_ && + hmi_apis::Common_Result::UNSUPPORTED_RESOURCE == tts_result_ && + HmiInterfaces::STATE_AVAILABLE == tts_interface_state) { + result = true; + out_result_code = mobile_apis::Result::WARNINGS; + out_response_info = "Unsupported phoneme type sent in a prompt"; + } else { + result = + PrepareResultForMobileResponse(ui_properties_info, tts_properties_info); + out_result_code = + PrepareResultCodeForResponse(ui_properties_info, tts_properties_info); + out_response_info = MergeInfos(tts_properties_info, + tts_response_info_, + ui_properties_info, + ui_response_info_); + } + + return result; +} + +bool ResetGlobalPropertiesRequest::IsPendingResponseExist() { + return IsInterfaceAwaited(HmiInterfaces::HMI_INTERFACE_TTS) || + IsInterfaceAwaited(HmiInterfaces::HMI_INTERFACE_UI); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/reset_global_properties_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/reset_global_properties_response.cc new file mode 100644 index 0000000000..abee868769 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/reset_global_properties_response.cc @@ -0,0 +1,55 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/reset_global_properties_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +ResetGlobalPropertiesResponse::ResetGlobalPropertiesResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +ResetGlobalPropertiesResponse::~ResetGlobalPropertiesResponse() {} + +void ResetGlobalPropertiesResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/scrollable_message_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/scrollable_message_request.cc new file mode 100644 index 0000000000..b0b2d5f464 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/scrollable_message_request.cc @@ -0,0 +1,154 @@ +/* + + Copyright (c) 2013, 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 <string.h> +#include "application_manager/commands/mobile/scrollable_message_request.h" + +#include "application_manager/application_impl.h" +#include "application_manager/policies/policy_handler.h" +#include "application_manager/message_helper.h" +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" +#include "utils/helpers.h" + +namespace application_manager { + +namespace commands { + +ScrollableMessageRequest::ScrollableMessageRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) { + subscribe_on_event(hmi_apis::FunctionID::UI_OnResetTimeout); +} + +ScrollableMessageRequest::~ScrollableMessageRequest() {} + +bool ScrollableMessageRequest::Init() { + /* Timeout in milliseconds. + If omitted a standard value of 10000 milliseconds is used.*/ + if ((*message_)[strings::msg_params].keyExists(strings::timeout)) { + default_timeout_ = + (*message_)[strings::msg_params][strings::timeout].asUInt(); + } else { + const int32_t def_value = 30000; + default_timeout_ = def_value; + } + + return true; +} + +void ScrollableMessageRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "Application is not registered"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + // ProcessSoftButtons checks strings on the contents incorrect character + + mobile_apis::Result::eType processing_result = + MessageHelper::ProcessSoftButtons((*message_)[strings::msg_params], + app, + application_manager_.GetPolicyHandler(), + application_manager_); + + if (mobile_apis::Result::SUCCESS != processing_result) { + LOG4CXX_ERROR(logger_, "Wrong soft buttons parameters!"); + SendResponse(false, processing_result); + return; + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + msg_params[hmi_request::message_text][hmi_request::field_name] = + static_cast<int32_t>( + hmi_apis::Common_TextFieldName::scrollableMessageBody); + msg_params[hmi_request::message_text][hmi_request::field_text] = + (*message_)[strings::msg_params][strings::scroll_message_body]; + msg_params[strings::app_id] = app->app_id(); + msg_params[strings::timeout] = default_timeout_; + + if ((*message_)[strings::msg_params].keyExists(strings::soft_buttons)) { + msg_params[strings::soft_buttons] = + (*message_)[strings::msg_params][strings::soft_buttons]; + MessageHelper::SubscribeApplicationToSoftButton( + (*message_)[strings::msg_params], app, function_id()); + } + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + SendHMIRequest(hmi_apis::FunctionID::UI_ScrollableMessage, &msg_params, true); +} + +void ScrollableMessageRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::UI_OnResetTimeout: { + LOG4CXX_INFO(logger_, "Received UI_OnResetTimeout event"); + application_manager_.updateRequestTimeout( + connection_key(), correlation_id(), default_timeout()); + break; + } + case hmi_apis::FunctionID::UI_ScrollableMessage: { + LOG4CXX_INFO(logger_, "Received UI_ScrollableMessage event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + + hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + std::string response_info; + GetInfo(message, response_info); + + const bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_UI); + + SendResponse(result, + MessageHelper::HMIToMobileResult(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + break; + } + } +} + +} // namespace commands +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/scrollable_message_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/scrollable_message_response.cc new file mode 100644 index 0000000000..d6c786b1ee --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/scrollable_message_response.cc @@ -0,0 +1,63 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/scrollable_message_response.h" +#include "application_manager/rpc_service.h" +#include "interfaces/HMI_API.h" +#include "interfaces/MOBILE_API.h" + +namespace application_manager { + +namespace commands { + +ScrollableMessageResponse::ScrollableMessageResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +void ScrollableMessageResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + mobile_apis::Result::eType result_code = + static_cast<mobile_apis::Result::eType>( + (*message_)[strings::msg_params][strings::result_code].asInt()); + ApplicationSharedPtr application = application_manager_.application( + (*message_)[strings::params][strings::connection_key].asInt()); + if ((mobile_apis::Result::REJECTED != result_code) && application) { + application->UnsubscribeFromSoftButtons( + (*message_)[strings::params][strings::function_id].asInt()); + } + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/send_haptic_data_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/send_haptic_data_request.cc new file mode 100644 index 0000000000..569eba6c02 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/send_haptic_data_request.cc @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2017 Xevo Inc. + * 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 Xevo Inc. 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 "application_manager/commands/mobile/send_haptic_data_request.h" +#include "interfaces/MOBILE_API.h" + +namespace application_manager { + +namespace commands { + +namespace custom_str = utils::custom_string; + +SendHapticDataRequest::SendHapticDataRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +SendHapticDataRequest::~SendHapticDataRequest() {} + +void SendHapticDataRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + smart_objects::SmartObject& msg_params = (*message_)[strings::msg_params]; + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "Application is not registered"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + if (app->is_navi() || app->mobile_projection_enabled()) { + SendHMIRequest(hmi_apis::FunctionID::UI_SendHapticData, &msg_params, true); + } else { + SendResponse(false, + mobile_apis::Result::DISALLOWED, + "Application is not of type Navigation or Mobile Projection"); + } +} + +void SendHapticDataRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace helpers; + + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::UI_SendHapticData: { + mobile_apis::Result::eType result_code = + GetMobileResultCode(static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asUInt())); + + const bool result = Compare<mobile_api::Result::eType, EQ, ONE>( + result_code, + mobile_api::Result::SUCCESS, + mobile_api::Result::WARNINGS); + + SendResponse(result, result_code, NULL, &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/send_haptic_data_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/send_haptic_data_response.cc new file mode 100644 index 0000000000..9860f89065 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/send_haptic_data_response.cc @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017 Xevo Inc. + * 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 Xevo Inc. 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 "application_manager/commands/mobile/send_haptic_data_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +SendHapticDataResponse::SendHapticDataResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +SendHapticDataResponse::~SendHapticDataResponse() {} + +void SendHapticDataResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/send_location_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/send_location_request.cc new file mode 100644 index 0000000000..54664a8771 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/send_location_request.cc @@ -0,0 +1,276 @@ +/* + + Copyright (c) 2013, 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 <algorithm> +#include "application_manager/commands/mobile/send_location_request.h" +#include "application_manager/message_helper.h" +#include "utils/custom_string.h" + +namespace application_manager { + +namespace commands { + +SendLocationRequest::SendLocationRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +SendLocationRequest::~SendLocationRequest() {} + +void SendLocationRequest::Run() { + using namespace hmi_apis; + using smart_objects::SmartObject; + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, + "An application with connection key " + << connection_key() << " is not registered."); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + smart_objects::SmartObject& msg_params = (*message_)[strings::msg_params]; + if (msg_params.keyExists(strings::delivery_mode)) { + const RPCParams& allowed_params = parameters_permissions().allowed_params; + + if (helpers::in_range(allowed_params, strings::delivery_mode)) { + msg_params.erase(strings::delivery_mode); + } + } + + std::vector<Common_TextFieldName::eType> fields_to_check; + if (msg_params.keyExists(strings::location_name)) { + fields_to_check.push_back(Common_TextFieldName::locationName); + } + if (msg_params.keyExists(strings::location_description)) { + fields_to_check.push_back(Common_TextFieldName::locationDescription); + } + if (msg_params.keyExists(strings::address_lines)) { + fields_to_check.push_back(Common_TextFieldName::addressLines); + } + if (msg_params.keyExists(strings::phone_number)) { + fields_to_check.push_back(Common_TextFieldName::phoneNumber); + } + + if (!CheckHMICapabilities(fields_to_check)) { + SendResponse(false, mobile_apis::Result::UNSUPPORTED_RESOURCE); + return; + } + + if (IsWhiteSpaceExist()) { + LOG4CXX_ERROR(logger_, "Strings contain invalid characters"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + if (msg_params.keyExists(strings::address)) { + const utils::custom_string::CustomString& address = + msg_params[strings::address].asCustomString(); + if (address.empty()) { + msg_params.erase(strings::address); + } + } + + if (!CheckFieldsCompatibility()) { + LOG4CXX_ERROR(logger_, "CheckFieldsCompatibility failed"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + if (msg_params.keyExists(strings::location_image)) { + mobile_apis::Result::eType verification_result = + mobile_apis::Result::SUCCESS; + verification_result = MessageHelper::VerifyImage( + (*message_)[strings::msg_params][strings::location_image], + app, + application_manager_); + if (mobile_apis::Result::SUCCESS != verification_result) { + LOG4CXX_ERROR(logger_, "VerifyImage INVALID_DATA!"); + SendResponse(false, verification_result); + return; + } + } + + SmartObject request_msg_params = SmartObject(smart_objects::SmartType_Map); + request_msg_params = msg_params; + request_msg_params[strings::app_id] = app->hmi_app_id(); + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_Navigation); + SendHMIRequest( + hmi_apis::FunctionID::Navigation_SendLocation, &request_msg_params, true); +} + +void SendLocationRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace hmi_apis; + const smart_objects::SmartObject& message = event.smart_object(); + if (hmi_apis::FunctionID::Navigation_SendLocation == event.id()) { + LOG4CXX_INFO(logger_, "Received Navigation_SendLocation event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_Navigation); + const Common_Result::eType result_code = static_cast<Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + std::string response_info; + GetInfo(message, response_info); + const bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_Navigation); + SendResponse(result, + MessageHelper::HMIToMobileResult(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::params])); + return; + } + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); +} + +bool SendLocationRequest::CheckFieldsCompatibility() { + const smart_objects::SmartObject& msg_params = + (*message_)[strings::msg_params]; + MessageHelper::PrintSmartObject(msg_params); + const bool longitude_degrees_exist = + msg_params.keyExists(strings::longitude_degrees); + const bool latitude_degrees_exist = + msg_params.keyExists(strings::latitude_degrees); + const bool address_exist = msg_params.keyExists(strings::address); + + if (latitude_degrees_exist ^ longitude_degrees_exist) { + LOG4CXX_DEBUG(logger_, + "latitude and longitude should be provided only in pair"); + return false; + } + + if (!address_exist && !longitude_degrees_exist && !latitude_degrees_exist) { + LOG4CXX_DEBUG(logger_, + "address or latitude/longtitude should should be provided"); + return false; + } + return true; +} +void insert_if_contains( + const smart_objects::SmartObject& msg_params, + const std::string& param_key, + std::vector<utils::custom_string::CustomString>& output_vector) { + if (msg_params.keyExists(param_key)) { + output_vector.push_back(msg_params[param_key].asCustomString()); + } +} + +bool SendLocationRequest::IsWhiteSpaceExist() { + LOG4CXX_AUTO_TRACE(logger_); + std::vector<utils::custom_string::CustomString> fields_to_check; + const smart_objects::SmartObject& msg_params = + (*message_)[strings::msg_params]; + insert_if_contains(msg_params, strings::location_name, fields_to_check); + insert_if_contains( + msg_params, strings::location_description, fields_to_check); + insert_if_contains(msg_params, strings::phone_number, fields_to_check); + + if (msg_params.keyExists(strings::address_lines)) { + const smart_objects::SmartArray* al_array = + msg_params[strings::address_lines].asArray(); + smart_objects::SmartArray::const_iterator it_al = al_array->begin(); + smart_objects::SmartArray::const_iterator it_al_end = al_array->end(); + for (; it_al != it_al_end; ++it_al) { + const utils::custom_string::CustomString& val = (*it_al).asCustomString(); + fields_to_check.push_back(val); + } + } + + if (msg_params.keyExists(strings::address)) { + const smart_objects::SmartObject& address_so = msg_params[strings::address]; + insert_if_contains(address_so, strings::country_name, fields_to_check); + insert_if_contains(address_so, strings::country_code, fields_to_check); + insert_if_contains(address_so, strings::postal_code, fields_to_check); + insert_if_contains( + address_so, strings::administrative_area, fields_to_check); + insert_if_contains(address_so, strings::locality, fields_to_check); + insert_if_contains(address_so, strings::sub_locality, fields_to_check); + insert_if_contains(address_so, strings::thoroughfare, fields_to_check); + insert_if_contains(address_so, strings::sub_thoroughfare, fields_to_check); + } + + std::vector<utils::custom_string::CustomString>::iterator it = + fields_to_check.begin(); + for (; it != fields_to_check.end(); ++it) { + const std::string& str = it->AsMBString(); + if (!CheckSyntax(str, false)) { + LOG4CXX_ERROR(logger_, + "string '" << str << "'' contains invalid characters"); + return true; + } + } + return false; +} + +bool SendLocationRequest::CheckHMICapabilities( + std::vector<hmi_apis::Common_TextFieldName::eType>& fields_names) { + using namespace smart_objects; + using namespace hmi_apis; + if (fields_names.empty()) { + return true; + } + + const HMICapabilities& hmi_capabilities = + application_manager_.hmi_capabilities(); + if (!hmi_capabilities.is_ui_cooperating()) { + LOG4CXX_ERROR(logger_, "UI is not supported."); + return false; + } + + if (hmi_capabilities.display_capabilities()) { + const SmartObject disp_cap = (*hmi_capabilities.display_capabilities()); + const SmartObject& text_fields = + disp_cap.getElement(hmi_response::text_fields); + const size_t len = text_fields.length(); + for (size_t i = 0; i < len; ++i) { + const SmartObject& text_field = text_fields[i]; + const Common_TextFieldName::eType filed_name = + static_cast<Common_TextFieldName::eType>( + text_field.getElement(strings::name).asInt()); + const std::vector<Common_TextFieldName::eType>::iterator it = + std::find(fields_names.begin(), fields_names.end(), filed_name); + if (it != fields_names.end()) { + fields_names.erase(it); + } + } + } + + if (!fields_names.empty()) { + LOG4CXX_ERROR(logger_, "Some fields are not supported by capabilities"); + return false; + } + return true; +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/send_location_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/send_location_response.cc new file mode 100644 index 0000000000..3968e566e3 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/send_location_response.cc @@ -0,0 +1,57 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/send_location_response.h" +#include "application_manager/rpc_service.h" +#include "application_manager/application_impl.h" +#include "interfaces/HMI_API.h" + +namespace application_manager { + +namespace commands { + +SendLocationResponse::SendLocationResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +SendLocationResponse::~SendLocationResponse() {} + +void SendLocationResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_app_icon_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_app_icon_request.cc new file mode 100644 index 0000000000..a100bbb5fb --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_app_icon_request.cc @@ -0,0 +1,288 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/set_app_icon_request.h" + +#include <algorithm> + +#include "application_manager/message_helper.h" +#include "application_manager/application_impl.h" +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" +#include "utils/file_system.h" +#include "utils/helpers.h" + +namespace application_manager { + +namespace commands { + +SetAppIconRequest::SetAppIconRequest(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) + , is_icons_saving_enabled_(false) { + const std::string path = + application_manager_.get_settings().app_icons_folder(); + is_icons_saving_enabled_ = file_system::IsWritingAllowed(path) && + file_system::IsReadingAllowed(path); +} + +SetAppIconRequest::~SetAppIconRequest() {} + +void SetAppIconRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "Application is not registered"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + const std::string& sync_file_name = + (*message_)[strings::msg_params][strings::sync_file_name].asString(); + + if (!file_system::IsFileNameValid(sync_file_name)) { + const std::string err_msg = "Sync file name contains forbidden symbols."; + LOG4CXX_ERROR(logger_, err_msg); + SendResponse(false, mobile_apis::Result::INVALID_DATA, err_msg.c_str()); + return; + } + + std::string full_file_path = + application_manager_.get_settings().app_storage_folder() + "/"; + full_file_path += app->folder_name(); + full_file_path += "/"; + full_file_path += sync_file_name; + + if (!file_system::FileExists(full_file_path)) { + LOG4CXX_ERROR(logger_, "No such file " << full_file_path); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::app_id] = app->app_id(); + msg_params[strings::sync_file_name] = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + // Panasonic requres unchanged path value without encoded special characters + const std::string full_file_path_for_hmi = + file_system::ConvertPathForURL(full_file_path); + + msg_params[strings::sync_file_name][strings::value] = full_file_path_for_hmi; + + // TODO(VS): research why is image_type hardcoded + msg_params[strings::sync_file_name][strings::image_type] = + static_cast<int32_t>(SetAppIconRequest::ImageType::DYNAMIC); + + // for further use in on_event function + (*message_)[strings::msg_params][strings::sync_file_name] = + msg_params[strings::sync_file_name]; + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + SendHMIRequest(hmi_apis::FunctionID::UI_SetAppIcon, &msg_params, true); +} + +void SetAppIconRequest::CopyToIconStorage( + const std::string& path_to_file) const { + if (!(application_manager_.protocol_handler() + .get_settings() + .max_supported_protocol_version() >= + protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_4)) { + LOG4CXX_WARN(logger_, + "Icon copying skipped, since protocol ver. 4 is not enabled."); + return; + } + + std::vector<uint8_t> file_content; + if (!file_system::ReadBinaryFile(path_to_file, file_content)) { + LOG4CXX_ERROR(logger_, "Can't read icon file: " << path_to_file); + return; + } + + const std::string icon_storage = + application_manager_.get_settings().app_icons_folder(); + const uint64_t storage_max_size = static_cast<uint64_t>( + application_manager_.get_settings().app_icons_folder_max_size()); + const uint64_t file_size = file_system::FileSize(path_to_file); + + if (storage_max_size < file_size) { + LOG4CXX_ERROR(logger_, + "Icon size (" << file_size << ") is bigger, than " + " icons storage maximum size (" + << storage_max_size << ")." + "Copying skipped."); + return; + } + + const uint64_t storage_size = + static_cast<uint64_t>(file_system::DirectorySize(icon_storage)); + if (storage_max_size < (file_size + storage_size)) { + const uint32_t icons_amount = + application_manager_.get_settings().app_icons_amount_to_remove(); + + if (!icons_amount) { + LOG4CXX_DEBUG(logger_, + "No icons will be deleted, since amount icons to remove " + "is zero. Icon saving skipped."); + return; + } + + while (!IsEnoughSpaceForIcon(file_size)) { + RemoveOldestIcons(icon_storage, icons_amount); + } + } + ApplicationConstSharedPtr app = + application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR( + logger_, + "Can't get application for connection key: " << connection_key()); + return; + } + + const std::string icon_path = icon_storage + "/" + app->policy_app_id(); + if (!file_system::CreateFile(icon_path)) { + LOG4CXX_ERROR(logger_, "Can't create icon: " << icon_path); + return; + } + + if (!file_system::Write(icon_path, file_content)) { + LOG4CXX_ERROR(logger_, "Can't write icon: " << icon_path); + return; + } + + LOG4CXX_DEBUG(logger_, + "Icon was successfully copied from :" << path_to_file << " to " + << icon_path); + + return; +} + +void SetAppIconRequest::RemoveOldestIcons(const std::string& storage, + const uint32_t icons_amount) const { + const std::vector<std::string> icons_list = file_system::ListFiles(storage); + std::map<uint64_t, std::string> icon_modification_time; + std::vector<std::string>::const_iterator it = icons_list.begin(); + for (; it != icons_list.end(); ++it) { + const std::string file_name = *it; + const std::string file_path = storage + "/" + file_name; + if (!file_system::FileExists(file_path)) { + continue; + } + const uint64_t time = file_system::GetFileModificationTime(file_path); + icon_modification_time[time] = file_name; + } + + for (size_t counter = 0; counter < icons_amount; ++counter) { + if (!icon_modification_time.size()) { + LOG4CXX_ERROR(logger_, "No more icons left for deletion."); + return; + } + const std::string file_name = icon_modification_time.begin()->second; + const std::string file_path = storage + "/" + file_name; + if (!file_system::DeleteFile(file_path)) { + LOG4CXX_DEBUG(logger_, "Error while deleting icon " << file_path); + } + icon_modification_time.erase(icon_modification_time.begin()); + LOG4CXX_DEBUG(logger_, + "Old icon " << file_path << " was deleted successfully."); + } +} + +bool SetAppIconRequest::IsEnoughSpaceForIcon(const uint64_t icon_size) const { + const std::string icon_storage = + application_manager_.get_settings().app_icons_folder(); + const uint64_t storage_max_size = static_cast<uint64_t>( + application_manager_.get_settings().app_icons_folder_max_size()); + const uint64_t storage_size = + static_cast<uint64_t>(file_system::DirectorySize(icon_storage)); + return storage_max_size >= (icon_size + storage_size); +} + +void SetAppIconRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::UI_SetAppIcon: { + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + const bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_UI); + std::string response_info; + GetInfo(message, response_info); + if (result) { + ApplicationSharedPtr app = + application_manager_.application(connection_key()); + + if (!message_.valid() || !app.valid()) { + LOG4CXX_ERROR(logger_, "NULL pointer."); + return; + } + + const std::string& path = + (*message_)[strings::msg_params][strings::sync_file_name] + [strings::value].asString(); + + if (is_icons_saving_enabled_) { + CopyToIconStorage(path); + } + + app->set_app_icon_path(path); + + LOG4CXX_INFO(logger_, + "Icon path was set to '" << app->app_icon_path() << "'"); + } + + SendResponse(result, + MessageHelper::HMIToMobileResult(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_app_icon_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_app_icon_response.cc new file mode 100644 index 0000000000..57e4f5600d --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_app_icon_response.cc @@ -0,0 +1,55 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/set_app_icon_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +SetAppIconResponse::SetAppIconResponse(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +SetAppIconResponse::~SetAppIconResponse() {} + +void SetAppIconResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_display_layout_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_display_layout_request.cc new file mode 100644 index 0000000000..ed60ca4928 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_display_layout_request.cc @@ -0,0 +1,165 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/set_display_layout_request.h" + +#include "application_manager/message_helper.h" +#include "application_manager/application_impl.h" + +namespace application_manager { + +namespace commands { + +SetDisplayLayoutRequest::SetDisplayLayoutRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +SetDisplayLayoutRequest::~SetDisplayLayoutRequest() {} + +void SetDisplayLayoutRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "Application is not registered"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + const smart_objects::SmartObject& msg_params = + (*message_)[strings::msg_params]; + + std::string old_layout = app->display_layout(); + std::string new_layout = ""; + + if (msg_params.keyExists(strings::display_layout)) { + new_layout = msg_params[strings::display_layout].asString(); + } + + if (new_layout != old_layout && + !new_layout.empty()) { // Template switched, allow any color change + LOG4CXX_DEBUG(logger_, + "SetDisplayLayoutRequest New Layout: " << new_layout); + app->set_display_layout(new_layout); + } else { + LOG4CXX_DEBUG(logger_, "SetDisplayLayoutRequest No Layout Change"); + // Template layout is the same as previous layout + // Reject message if colors are set + if (msg_params.keyExists(strings::day_color_scheme) && + app->day_color_scheme() != NULL && + !(msg_params[strings::day_color_scheme] == + *(app->day_color_scheme()))) { + // Color scheme param exists and has been previously set, do not allow + // color change + LOG4CXX_DEBUG(logger_, "Reject Day Color Scheme Change"); + SendResponse(false, mobile_apis::Result::REJECTED); + return; + } + + if (msg_params.keyExists(strings::night_color_scheme) && + app->night_color_scheme() != NULL && + !(msg_params[strings::night_color_scheme] == + *(app->night_color_scheme()))) { + // Color scheme param exists and has been previously set, do not allow + // color change + LOG4CXX_DEBUG(logger_, "Reject Night Color Scheme Change"); + SendResponse(false, mobile_apis::Result::REJECTED); + return; + } + } + + if (msg_params.keyExists(strings::day_color_scheme)) { + LOG4CXX_DEBUG(logger_, "Allow Day Color Scheme Change"); + app->set_day_color_scheme(msg_params[strings::day_color_scheme]); + } + + if (msg_params.keyExists(strings::night_color_scheme)) { + LOG4CXX_DEBUG(logger_, "Allow Night Color Scheme Change"); + app->set_night_color_scheme(msg_params[strings::night_color_scheme]); + } + + (*message_)[strings::msg_params][strings::app_id] = app->app_id(); + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + SendHMIRequest(hmi_apis::FunctionID::UI_SetDisplayLayout, + &((*message_)[strings::msg_params]), + true); +} + +void SetDisplayLayoutRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + + const smart_objects::SmartObject& message = event.smart_object(); + switch (event.id()) { + case hmi_apis::FunctionID::UI_SetDisplayLayout: { + LOG4CXX_INFO(logger_, "Received UI_SetDisplayLayout event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + const bool response_success = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_UI); + std::string info; + GetInfo(message, info); + smart_objects::SmartObject msg_params = message[strings::msg_params]; + if (response_success) { + HMICapabilities& hmi_capabilities = + application_manager_.hmi_capabilities(); + + // in case templates_available is empty copy from hmi capabilities + if (msg_params.keyExists(hmi_response::display_capabilities)) { + if (0 == + msg_params[hmi_response::display_capabilities] + [hmi_response::templates_available].length()) { + msg_params[hmi_response::display_capabilities] + [hmi_response::templates_available] = + hmi_capabilities.display_capabilities()->getElement( + hmi_response::templates_available); + } + } + } + SendResponse(response_success, + MessageHelper::HMIToMobileResult(result_code), + info.empty() ? NULL : info.c_str(), + &msg_params); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_display_layout_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_display_layout_response.cc new file mode 100644 index 0000000000..fe5c73dd7d --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_display_layout_response.cc @@ -0,0 +1,56 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/set_display_layout_response.h" +#include "application_manager/application_impl.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +SetDisplayLayoutResponse::SetDisplayLayoutResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +SetDisplayLayoutResponse::~SetDisplayLayoutResponse() {} + +void SetDisplayLayoutResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_global_properties_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_global_properties_request.cc new file mode 100644 index 0000000000..621aa90447 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_global_properties_request.cc @@ -0,0 +1,601 @@ +/* + Copyright (c) 2015, 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 <string.h> +#include <numeric> +#include <algorithm> +#include "application_manager/commands/mobile/set_global_properties_request.h" + +#include "application_manager/message_helper.h" +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" +#include "utils/helpers.h" + +namespace application_manager { + +namespace commands { + +SetGlobalPropertiesRequest::SetGlobalPropertiesRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) + , is_ui_send_(false) + , is_tts_send_(false) + , is_ui_received_(false) + , is_tts_received_(false) + , ui_result_(hmi_apis::Common_Result::INVALID_ENUM) + , tts_result_(hmi_apis::Common_Result::INVALID_ENUM) {} + +SetGlobalPropertiesRequest::~SetGlobalPropertiesRequest() {} + +void SetGlobalPropertiesRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + const smart_objects::SmartObject& msg_params = + (*message_)[strings::msg_params]; + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, + "No application associated with connection key " + << connection_key()); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + if (!ValidateConditionalMandatoryParameters(msg_params)) { + SendResponse(false, + mobile_apis::Result::INVALID_DATA, + "There are no parameters present in request."); + return; + } + + mobile_apis::Result::eType verification_result = mobile_apis::Result::SUCCESS; + + if ((*message_)[strings::msg_params].keyExists(strings::menu_icon)) { + verification_result = MessageHelper::VerifyImage( + (*message_)[strings::msg_params][strings::menu_icon], + app, + application_manager_); + if (mobile_apis::Result::SUCCESS != verification_result) { + LOG4CXX_ERROR( + logger_, "MessageHelper::VerifyImage return " << verification_result); + SendResponse(false, verification_result); + return; + } + } + // Check for image file(s) in vrHelpItem + if ((*message_)[strings::msg_params].keyExists(strings::vr_help)) { + if (mobile_apis::Result::SUCCESS != + MessageHelper::VerifyImageVrHelpItems( + (*message_)[strings::msg_params][strings::vr_help], + app, + application_manager_)) { + LOG4CXX_ERROR(logger_, "MessageHelper::VerifyImage return INVALID_DATA!"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + } + + if (IsWhiteSpaceExist()) { + LOG4CXX_ERROR(logger_, "White spaces found"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + // if application waits for sending ttsGlobalProperties need to remove this + // application from tts_global_properties_app_list_ + application_manager_.RemoveAppFromTTSGlobalPropertiesList(connection_key()); + bool is_help_prompt_present = msg_params.keyExists(strings::help_prompt); + bool is_timeout_prompt_present = + msg_params.keyExists(strings::timeout_prompt); + bool is_vr_help_title_present = msg_params.keyExists(strings::vr_help_title); + bool is_vr_help_present = msg_params.keyExists(strings::vr_help); + + // check VR params + if (is_vr_help_title_present ^ is_vr_help_present) { + LOG4CXX_ERROR(logger_, + "Reject because of vr_help or vr_help_title only provided"); + SendResponse(false, mobile_apis::Result::REJECTED); + return; + } + + /* Need to set flags before sending request to HMI + * for correct processing this flags in method on_event */ + if (is_help_prompt_present || is_timeout_prompt_present) { + is_tts_send_ = true; + } + if (is_vr_help_title_present && is_vr_help_present) { + LOG4CXX_DEBUG(logger_, "VRHelp params presents"); + + if (!CheckVrHelpItemsOrder(msg_params[strings::vr_help])) { + LOG4CXX_ERROR(logger_, + "VR Help Items contains nonsequential positions" + << " (e.g. [1,2,4]) or not started from 1"); + SendResponse(false, mobile_apis::Result::REJECTED); + return; + } + + smart_objects::SmartObject params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + PrepareUIRequestVRHelpData(app, msg_params, params); + PrepareUIRequestMenuAndKeyboardData(app, msg_params, params); + + params[strings::app_id] = app->app_id(); + SendUIRequest(params, true); + } else { + LOG4CXX_DEBUG(logger_, "VRHelp params does not present"); + DCHECK_OR_RETURN_VOID(!is_vr_help_title_present && !is_vr_help_present); + + smart_objects::SmartObject params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + if (ValidateVRHelpTitle(app->vr_help_title())) { + LOG4CXX_DEBUG(logger_, "App already contains VRHelp data"); + } else { + if (!PrepareUIRequestDefaultVRHelpData(app, params)) { + LOG4CXX_ERROR(logger_, "default VRHElp data could not be generated"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + } + PrepareUIRequestMenuAndKeyboardData(app, msg_params, params); + + // Preparing data + if (params.empty()) { + LOG4CXX_DEBUG(logger_, "No UI info provided"); + } else { + params[strings::app_id] = app->app_id(); + SendUIRequest(params, true); + } + } + + // check TTS params + if (is_help_prompt_present || is_timeout_prompt_present) { + LOG4CXX_DEBUG(logger_, "TTS params presents"); + smart_objects::SmartObject params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + std::vector<std::string> invalid_params; + if (is_help_prompt_present) { + smart_objects::SmartObject& help_prompt = + (*message_)[strings::msg_params][strings::help_prompt]; + mobile_apis::Result::eType verification_result = + MessageHelper::VerifyTtsFiles(help_prompt, app, application_manager_); + + if (mobile_apis::Result::FILE_NOT_FOUND == verification_result) { + LOG4CXX_ERROR(logger_, + "MessageHelper::VerifyTtsFiles return " + << verification_result); + invalid_params.push_back("help_prompt"); + } else { + app->set_help_prompt(help_prompt); + params[strings::help_prompt] = (*app->help_prompt()); + } + } + + if (is_timeout_prompt_present) { + smart_objects::SmartObject& timeout_prompt = + (*message_)[strings::msg_params][strings::timeout_prompt]; + mobile_apis::Result::eType verification_result = + MessageHelper::VerifyTtsFiles( + timeout_prompt, app, application_manager_); + + if (mobile_apis::Result::FILE_NOT_FOUND == verification_result) { + LOG4CXX_ERROR(logger_, + "MessageHelper::VerifyTtsFiles return " + << verification_result); + invalid_params.push_back("timeout_prompt"); + } else { + app->set_timeout_prompt(timeout_prompt); + params[strings::timeout_prompt] = (*app->timeout_prompt()); + } + } + + if (!invalid_params.empty()) { + std::string params_list = std::accumulate( + std::begin(invalid_params), + std::end(invalid_params), + std::string(""), + [](std::string& first, std::string& second) { + return first.empty() ? second : first + ", " + second; + }); + const std::string info = + "One or more files needed for " + params_list + " are not present"; + SendResponse(false, mobile_apis::Result::FILE_NOT_FOUND, info.c_str()); + return; + } + + params[strings::app_id] = app->app_id(); + SendTTSRequest(params, true); + } +} + +bool SetGlobalPropertiesRequest::CheckVrHelpItemsOrder( + const smart_objects::SmartObject& vr_help) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN(vr_help.getType() == smart_objects::SmartType_Array, false); + const size_t vr_help_length = vr_help.length(); + DCHECK_OR_RETURN(vr_help_length > 0, false); + + for (size_t j = 0; j < vr_help_length; ++j) { + const size_t position = + vr_help.getElement(j).getElement(strings::position).asUInt(); + // Elements shall start from 1 and increment one by one + if (position != (j + 1)) { + LOG4CXX_ERROR(logger_, + "VR help items order is wrong" + << " at " << j << ", position value:" << position); + return false; + } + } + return true; +} + +void SetGlobalPropertiesRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace helpers; + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::UI_SetGlobalProperties: { + LOG4CXX_INFO(logger_, "Received UI_SetGlobalProperties event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + is_ui_received_ = true; + ui_result_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + GetInfo(message, ui_response_info_); + break; + } + case hmi_apis::FunctionID::TTS_SetGlobalProperties: { + LOG4CXX_INFO(logger_, "Received TTS_SetGlobalProperties event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_TTS); + is_tts_received_ = true; + tts_result_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + GetInfo(message, tts_response_info_); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } + + if (IsPendingResponseExist()) { + LOG4CXX_DEBUG(logger_, "Continue waiting for response"); + return; + } + mobile_apis::Result::eType result_code = mobile_apis::Result::INVALID_ENUM; + std::string response_info; + const bool result = PrepareResponseParameters(result_code, response_info); + + // TODO{ALeshin} APPLINK-15858. connection_key removed during SendResponse + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + + SendResponse(result, + result_code, + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); +} + +bool SetGlobalPropertiesRequest::Init() { + hash_update_mode_ = HashUpdateMode::kDoHashUpdate; + return true; +} + +bool SetGlobalPropertiesRequest::PrepareResponseParameters( + mobile_apis::Result::eType& result_code, std::string& info) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace helpers; + + ResponseInfo ui_properties_info( + ui_result_, HmiInterfaces::HMI_INTERFACE_UI, application_manager_); + + ResponseInfo tts_properties_info( + tts_result_, HmiInterfaces::HMI_INTERFACE_TTS, application_manager_); + const bool result = + PrepareResultForMobileResponse(ui_properties_info, tts_properties_info); + if (result && + (HmiInterfaces::STATE_AVAILABLE == tts_properties_info.interface_state) && + (tts_properties_info.is_unsupported_resource)) { + result_code = mobile_apis::Result::WARNINGS; + tts_response_info_ = "Unsupported phoneme type sent in a prompt"; + info = MergeInfos(tts_properties_info, + tts_response_info_, + ui_properties_info, + ui_response_info_); + return result; + } + result_code = + PrepareResultCodeForResponse(ui_properties_info, tts_properties_info); + info = MergeInfos(tts_properties_info, + tts_response_info_, + ui_properties_info, + ui_response_info_); + return result; +} + +bool SetGlobalPropertiesRequest::ValidateVRHelpTitle( + const smart_objects::SmartObject* const vr_help_so_ptr) { + LOG4CXX_AUTO_TRACE(logger_); + if (vr_help_so_ptr) { + const std::string& vr_help = vr_help_so_ptr->asString(); + LOG4CXX_TRACE(logger_, "App contains vr_help_title: \"" << vr_help << '"'); + return !vr_help.empty(); + } + return false; +} + +void SetGlobalPropertiesRequest::PrepareUIRequestVRHelpData( + const ApplicationSharedPtr app, + const smart_objects::SmartObject& msg_params, + smart_objects::SmartObject& out_params) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(app); + + app->set_vr_help_title(msg_params.getElement(strings::vr_help_title)); + app->set_vr_help(msg_params.getElement(strings::vr_help)); + + out_params[strings::vr_help_title] = (*app->vr_help_title()); + out_params[strings::vr_help] = (*app->vr_help()); +} + +bool SetGlobalPropertiesRequest::PrepareUIRequestDefaultVRHelpData( + const ApplicationSharedPtr app, smart_objects::SmartObject& out_params) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN(app, false); + + LOG4CXX_DEBUG(logger_, "Generate default VRHelp data"); + const DataAccessor<CommandsMap> accessor = app->commands_map(); + const CommandsMap& cmdMap = accessor.GetData(); + + int32_t index = 0; + smart_objects::SmartObject vr_help_items; + for (CommandsMap::const_iterator command_it = cmdMap.begin(); + cmdMap.end() != command_it; + ++command_it) { + const smart_objects::SmartObject& command = *command_it->second; + if (!command.keyExists(strings::vr_commands)) { + LOG4CXX_ERROR(logger_, "VR synonyms are empty"); + return false; + } + // use only first + vr_help_items[index][strings::position] = (index + 1); + vr_help_items[index++][strings::text] = + (*command_it->second)[strings::vr_commands][0]; + } + + app->set_vr_help_title(smart_objects::SmartObject(app->name())); + + out_params[strings::vr_help_title] = (*app->vr_help_title()); + if (vr_help_items.length() > 0) { + app->set_vr_help(vr_help_items); + out_params[strings::vr_help] = (*app->vr_help()); + } + return true; +} + +void SetGlobalPropertiesRequest::PrepareUIRequestMenuAndKeyboardData( + const ApplicationSharedPtr app, + const smart_objects::SmartObject& msg_params, + smart_objects::SmartObject& out_params) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(app); + + const bool is_menu_title_present = + msg_params.keyExists(hmi_request::menu_title); + const bool is_menu_icon_present = + msg_params.keyExists(hmi_request::menu_icon); + const bool is_keyboard_props_present = + msg_params.keyExists(hmi_request::keyboard_properties); + + if (is_menu_title_present) { + out_params[hmi_request::menu_title] = + msg_params[hmi_request::menu_title].asString(); + app->set_menu_title(msg_params[hmi_request::menu_title]); + } + if (is_menu_icon_present) { + out_params[hmi_request::menu_icon] = msg_params[hmi_request::menu_icon]; + app->set_menu_icon(msg_params[hmi_request::menu_icon]); + } + if (is_keyboard_props_present) { + out_params[hmi_request::keyboard_properties] = + msg_params[hmi_request::keyboard_properties]; + app->set_keyboard_props(msg_params[hmi_request::keyboard_properties]); + } +} + +void SetGlobalPropertiesRequest::SendTTSRequest( + const smart_objects::SmartObject& params, bool use_events) { + LOG4CXX_AUTO_TRACE(logger_); + is_tts_send_ = true; + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_TTS); + SendHMIRequest( + hmi_apis::FunctionID::TTS_SetGlobalProperties, ¶ms, use_events); +} + +void SetGlobalPropertiesRequest::SendUIRequest( + const smart_objects::SmartObject& params, bool use_events) { + LOG4CXX_AUTO_TRACE(logger_); + is_ui_send_ = true; + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + SendHMIRequest( + hmi_apis::FunctionID::UI_SetGlobalProperties, ¶ms, use_events); +} + +bool SetGlobalPropertiesRequest::IsPendingResponseExist() { + return is_ui_send_ != is_ui_received_ || is_tts_send_ != is_tts_received_; +} + +bool SetGlobalPropertiesRequest::ValidateConditionalMandatoryParameters( + const smart_objects::SmartObject& params) { + LOG4CXX_AUTO_TRACE(logger_); + return params.keyExists(strings::help_prompt) || + params.keyExists(strings::timeout_prompt) || + params.keyExists(strings::vr_help_title) || + params.keyExists(strings::vr_help) || + params.keyExists(strings::menu_title) || + params.keyExists(strings::menu_icon) || + params.keyExists(strings::keyboard_properties); +} + +bool SetGlobalPropertiesRequest::IsWhiteSpaceExist() { + LOG4CXX_AUTO_TRACE(logger_); + const char* str; + + const smart_objects::SmartObject& msg_params = + (*message_)[strings::msg_params]; + + if (msg_params.keyExists(strings::help_prompt)) { + const smart_objects::SmartArray* hp_array = + msg_params[strings::help_prompt].asArray(); + + smart_objects::SmartArray::const_iterator it_hp = hp_array->begin(); + smart_objects::SmartArray::const_iterator it_hp_end = hp_array->end(); + + for (; it_hp != it_hp_end; ++it_hp) { + str = (*it_hp)[strings::text].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid help_prompt syntax check failed"); + return true; + } + } + } + + if (msg_params.keyExists(strings::timeout_prompt)) { + const smart_objects::SmartArray* tp_array = + msg_params[strings::timeout_prompt].asArray(); + + smart_objects::SmartArray::const_iterator it_tp = tp_array->begin(); + smart_objects::SmartArray::const_iterator it_tp_end = tp_array->end(); + + for (; it_tp != it_tp_end; ++it_tp) { + str = (*it_tp)[strings::text].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid timeout_prompt syntax check failed"); + return true; + } + } + } + + if (msg_params.keyExists(strings::vr_help)) { + const smart_objects::SmartArray* vh_array = + msg_params[strings::vr_help].asArray(); + + smart_objects::SmartArray::const_iterator it_vh = vh_array->begin(); + smart_objects::SmartArray::const_iterator it_vh_end = vh_array->end(); + + for (; it_vh != it_vh_end; ++it_vh) { + str = (*it_vh)[strings::text].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid vr_help text syntax check failed"); + return true; + } + + if ((*it_vh).keyExists(strings::image)) { + str = (*it_vh)[strings::image][strings::value].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid vr_help image value syntax check failed"); + return true; + } + } // if image exists + } // for - vh_array iteration + } + + if (msg_params.keyExists(strings::menu_icon)) { + str = msg_params[strings::menu_icon][strings::value].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid menu_icon value syntax check failed"); + return true; + } + } + + if (msg_params.keyExists(strings::vr_help_title)) { + str = msg_params[strings::vr_help_title].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid vr_help_title value syntax check failed"); + return true; + } + } + + if (msg_params.keyExists(strings::menu_title)) { + str = msg_params[strings::menu_title].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid menu_title value syntax check failed"); + return true; + } + } + + if (msg_params.keyExists(strings::keyboard_properties)) { + if (msg_params[strings::keyboard_properties].keyExists( + strings::limited_character_list)) { + const smart_objects::SmartArray* lcl_array = + msg_params[strings::keyboard_properties] + [strings::limited_character_list].asArray(); + + smart_objects::SmartArray::const_iterator it_lcl = lcl_array->begin(); + smart_objects::SmartArray::const_iterator it_lcl_end = lcl_array->end(); + + for (; it_lcl != it_lcl_end; ++it_lcl) { + str = (*it_lcl).asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid keyboard_properties " + "limited_character_list syntax check failed"); + return true; + } + } + } + + if (msg_params[strings::keyboard_properties].keyExists( + strings::auto_complete_text)) { + str = + msg_params[strings::keyboard_properties][strings::auto_complete_text] + .asCharArray(); + + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid keyboard_properties " + "auto_complete_text syntax check failed"); + return true; + } + } + } + return false; +} + +} // namespace commands +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_global_properties_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_global_properties_response.cc new file mode 100644 index 0000000000..cea090f35b --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_global_properties_response.cc @@ -0,0 +1,55 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/set_global_properties_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +SetGlobalPropertiesResponse::SetGlobalPropertiesResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +SetGlobalPropertiesResponse::~SetGlobalPropertiesResponse() {} + +void SetGlobalPropertiesResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_icon_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_icon_request.cc new file mode 100644 index 0000000000..037de54456 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_icon_request.cc @@ -0,0 +1,140 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/set_icon_request.h" +#include "application_manager/application_manager.h" +#include "application_manager/application_impl.h" +#include "config_profile/profile.h" +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" +#include "utils/file_system.h" + +namespace application_manager { + +namespace commands { + +SetIconRequest::SetIconRequest(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +SetIconRequest::~SetIconRequest() {} + +void SetIconRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "Application is not registered"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + const std::string& sync_file_name = + (*message_)[strings::msg_params][strings::sync_file_name].asString(); + + std::string full_file_path = + application_manager_.get_settings().app_storage_folder() + "/"; + full_file_path += app->folder_name(); + full_file_path += "/"; + full_file_path += sync_file_name; + + if (!file_system::FileExists(full_file_path)) { + LOG4CXX_ERROR(logger_, "No such file " << full_file_path); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::app_id] = app->app_id(); + msg_params[strings::sync_file_name] = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + // Panasonic requres unchanged path value without encoded special characters + const std::string full_file_path_for_hmi = + file_system::ConvertPathForURL(full_file_path); + + msg_params[strings::sync_file_name][strings::value] = full_file_path_for_hmi; + + // TODO(VS): research why is image_type hardcoded + msg_params[strings::sync_file_name][strings::image_type] = + static_cast<int32_t>(SetIconRequest::ImageType::DYNAMIC); + + // for further use in on_event function + (*message_)[strings::msg_params][strings::sync_file_name] = + msg_params[strings::sync_file_name]; + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + SendHMIRequest(hmi_apis::FunctionID::UI_SetAppIcon, &msg_params, true); +} + +void SetIconRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::UI_SetAppIcon: { + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + mobile_apis::Result::eType result_code = + static_cast<mobile_apis::Result::eType>( + message[strings::params][hmi_response::code].asInt()); + + bool result = mobile_apis::Result::SUCCESS == result_code; + + if (result) { + ApplicationSharedPtr app = + application_manager_.application(connection_key()); + + const std::string path = + (*message_)[strings::msg_params][strings::sync_file_name] + [strings::value].asString(); + app->set_app_icon_path(path); + + LOG4CXX_INFO(logger_, + "Icon path was set to '" << app->app_icon_path() << "'"); + } + + SendResponse(result, result_code, NULL, &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_icon_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_icon_response.cc new file mode 100644 index 0000000000..524d4e3ad9 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_icon_response.cc @@ -0,0 +1,56 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/set_icon_response.h" +#include "application_manager/application_manager.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +SetIconResponse::SetIconResponse(const MessageSharedPtr& message, + ApplicationManager& app_man) + : CommandResponseImpl(message, app_man) {} + +SetIconResponse::~SetIconResponse() {} + +void SetIconResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_media_clock_timer_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_media_clock_timer_request.cc new file mode 100644 index 0000000000..54727abe01 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_media_clock_timer_request.cc @@ -0,0 +1,157 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/set_media_clock_timer_request.h" + +#include "application_manager/message_helper.h" +#include "application_manager/application_impl.h" +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" + +namespace application_manager { + +namespace commands { + +SetMediaClockRequest::SetMediaClockRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +SetMediaClockRequest::~SetMediaClockRequest() {} + +void SetMediaClockRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + LOG4CXX_ERROR(logger_, "Application is not registered"); + return; + } + + if (!app->is_media_application()) { + LOG4CXX_ERROR(logger_, "Application is not media application"); + SendResponse(false, mobile_apis::Result::REJECTED); + return; + } + + if (isDataValid()) { + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + // copy entirely msg + msg_params = (*message_)[strings::msg_params]; + msg_params[strings::app_id] = app->app_id(); + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + + SendHMIRequest( + hmi_apis::FunctionID::UI_SetMediaClockTimer, &msg_params, true); + } else { + SendResponse(false, mobile_apis::Result::INVALID_DATA); + } +} + +void SetMediaClockRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::UI_SetMediaClockTimer: { + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + const bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_UI); + std::string response_info; + GetInfo(message, response_info); + + SendResponse(result, + MessageHelper::HMIToMobileResult(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } +} + +bool SetMediaClockRequest::isDataValid() { + smart_objects::SmartObject msg_params = (*message_)[strings::msg_params]; + mobile_apis::UpdateMode::eType update_mode = + static_cast<mobile_apis::UpdateMode::eType>( + msg_params[strings::update_mode].asUInt()); + + if (update_mode == mobile_apis::UpdateMode::COUNTUP || + update_mode == mobile_apis::UpdateMode::COUNTDOWN) { + if (!msg_params.keyExists(strings::start_time)) { + LOG4CXX_INFO(logger_, "Invalid data"); + return false; + } + + if (msg_params.keyExists(strings::end_time)) { + unsigned int start_time_in_seconds = 0; + start_time_in_seconds = + (msg_params[strings::start_time][strings::hours].asUInt()) * 3600; + start_time_in_seconds += + (msg_params[strings::start_time][strings::minutes].asUInt()) * 60; + start_time_in_seconds += + (msg_params[strings::start_time][strings::seconds].asUInt()); + + unsigned int end_time_in_seconds = 0; + end_time_in_seconds = + (msg_params[strings::end_time][strings::hours].asUInt()) * 3600; + end_time_in_seconds += + (msg_params[strings::end_time][strings::minutes].asUInt()) * 60; + end_time_in_seconds += + (msg_params[strings::end_time][strings::seconds].asUInt()); + + if (((end_time_in_seconds > start_time_in_seconds) && + (update_mode == mobile_apis::UpdateMode::COUNTDOWN)) || + ((end_time_in_seconds < start_time_in_seconds) && + (update_mode == mobile_apis::UpdateMode::COUNTUP))) { + LOG4CXX_INFO(logger_, "Invalid data"); + return false; + } + } + } + + LOG4CXX_INFO(logger_, "Data is valid"); + return true; +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_media_clock_timer_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_media_clock_timer_response.cc new file mode 100644 index 0000000000..d189891888 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_media_clock_timer_response.cc @@ -0,0 +1,55 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/set_media_clock_timer_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +SetMediaClockTimerResponse::SetMediaClockTimerResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +SetMediaClockTimerResponse::~SetMediaClockTimerResponse() {} + +void SetMediaClockTimerResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/show_constant_tbt_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/show_constant_tbt_request.cc new file mode 100644 index 0000000000..42bfea4864 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/show_constant_tbt_request.cc @@ -0,0 +1,285 @@ +/* + + Copyright (c) 2013, 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 <cstring> +#include "application_manager/commands/mobile/show_constant_tbt_request.h" + +#include "application_manager/policies/policy_handler.h" +#include "application_manager/application_impl.h" +#include "application_manager/message_helper.h" +#include "application_manager/policies/policy_handler_interface.h" +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" + +namespace application_manager { + +namespace commands { + +ShowConstantTBTRequest::ShowConstantTBTRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +ShowConstantTBTRequest::~ShowConstantTBTRequest() {} + +void ShowConstantTBTRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application( + (*message_)[strings::params][strings::connection_key].asUInt()); + + if (!app) { + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + LOG4CXX_ERROR(logger_, "Application is not registered"); + return; + } + // SDLAQ-CRS-664, VC3.1 + if ((*message_)[strings::msg_params].empty()) { + LOG4CXX_ERROR(logger_, "INVALID_DATA!"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_params = (*message_)[strings::msg_params]; + + if (IsWhiteSpaceExist()) { + LOG4CXX_ERROR(logger_, + "Incoming show constant TBT has contains \t\n \\t \\n"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + // ProcessSoftButtons checks strings on the contents incorrect character + + mobile_apis::Result::eType processing_result = + MessageHelper::ProcessSoftButtons(msg_params, + app, + application_manager_.GetPolicyHandler(), + application_manager_); + + if (mobile_apis::Result::SUCCESS != processing_result) { + LOG4CXX_ERROR(logger_, "INVALID_DATA!"); + SendResponse(false, processing_result); + return; + } + + mobile_apis::Result::eType verification_result = mobile_apis::Result::SUCCESS; + if (msg_params.keyExists(strings::turn_icon)) { + verification_result = MessageHelper::VerifyImage( + msg_params[strings::turn_icon], app, application_manager_); + if (mobile_apis::Result::SUCCESS != verification_result) { + LOG4CXX_ERROR(logger_, "VerifyImage INVALID_DATA!"); + SendResponse(false, verification_result); + return; + } + } + + if (msg_params.keyExists(strings::next_turn_icon)) { + verification_result = MessageHelper::VerifyImage( + msg_params[strings::next_turn_icon], app, application_manager_); + if (mobile_apis::Result::SUCCESS != verification_result) { + LOG4CXX_ERROR(logger_, "VerifyImage INVALID_DATA!"); + SendResponse(false, verification_result); + return; + } + } + + msg_params[strings::app_id] = app->app_id(); + + msg_params[hmi_request::navi_texts] = + smart_objects::SmartObject(smart_objects::SmartType_Array); + + int32_t index = 0; + if (msg_params.keyExists(strings::navigation_text_1)) { + // erase useless parametr + msg_params.erase(strings::navigation_text_1); + msg_params[hmi_request::navi_texts][index][hmi_request::field_name] = + static_cast<int32_t>(hmi_apis::Common_TextFieldName::navigationText1); + msg_params[hmi_request::navi_texts][index++][hmi_request::field_text] = + (*message_)[strings::msg_params][strings::navigation_text_1]; + } + + if (msg_params.keyExists(strings::navigation_text_2)) { + // erase useless param + msg_params.erase(strings::navigation_text_2); + msg_params[hmi_request::navi_texts][index][hmi_request::field_name] = + static_cast<int32_t>(hmi_apis::Common_TextFieldName::navigationText2); + msg_params[hmi_request::navi_texts][index++][hmi_request::field_text] = + (*message_)[strings::msg_params][strings::navigation_text_2]; + } + + if (msg_params.keyExists(strings::eta)) { + // erase useless param + msg_params.erase(strings::eta); + msg_params[hmi_request::navi_texts][index][hmi_request::field_name] = + static_cast<int32_t>(hmi_apis::Common_TextFieldName::ETA); + msg_params[hmi_request::navi_texts][index++][hmi_request::field_text] = + (*message_)[strings::msg_params][strings::eta]; + } + + if (msg_params.keyExists(strings::total_distance)) { + // erase useless param + msg_params.erase(strings::total_distance); + msg_params[hmi_request::navi_texts][index][hmi_request::field_name] = + static_cast<int32_t>(hmi_apis::Common_TextFieldName::totalDistance); + msg_params[hmi_request::navi_texts][index++][hmi_request::field_text] = + (*message_)[strings::msg_params][strings::total_distance]; + } + + if (msg_params.keyExists(strings::time_to_destination)) { + // erase useless param + msg_params.erase(strings::time_to_destination); + msg_params[hmi_request::navi_texts][index][hmi_request::field_name] = + static_cast<int32_t>(hmi_apis::Common_TextFieldName::timeToDestination); + msg_params[hmi_request::navi_texts][index++][hmi_request::field_text] = + (*message_)[strings::msg_params][strings::time_to_destination]; + } + + if (msg_params.keyExists(strings::soft_buttons)) { + MessageHelper::SubscribeApplicationToSoftButton( + msg_params, app, function_id()); + } + + app->set_tbt_show_command(msg_params); + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_Navigation); + SendHMIRequest( + hmi_apis::FunctionID::Navigation_ShowConstantTBT, &msg_params, true); +} + +void ShowConstantTBTRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace hmi_apis; + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::Navigation_ShowConstantTBT: { + LOG4CXX_INFO(logger_, "Received Navigation_ShowConstantTBT event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_Navigation); + const Common_Result::eType result_code = + static_cast<Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + std::string response_info; + GetInfo(message, response_info); + const bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_Navigation); + SendResponse(result, + MessageHelper::HMIToMobileResult(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + break; + } + } +} + +bool ShowConstantTBTRequest::IsWhiteSpaceExist() { + LOG4CXX_AUTO_TRACE(logger_); + const char* str = NULL; + + if ((*message_)[strings::msg_params].keyExists(strings::turn_icon)) { + str = (*message_)[strings::msg_params][strings::turn_icon][strings::value] + .asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid turn_icon value syntax check failed"); + return true; + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::next_turn_icon)) { + str = (*message_)[strings::msg_params][strings::next_turn_icon] + [strings::value].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid next_turn_icon value syntax check failed"); + return true; + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::navigation_text_1)) { + str = (*message_)[strings::msg_params][strings::navigation_text_1] + .asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid navigation_text_1 value syntax check failed"); + return true; + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::navigation_text_2)) { + str = (*message_)[strings::msg_params][strings::navigation_text_2] + .asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid navigation_text_2 value syntax check failed"); + return true; + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::eta)) { + str = (*message_)[strings::msg_params][strings::eta].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid eta value syntax check failed"); + return true; + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::total_distance)) { + str = + (*message_)[strings::msg_params][strings::total_distance].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid total_distance value syntax check failed"); + return true; + } + } + + if ((*message_)[strings::msg_params].keyExists( + strings::time_to_destination)) { + str = (*message_)[strings::msg_params][strings::time_to_destination] + .asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid time_to_destination value syntax check failed"); + return true; + } + } + return false; +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/show_constant_tbt_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/show_constant_tbt_response.cc new file mode 100644 index 0000000000..d2cdc1689a --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/show_constant_tbt_response.cc @@ -0,0 +1,57 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/show_constant_tbt_response.h" +#include "application_manager/rpc_service.h" +#include "interfaces/HMI_API.h" + +namespace application_manager { + +namespace commands { + +ShowConstantTBTResponse::ShowConstantTBTResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + + : CommandResponseImpl(message, application_manager) {} + +ShowConstantTBTResponse::~ShowConstantTBTResponse() {} + +void ShowConstantTBTResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/show_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/show_request.cc new file mode 100644 index 0000000000..ad598efc1d --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/show_request.cc @@ -0,0 +1,403 @@ +/* + + Copyright (c) 2013, 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 <string.h> +#include "application_manager/commands/mobile/show_request.h" + +#include "application_manager/policies/policy_handler.h" +#include "application_manager/application.h" +#include "application_manager/message_helper.h" +#include "utils/file_system.h" +#include "utils/helpers.h" + +namespace application_manager { + +namespace commands { + +ShowRequest::ShowRequest(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) + , core_result_code_(mobile_apis::Result::INVALID_ENUM) {} + +ShowRequest::~ShowRequest() {} + +void ShowRequest::HandleMetadata(const char* field_id, + int32_t field_index, + smart_objects::SmartObject& msg_params) { + smart_objects::SmartObject& metadata_tags = + (*message_)[strings::msg_params][strings::metadata_tags]; + + if (metadata_tags.keyExists(field_id)) { + if (field_index != -1) { + msg_params[hmi_request::show_strings][field_index] + [hmi_request::field_types] = + smart_objects::SmartObject(smart_objects::SmartType_Array); + + const size_t num_tags = metadata_tags[field_id].length(); + for (size_t i = 0; i < num_tags; ++i) { + const int32_t current_tag = metadata_tags[field_id][i].asInt(); + msg_params[hmi_request::show_strings][field_index] + [hmi_request::field_types][i] = current_tag; + } + } else { + LOG4CXX_INFO(logger_, + "metadata tag provided with no item for " + << field_id << ", ignoring with warning"); + // tag provided with no item, ignore with warning + if (mobile_apis::Result::INVALID_ENUM == core_result_code_) { + core_result_code_ = mobile_apis::Result::WARNINGS; + core_response_info_ = + "Metadata tag was provided for a field with no data."; + } + } + } else { + LOG4CXX_INFO(logger_, + "No metadata tagging provided for field: " << field_id); + } +} + +void ShowRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "Application is not registered"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + // SDLAQ-CRS-494, VC3.1 + if ((*message_)[strings::msg_params].empty()) { + LOG4CXX_ERROR(logger_, strings::msg_params << " is empty."); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + if (!CheckStringsOfShowRequest()) { + LOG4CXX_ERROR(logger_, "Incorrect characters in string"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + // ProcessSoftButtons checks strings on the contents incorrect character + + mobile_apis::Result::eType processing_result = mobile_apis::Result::SUCCESS; + if (((*message_)[strings::msg_params].keyExists(strings::soft_buttons)) && + ((*message_)[strings::msg_params][strings::soft_buttons].length() > 0)) { + processing_result = MessageHelper::ProcessSoftButtons( + (*message_)[strings::msg_params], + app, + application_manager_.GetPolicyHandler(), + application_manager_); + } + + if (mobile_apis::Result::SUCCESS != processing_result) { + LOG4CXX_ERROR(logger_, "Processing of soft buttons failed."); + SendResponse(false, processing_result); + return; + } + + mobile_apis::Result::eType verification_result = mobile_apis::Result::SUCCESS; + if (((*message_)[strings::msg_params].keyExists(strings::graphic)) && + ((*message_)[strings::msg_params][strings::graphic][strings::value] + .asString()).length()) { + verification_result = MessageHelper::VerifyImage( + (*message_)[strings::msg_params][strings::graphic], + app, + application_manager_); + if (mobile_apis::Result::SUCCESS != verification_result) { + LOG4CXX_ERROR(logger_, "Image verification failed."); + SendResponse(false, verification_result); + return; + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::secondary_graphic)) { + verification_result = MessageHelper::VerifyImage( + (*message_)[strings::msg_params][strings::secondary_graphic], + app, + application_manager_); + if (mobile_apis::Result::SUCCESS != verification_result) { + LOG4CXX_ERROR(logger_, "Image verification failed."); + SendResponse(false, verification_result); + return; + } + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_params[strings::app_id] = app->app_id(); + + msg_params[hmi_request::show_strings] = + smart_objects::SmartObject(smart_objects::SmartType_Array); + + int32_t index = 0; + int32_t main_field_1_index = -1; + if ((*message_)[strings::msg_params].keyExists(strings::main_field_1)) { + msg_params[hmi_request::show_strings][index][hmi_request::field_name] = + static_cast<int32_t>(hmi_apis::Common_TextFieldName::mainField1); + msg_params[hmi_request::show_strings][index][hmi_request::field_text] = + (*message_)[strings::msg_params][strings::main_field_1]; + main_field_1_index = index; + ++index; + } + + int32_t main_field_2_index = -1; + if ((*message_)[strings::msg_params].keyExists(strings::main_field_2)) { + msg_params[hmi_request::show_strings][index][hmi_request::field_name] = + static_cast<int32_t>(hmi_apis::Common_TextFieldName::mainField2); + msg_params[hmi_request::show_strings][index][hmi_request::field_text] = + (*message_)[strings::msg_params][strings::main_field_2]; + main_field_2_index = index; + ++index; + } + + int32_t main_field_3_index = -1; + if ((*message_)[strings::msg_params].keyExists(strings::main_field_3)) { + msg_params[hmi_request::show_strings][index][hmi_request::field_name] = + static_cast<int32_t>(hmi_apis::Common_TextFieldName::mainField3); + msg_params[hmi_request::show_strings][index][hmi_request::field_text] = + (*message_)[strings::msg_params][strings::main_field_3]; + main_field_3_index = index; + ++index; + } + + int32_t main_field_4_index = -1; + if ((*message_)[strings::msg_params].keyExists(strings::main_field_4)) { + msg_params[hmi_request::show_strings][index][hmi_request::field_name] = + static_cast<int32_t>(hmi_apis::Common_TextFieldName::mainField4); + msg_params[hmi_request::show_strings][index][hmi_request::field_text] = + (*message_)[strings::msg_params][strings::main_field_4]; + main_field_4_index = index; + ++index; + } + + if ((*message_)[strings::msg_params].keyExists(strings::metadata_tags)) { + HandleMetadata(strings::main_field_1, main_field_1_index, msg_params); + HandleMetadata(strings::main_field_2, main_field_2_index, msg_params); + HandleMetadata(strings::main_field_3, main_field_3_index, msg_params); + HandleMetadata(strings::main_field_4, main_field_4_index, msg_params); + } + + if ((*message_)[strings::msg_params].keyExists(strings::media_clock)) { + msg_params[hmi_request::show_strings][index][hmi_request::field_name] = + static_cast<int32_t>(hmi_apis::Common_TextFieldName::mediaClock); + msg_params[hmi_request::show_strings][index][hmi_request::field_text] = + (*message_)[strings::msg_params][strings::media_clock]; + ++index; + } + + if ((*message_)[strings::msg_params].keyExists(strings::media_track)) { + msg_params[hmi_request::show_strings][index][hmi_request::field_name] = + static_cast<int32_t>(hmi_apis::Common_TextFieldName::mediaTrack); + msg_params[hmi_request::show_strings][index][hmi_request::field_text] = + (*message_)[strings::msg_params][strings::media_track]; + ++index; + } + + if ((*message_)[strings::msg_params].keyExists(strings::status_bar)) { + msg_params[hmi_request::show_strings][index][hmi_request::field_name] = + static_cast<int32_t>(hmi_apis::Common_TextFieldName::statusBar); + msg_params[hmi_request::show_strings][index][hmi_request::field_text] = + (*message_)[strings::msg_params][strings::status_bar]; + ++index; + } + + if ((*message_)[strings::msg_params].keyExists(strings::alignment)) { + msg_params[strings::alignment] = + (*message_)[strings::msg_params][strings::alignment]; + } + + if ((*message_)[strings::msg_params].keyExists(strings::graphic)) { + msg_params[strings::graphic] = + (*message_)[strings::msg_params][strings::graphic]; + } + + if ((*message_)[strings::msg_params].keyExists(strings::secondary_graphic)) { + msg_params[strings::secondary_graphic] = + (*message_)[strings::msg_params][strings::secondary_graphic]; + } + + if ((*message_)[strings::msg_params].keyExists(strings::soft_buttons)) { + msg_params[strings::soft_buttons] = + (*message_)[strings::msg_params][strings::soft_buttons]; + if ((*message_)[strings::msg_params][strings::soft_buttons].length() == 0) { + app->UnsubscribeFromSoftButtons(function_id()); + } else { + MessageHelper::SubscribeApplicationToSoftButton( + (*message_)[strings::msg_params], app, function_id()); + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::custom_presets)) { + msg_params[strings::custom_presets] = + (*message_)[strings::msg_params][strings::custom_presets]; + } + + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + SendHMIRequest(hmi_apis::FunctionID::UI_Show, &msg_params, true); + + MessageSharedPtr persistentData = new smart_objects::SmartObject(msg_params); + app->set_show_command(*persistentData); +} + +void ShowRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace helpers; + + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::UI_Show: { + LOG4CXX_DEBUG(logger_, "Received UI_Show event."); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + std::string response_info; + hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + const bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_UI); + GetInfo(message, response_info); + if (hmi_apis::Common_Result::WARNINGS == result_code && + message[strings::params].keyExists(hmi_response::message)) { + response_info = + message[strings::params][hmi_response::message].asString(); + } + mobile_apis::Result::eType converted_result_code = + MessageHelper::HMIToMobileResult(result_code); + if (mobile_apis::Result::SUCCESS == converted_result_code && + mobile_apis::Result::INVALID_ENUM != core_result_code_) { + converted_result_code = core_result_code_; + response_info = core_response_info_; + } + SendResponse(result, + converted_result_code, + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event " << event.id()); + break; + } + } +} + +bool ShowRequest::CheckStringsOfShowRequest() { + LOG4CXX_AUTO_TRACE(logger_); + const char* str; + + if ((*message_)[strings::msg_params].keyExists(strings::main_field_4)) { + str = (*message_)[strings::msg_params][strings::main_field_4].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid main_field_4 syntax check failed"); + return false; + } + } + if ((*message_)[strings::msg_params].keyExists(strings::main_field_3)) { + str = (*message_)[strings::msg_params][strings::main_field_3].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid main_field_3 syntax check failed"); + return false; + } + } + if ((*message_)[strings::msg_params].keyExists(strings::main_field_2)) { + str = (*message_)[strings::msg_params][strings::main_field_2].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid main_field_2 syntax check failed"); + return false; + } + } + if ((*message_)[strings::msg_params].keyExists(strings::main_field_1)) { + str = (*message_)[strings::msg_params][strings::main_field_1].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid main_field_1 syntax check failed"); + return false; + } + } + if ((*message_)[strings::msg_params].keyExists(strings::status_bar)) { + str = (*message_)[strings::msg_params][strings::status_bar].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid status_bar syntax check failed"); + return false; + } + } + if ((*message_)[strings::msg_params].keyExists(strings::media_clock)) { + str = (*message_)[strings::msg_params][strings::media_clock].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid media_clock syntax check failed"); + return false; + } + } + if ((*message_)[strings::msg_params].keyExists(strings::media_track)) { + str = (*message_)[strings::msg_params][strings::media_track].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid media_track syntax check failed"); + return false; + } + } + if ((*message_)[strings::msg_params].keyExists(strings::custom_presets)) { + smart_objects::SmartObject& custom_presets_array = + (*message_)[strings::msg_params][strings::custom_presets]; + for (size_t i = 0; i < custom_presets_array.length(); ++i) { + str = custom_presets_array[i].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid custom_presets syntax check failed"); + return false; + } + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::graphic)) { + str = (*message_)[strings::msg_params][strings::graphic][strings::value] + .asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid graphic value syntax check failed"); + return false; + } + } + + if ((*message_)[strings::msg_params].keyExists(strings::secondary_graphic)) { + str = (*message_)[strings::msg_params][strings::secondary_graphic] + [strings::value].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, + "Invalid secondary_graphic value syntax check failed"); + return false; + } + } + return true; +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/show_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/show_response.cc new file mode 100644 index 0000000000..b3a54ee2dd --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/show_response.cc @@ -0,0 +1,57 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/show_response.h" +#include "application_manager/rpc_service.h" +#include "application_manager/application_impl.h" +#include "interfaces/HMI_API.h" + +namespace application_manager { + +namespace commands { + +ShowResponse::ShowResponse(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +ShowResponse::~ShowResponse() {} + +void ShowResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/slider_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/slider_request.cc new file mode 100644 index 0000000000..f98869b08f --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/slider_request.cc @@ -0,0 +1,198 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/slider_request.h" + +#include "application_manager/application_impl.h" +#include "application_manager/message_helper.h" +#include "utils/helpers.h" +#include "config_profile/profile.h" + +namespace application_manager { + +namespace commands { + +SliderRequest::SliderRequest(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) { + subscribe_on_event(hmi_apis::FunctionID::UI_OnResetTimeout); +} + +SliderRequest::~SliderRequest() {} + +bool SliderRequest::Init() { + /* Timeout in milliseconds. + If omitted a standard value of 10000 milliseconds is used.*/ + if ((*message_)[strings::msg_params].keyExists(strings::timeout)) { + default_timeout_ = + application_manager_.get_settings().default_timeout() + + (*message_)[strings::msg_params][strings::timeout].asUInt(); + } + + return true; +} + +void SliderRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr application = application_manager_.application( + (*message_)[strings::params][strings::connection_key].asUInt()); + + if (!application) { + LOG4CXX_ERROR(logger_, "Application is not registered"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + if ((*message_)[strings::msg_params][strings::num_ticks].asInt() < + (*message_)[strings::msg_params][strings::position].asInt()) { + LOG4CXX_ERROR(logger_, "INVALID_DATA"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + if ((*message_)[strings::msg_params].keyExists(strings::slider_footer)) { + if (1 < (*message_)[strings::msg_params][strings::slider_footer].length()) { + if ((*message_)[strings::msg_params][strings::num_ticks].asUInt() != + (*message_)[strings::msg_params][strings::slider_footer].length()) { + LOG4CXX_ERROR(logger_, "INVALID_DATA"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + } + } + + if (IsWhiteSpaceExist()) { + LOG4CXX_ERROR(logger_, "Incoming slider has contains \t\n \\t \\n"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_params = (*message_)[strings::msg_params]; + msg_params[strings::app_id] = application->app_id(); + + if (!(*message_)[strings::msg_params].keyExists(strings::timeout)) { + msg_params[strings::timeout] = default_timeout_; + } + + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + SendHMIRequest(hmi_apis::FunctionID::UI_Slider, &msg_params, true); +} + +void SliderRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace helpers; + using namespace smart_objects; + using namespace hmi_apis; + + const SmartObject& message = event.smart_object(); + + const event_engine::Event::EventID event_id = event.id(); + if (event_id == FunctionID::UI_OnResetTimeout) { + LOG4CXX_INFO(logger_, "Received UI_OnResetTimeout event"); + application_manager_.updateRequestTimeout( + connection_key(), correlation_id(), default_timeout()); + return; + } + + if (event_id != FunctionID::UI_Slider) { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + + LOG4CXX_DEBUG(logger_, "Received UI_Slider event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); + const Common_Result::eType response_code = static_cast<Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + + SmartObject response_msg_params = message[strings::msg_params]; + + const bool is_timeout_aborted = Compare<Common_Result::eType, EQ, ONE>( + response_code, Common_Result::TIMED_OUT, Common_Result::ABORTED); + + if (is_timeout_aborted) { + if (message[strings::params][strings::data].keyExists( + strings::slider_position)) { + // Copy slider_position info to msg_params section + response_msg_params[strings::slider_position] = + message[strings::params][strings::data][strings::slider_position]; + } else { + LOG4CXX_ERROR(logger_, + strings::slider_position << " field is absent" + " in response."); + response_msg_params[strings::slider_position] = 0; + } + } + std::string response_info; + GetInfo(message, response_info); + const bool is_response_success = PrepareResultForMobileResponse( + response_code, HmiInterfaces::HMI_INTERFACE_UI); + + SendResponse(is_response_success, + MessageHelper::HMIToMobileResult(response_code), + response_info.empty() ? NULL : response_info.c_str(), + &response_msg_params); +} + +bool SliderRequest::IsWhiteSpaceExist() { + LOG4CXX_AUTO_TRACE(logger_); + const char* str = NULL; + + str = (*message_)[strings::msg_params][strings::slider_header].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid slider_header value syntax check failed"); + return true; + } + + if ((*message_)[strings::msg_params].keyExists(strings::slider_footer)) { + const smart_objects::SmartArray* sf_array = + (*message_)[strings::msg_params][strings::slider_footer].asArray(); + + smart_objects::SmartArray::const_iterator it_sf = sf_array->begin(); + smart_objects::SmartArray::const_iterator it_sf_end = sf_array->end(); + + for (; it_sf != it_sf_end; ++it_sf) { + str = (*it_sf).asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid slider_footer syntax check failed"); + return true; + } + } + } + return false; +} + +} // namespace commands +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/slider_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/slider_response.cc new file mode 100644 index 0000000000..4664689f0c --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/slider_response.cc @@ -0,0 +1,55 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/slider_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +SliderResponse::SliderResponse(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +SliderResponse::~SliderResponse() {} + +void SliderResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/speak_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/speak_request.cc new file mode 100644 index 0000000000..6da6b482b3 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/speak_request.cc @@ -0,0 +1,175 @@ +/* + + Copyright (c) 2013, 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 <string.h> +#include "application_manager/commands/mobile/speak_request.h" + +#include "application_manager/application_impl.h" +#include "application_manager/message_helper.h" +#include "utils/helpers.h" + +namespace application_manager { + +namespace commands { + +SpeakRequest::SpeakRequest(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) { + subscribe_on_event(hmi_apis::FunctionID::TTS_OnResetTimeout); +} + +SpeakRequest::~SpeakRequest() {} + +void SpeakRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + if (IsWhiteSpaceExist()) { + LOG4CXX_ERROR(logger_, + "Incoming speak has contains \\t\\n \\\\t \\\\n " + " text contains only whitespace in ttsChunks"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + smart_objects::SmartObject& tts_chunks = + (*message_)[strings::msg_params][strings::tts_chunks]; + mobile_apis::Result::eType verification_result = + MessageHelper::VerifyTtsFiles(tts_chunks, app, application_manager_); + + if (mobile_apis::Result::FILE_NOT_FOUND == verification_result) { + LOG4CXX_ERROR(logger_, + "MessageHelper::VerifyTtsFiles return " + << verification_result); + SendResponse(false, + mobile_apis::Result::FILE_NOT_FOUND, + "One or more files needed for tts_chunks are not present"); + return; + } + + (*message_)[strings::msg_params][strings::app_id] = app->app_id(); + (*message_)[strings::msg_params][hmi_request::speak_type] = + hmi_apis::Common_MethodName::SPEAK; + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_TTS); + SendHMIRequest(hmi_apis::FunctionID::TTS_Speak, + &message_->getElement(strings::msg_params), + true); +} + +void SpeakRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + switch (event.id()) { + case hmi_apis::FunctionID::TTS_Speak: { + LOG4CXX_INFO(logger_, "Received TTS_Speak event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_TTS); + ProcessTTSSpeakResponse(event.smart_object()); + break; + } + case hmi_apis::FunctionID::TTS_OnResetTimeout: { + LOG4CXX_INFO(logger_, "Received TTS_OnResetTimeout event"); + + application_manager_.updateRequestTimeout( + connection_key(), correlation_id(), default_timeout()); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + break; + } + } +} + +void SpeakRequest::ProcessTTSSpeakResponse( + const smart_objects::SmartObject& message) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace helpers; + + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + + if (!application) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + return; + } + + hmi_apis::Common_Result::eType hmi_result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + + mobile_apis::Result::eType result_code = + MessageHelper::HMIToMobileResult(hmi_result_code); + + const bool result = PrepareResultForMobileResponse( + hmi_result_code, HmiInterfaces::HMI_INTERFACE_TTS); + + (*message_)[strings::params][strings::function_id] = + mobile_apis::FunctionID::SpeakID; + + const char* return_info = NULL; + + SendResponse( + result, result_code, return_info, &(message[strings::msg_params])); +} + +bool SpeakRequest::IsWhiteSpaceExist() { + LOG4CXX_AUTO_TRACE(logger_); + const char* str = NULL; + + if ((*message_)[strings::msg_params].keyExists(strings::tts_chunks)) { + const smart_objects::SmartArray* tc_array = + (*message_)[strings::msg_params][strings::tts_chunks].asArray(); + + smart_objects::SmartArray::const_iterator it_tc = tc_array->begin(); + smart_objects::SmartArray::const_iterator it_tc_end = tc_array->end(); + + for (; it_tc != it_tc_end; ++it_tc) { + str = (*it_tc)[strings::text].asCharArray(); + if (strlen(str) && !CheckSyntax(str)) { + LOG4CXX_ERROR(logger_, "Invalid tts_chunks syntax check failed"); + return true; + } + } + } + return false; +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/speak_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/speak_response.cc new file mode 100644 index 0000000000..59b327e009 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/speak_response.cc @@ -0,0 +1,57 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/speak_response.h" +#include "application_manager/rpc_service.h" +#include "application_manager/application_impl.h" +#include "interfaces/HMI_API.h" + +namespace application_manager { + +namespace commands { + +SpeakResponse::SpeakResponse(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +SpeakResponse::~SpeakResponse() {} + +void SpeakResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_button_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_button_request.cc new file mode 100644 index 0000000000..4d11467d2d --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_button_request.cc @@ -0,0 +1,123 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/subscribe_button_request.h" + +namespace application_manager { + +namespace commands { + +namespace str = strings; + +SubscribeButtonRequest::SubscribeButtonRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +SubscribeButtonRequest::~SubscribeButtonRequest() {} + +void SubscribeButtonRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "APPLICATION_NOT_REGISTERED"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + const mobile_apis::ButtonName::eType btn_id = + static_cast<mobile_apis::ButtonName::eType>( + (*message_)[str::msg_params][str::button_name].asInt()); + + if (!IsSubscriptionAllowed(app, btn_id)) { + LOG4CXX_ERROR(logger_, + "Subscribe on button " << btn_id << " isn't allowed"); + SendResponse(false, mobile_apis::Result::REJECTED); + return; + } + + if (!CheckHMICapabilities(btn_id)) { + LOG4CXX_ERROR(logger_, + "Subscribe on button " + << btn_id << " isn't allowed by HMI capabilities"); + SendResponse(false, mobile_apis::Result::UNSUPPORTED_RESOURCE); + return; + } + + if (app->IsSubscribedToButton(btn_id)) { + LOG4CXX_ERROR(logger_, "Already subscribed to button " << btn_id); + SendResponse(false, mobile_apis::Result::IGNORED); + return; + } + + app->SubscribeToButton(static_cast<mobile_apis::ButtonName::eType>(btn_id)); + SendSubscribeButtonNotification(); + + const bool is_succedeed = true; + SendResponse(is_succedeed, mobile_apis::Result::SUCCESS); +} + +bool SubscribeButtonRequest::Init() { + hash_update_mode_ = HashUpdateMode::kDoHashUpdate; + return true; +} + +bool SubscribeButtonRequest::IsSubscriptionAllowed( + ApplicationSharedPtr app, mobile_apis::ButtonName::eType btn_id) { + if (!app->is_media_application() && + ((mobile_apis::ButtonName::SEEKLEFT == btn_id) || + (mobile_apis::ButtonName::SEEKRIGHT == btn_id) || + (mobile_apis::ButtonName::TUNEUP == btn_id) || + (mobile_apis::ButtonName::TUNEDOWN == btn_id))) { + return false; + } + return true; +} + +void SubscribeButtonRequest::SendSubscribeButtonNotification() { + using namespace smart_objects; + using namespace hmi_apis; + + // send OnButtonSubscription notification + SmartObject msg_params = SmartObject(SmartType_Map); + msg_params[strings::app_id] = connection_key(); + msg_params[strings::name] = static_cast<Common_ButtonName::eType>( + (*message_)[strings::msg_params][strings::button_name].asUInt()); + msg_params[strings::is_suscribed] = true; + CreateHMINotification(FunctionID::Buttons_OnButtonSubscription, msg_params); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_button_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_button_response.cc new file mode 100644 index 0000000000..a92e58b19a --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_button_response.cc @@ -0,0 +1,64 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/subscribe_button_response.h" + +namespace application_manager { + +namespace commands { + +SubscribeButtonResponse::SubscribeButtonResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +SubscribeButtonResponse::~SubscribeButtonResponse() {} + +void SubscribeButtonResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + // check if response false + if (true == (*message_)[strings::msg_params].keyExists(strings::success)) { + if ((*message_)[strings::msg_params][strings::success].asBool() == false) { + LOG4CXX_ERROR(logger_, "Success = false"); + SendResponse(false); + return; + } + } + + // TODO(DK): Some logic + SendResponse(true); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_vehicle_data_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_vehicle_data_request.cc new file mode 100644 index 0000000000..15ba7999bd --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_vehicle_data_request.cc @@ -0,0 +1,497 @@ +/* + + Copyright (c) 2013, Ford Motor Company + All rights reserved. + + Copyright (c) 2017, Livio, Inc. + 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 "application_manager/commands/mobile/subscribe_vehicle_data_request.h" + +#include "application_manager/application_impl.h" +#include "application_manager/message_helper.h" +#include "utils/helpers.h" + +namespace application_manager { +namespace commands { + +SubscribeVehicleDataRequest::SubscribeVehicleDataRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +SubscribeVehicleDataRequest::~SubscribeVehicleDataRequest() {} + +#ifdef HMI_DBUS_API +namespace { +struct Subrequest { + hmi_apis::FunctionID::eType func_id; + const char* str; +}; +Subrequest subrequests[] = { + {hmi_apis::FunctionID::VehicleInfo_SubscribeGps, strings::gps}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeSpeed, strings::speed}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeRpm, strings::rpm}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeFuelLevel, strings::fuel_level}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeFuelLevel_State, + strings::fuel_level_state}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeInstantFuelConsumption, + strings::instant_fuel_consumption}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeExternalTemperature, + strings::external_temp}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeVin, strings::vin}, + {hmi_apis::FunctionID::VehicleInfo_SubscribePrndl, strings::prndl}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeTirePressure, + strings::tire_pressure}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeOdometer, strings::odometer}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeBeltStatus, + strings::belt_status}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeBodyInformation, + strings::body_information}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeDeviceStatus, + strings::device_status}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeDriverBraking, + strings::driver_braking}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeWiperStatus, + strings::wiper_status}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeHeadLampStatus, + strings::head_lamp_status}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeEngineTorque, + strings::engine_torque}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeAccPedalPosition, + strings::acc_pedal_pos}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeSteeringWheelAngle, + strings::steering_wheel_angle}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeECallInfo, + strings::e_call_info}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeAirbagStatus, + strings::airbag_status}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeEmergencyEvent, + strings::emergency_event}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeClusterModeStatus, + strings::cluster_mode_status}, + {hmi_apis::FunctionID::VehicleInfo_SubscribeMyKey, strings::my_key}, +}; +} +#endif // #ifdef HMI_DBUS_API + +void SubscribeVehicleDataRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + std::string info; + mobile_apis::Result::eType result_code = mobile_apis::Result::INVALID_ENUM; + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + smart_objects::SmartObject response_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + bool result = false; + CheckVISubscriptions( + app, info, result_code, response_params, msg_params, result); + + if (mobile_apis::Result::INVALID_ENUM != result_code) { + SendResponse(result, + result_code, + info.empty() ? NULL : info.c_str(), + response_params.empty() ? NULL : &response_params); + return; + } + +#ifdef HMI_DBUS_API + // Generate list of subrequests + for (size_t i = 0; i < sizeof(subrequests) / sizeof(subrequests[0]); ++i) { + const Subrequest& sr = subrequests[i]; + if (true == (*message_)[strings::msg_params].keyExists(sr.str) && + true == (*message_)[strings::msg_params][sr.str].asBool()) { + HmiRequest hmi_request; + hmi_request.str = sr.str; + hmi_request.func_id = sr.func_id; + hmi_request.complete = false; + hmi_requests_.push_back(hmi_request); + } + } + LOG4CXX_DEBUG( + logger_, hmi_requests_.size() << " requests are going to be sent to HMI"); + + // Send subrequests + for (HmiRequests::const_iterator it = hmi_requests_.begin(); + it != hmi_requests_.end(); + ++it) + SendHMIRequest(it->func_id, &msg_params, true); +#else + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VehicleInfo); + SendHMIRequest(hmi_apis::FunctionID::VehicleInfo_SubscribeVehicleData, + &msg_params, + true); +#endif // #ifdef HMI_DBUS_API +} + +void SubscribeVehicleDataRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace helpers; + + const smart_objects::SmartObject& message = event.smart_object(); + + if (hmi_apis::FunctionID::VehicleInfo_SubscribeVehicleData != event.id()) { + LOG4CXX_ERROR(logger_, "Received unknown event."); + return; + } + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VehicleInfo); + ApplicationSharedPtr app = + application_manager_.application(CommandRequestImpl::connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer."); + return; + } + +#ifdef HMI_DBUS_API + for (HmiRequests::iterator it = hmi_requests_.begin(); + it != hmi_requests_.end(); + ++it) { + HmiRequest& hmi_request = *it; + if (hmi_request.func_id == event.id()) { + hmi_request.status = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + if (hmi_apis::Common_Result::SUCCESS == hmi_request.status) + hmi_request.value = message[strings::msg_params][hmi_request.str]; + hmi_request.complete = true; + break; + } + } + bool all_complete = true; + bool any_arg_success = false; + mobile_api::Result::eType status = mobile_api::Result::eType::SUCCESS; + for (HmiRequests::const_iterator it = hmi_requests_.begin(); + it != hmi_requests_.end(); + ++it) { + if (!it->complete) { + all_complete = false; + break; + } + if (hmi_apis::Common_Result::SUCCESS != it->status) { + if (mobile_api::Result::SUCCESS == status) { + status = static_cast<mobile_apis::Result::eType>(it->status); + } else if (status != + static_cast<mobile_apis::Result::eType>(it->status)) { + status = mobile_api::Result::eType::GENERIC_ERROR; + } + LOG4CXX_TRACE(logger_, + "Status from HMI: " << it->status + << ", so response status become " + << status); + } else { + any_arg_success = true; + } + } + + if (all_complete) { + smart_objects::SmartObject response_params(smart_objects::SmartType_Map); + if (any_arg_success) { + for (HmiRequests::const_iterator it = hmi_requests_.begin(); + it != hmi_requests_.end(); + ++it) { + response_params[it->str] = it->value; + } + } + LOG4CXX_DEBUG(logger_, "All HMI requests are complete"); + const bool result = any_arg_success; + SendResponse(any_arg_success, status, NULL, &response_params); + if (result) { + app->UpdateHash(); + } + } +#else + + hmi_apis::Common_Result::eType hmi_result = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + std::string response_info; + GetInfo(message, response_info); + const bool result = PrepareResultForMobileResponse( + hmi_result, HmiInterfaces::HMI_INTERFACE_VehicleInfo); + + bool is_succeeded = result || !vi_already_subscribed_by_another_apps_.empty(); + + mobile_apis::Result::eType result_code = + MessageHelper::HMIToMobileResult(hmi_result); + + if (is_succeeded) { + if (!vi_already_subscribed_by_this_app_.empty()) { + result_code = mobile_apis::Result::IGNORED; + response_info = "Already subscribed on some provided VehicleData."; + } + + if (!vi_waiting_for_subscribe_.empty()) { + LOG4CXX_DEBUG(logger_, "Subscribing to all pending VehicleData"); + VehicleInfoSubscriptions::const_iterator key = + vi_waiting_for_subscribe_.begin(); + for (; key != vi_waiting_for_subscribe_.end(); ++key) { + app->SubscribeToIVI(*key); + } + } + } + + UnsubscribeFailedSubscriptions(app, message[strings::msg_params]); + + if (!vi_already_subscribed_by_another_apps_.empty() || + !vi_already_subscribed_by_this_app_.empty()) { + AddAlreadySubscribedVI( + const_cast<smart_objects::SmartObject&>(message[strings::msg_params])); + } + + SendResponse(is_succeeded, + result_code, + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); +#endif // #ifdef HMI_DBUS_API +} + +bool SubscribeVehicleDataRequest::Init() { + hash_update_mode_ = HashUpdateMode::kDoHashUpdate; + return true; +} + +void SubscribeVehicleDataRequest::AddAlreadySubscribedVI( + smart_objects::SmartObject& msg_params) const { + LOG4CXX_AUTO_TRACE(logger_); + using namespace mobile_apis; + auto vi_to_string = + [](const mobile_apis::VehicleDataType::eType vehicle_data) { + for (auto& vi_str_to_int_pair : MessageHelper::vehicle_data()) { + if (vehicle_data == vi_str_to_int_pair.second) { + return vi_str_to_int_pair.first; + } + } + return std::string(); + }; + + VehicleInfoSubscriptions::const_iterator it_same_app = + vi_already_subscribed_by_this_app_.begin(); + for (; vi_already_subscribed_by_this_app_.end() != it_same_app; + ++it_same_app) { + msg_params[vi_to_string(*it_same_app)][strings::result_code] = + VehicleDataResultCode::VDRC_DATA_ALREADY_SUBSCRIBED; + msg_params[vi_to_string(*it_same_app)][strings::data_type] = *it_same_app; + } + + VehicleInfoSubscriptions::const_iterator it_another_app = + vi_already_subscribed_by_another_apps_.begin(); + for (; vi_already_subscribed_by_another_apps_.end() != it_another_app; + ++it_another_app) { + msg_params[vi_to_string(*it_another_app)][strings::result_code] = + VehicleDataResultCode::VDRC_SUCCESS; + msg_params[vi_to_string(*it_another_app)][strings::data_type] = + *it_another_app; + } +} + +void SubscribeVehicleDataRequest::UnsubscribeFailedSubscriptions( + ApplicationSharedPtr app, + const smart_objects::SmartObject& msg_params) const { + LOG4CXX_AUTO_TRACE(logger_); + const VehicleData& vehicle_data = MessageHelper::vehicle_data(); + VehicleData::const_iterator it = vehicle_data.begin(); + + for (; vehicle_data.end() != it; ++it) { + if (msg_params.keyExists(it->first)) { + if (msg_params[it->first][strings::result_code].asInt() != + hmi_apis::Common_VehicleDataResultCode::VDRC_SUCCESS) { + LOG4CXX_DEBUG(logger_, + "Subscription for VehicleDataType " + << it->first + << " is unsuccessfull. " + "Unsubscribing app with connection key " + << connection_key() << " from it."); + app->UnsubscribeFromIVI(it->second); + } + } + } +} + +struct SubscribedToIVIPredicate { + int32_t vehicle_info_; + SubscribedToIVIPredicate(int32_t vehicle_info) + : vehicle_info_(vehicle_info) {} + bool operator()(const ApplicationSharedPtr app) const { + return app ? app->IsSubscribedToIVI(vehicle_info_) : false; + } +}; + +bool SubscribeVehicleDataRequest::IsSomeoneSubscribedFor( + const uint32_t param_id) const { + LOG4CXX_AUTO_TRACE(logger_); + SubscribedToIVIPredicate finder(param_id); + DataAccessor<ApplicationSet> accessor = application_manager_.applications(); + ApplicationSetConstIt it = std::find_if( + accessor.GetData().begin(), accessor.GetData().end(), finder); + return it != accessor.GetData().end(); +} + +void SubscribeVehicleDataRequest::CheckVISubscribtions( + ApplicationSharedPtr app, + std::string& out_info, + mobile_apis::Result::eType& out_result_code, + smart_objects::SmartObject& out_response_params, + smart_objects::SmartObject& out_request_params, + bool& out_result) { + CheckVISubscriptions(app, + out_info, + out_result_code, + out_response_params, + out_request_params, + out_result); +} + +void SubscribeVehicleDataRequest::CheckVISubscriptions( + ApplicationSharedPtr app, + std::string& out_info, + mobile_apis::Result::eType& out_result_code, + smart_objects::SmartObject& out_response_params, + smart_objects::SmartObject& out_request_params, + bool& out_result) { + // counter for items to subscribe + VehicleInfoSubscriptions::size_type items_to_subscribe = 0; + // counter for subscribed items by application + uint32_t subscribed_items = 0; + + const VehicleData& vehicle_data = MessageHelper::vehicle_data(); + VehicleData::const_iterator it = vehicle_data.begin(); + + HmiInterfaces::InterfaceState interface_state = + application_manager_.hmi_interfaces().GetInterfaceState( + HmiInterfaces::HMI_INTERFACE_VehicleInfo); + + const bool is_interface_not_available = + interface_state == HmiInterfaces::STATE_NOT_AVAILABLE; + + for (; vehicle_data.end() != it; ++it) { + const std::string& key_name = it->first; + if ((*message_)[strings::msg_params].keyExists(key_name)) { + const bool is_key_enabled = + (*message_)[strings::msg_params][key_name].asBool(); + if (is_key_enabled) { + ++items_to_subscribe; + } + if (!is_interface_not_available && is_key_enabled) { + mobile_apis::VehicleDataType::eType key_type = it->second; + if (app->IsSubscribedToIVI(key_type)) { + LOG4CXX_DEBUG(logger_, + "App with connection key " + << connection_key() + << " is subscribed already for VehicleDataType: " + << key_type); + ++subscribed_items; + vi_already_subscribed_by_this_app_.insert(key_type); + out_response_params[key_name][strings::data_type] = key_type; + out_response_params[key_name][strings::result_code] = + mobile_apis::VehicleDataResultCode::VDRC_DATA_ALREADY_SUBSCRIBED; + continue; + } + + if (IsSomeoneSubscribedFor(key_type)) { + LOG4CXX_DEBUG(logger_, + "There are apps subscribed already for " + "VehicleDataType: " + << key_type); + if (!app->SubscribeToIVI(static_cast<uint32_t>(key_type))) { + LOG4CXX_ERROR( + logger_, + "Unable to subscribe for VehicleDataType: " << key_type); + continue; + } + LOG4CXX_DEBUG( + logger_, + "App with connection key " + << connection_key() + << " have been subscribed for VehicleDataType: " << key_type); + ++subscribed_items; + vi_already_subscribed_by_another_apps_.insert(key_type); + out_response_params[key_name][strings::data_type] = key_type; + out_response_params[key_name][strings::result_code] = + mobile_apis::VehicleDataResultCode::VDRC_SUCCESS; + continue; + } + + out_request_params[key_name] = is_key_enabled; + + if (is_key_enabled) { + vi_waiting_for_subscribe_.insert(key_type); + LOG4CXX_DEBUG( + logger_, + "App with connection key " + << connection_key() + << " will be subscribed for VehicleDataType: " << key_type); + ++subscribed_items; + } + } + } + } + + const bool is_everything_already_subscribed = + items_to_subscribe == + vi_already_subscribed_by_another_apps_.size() + + vi_already_subscribed_by_this_app_.size(); + + if (0 == items_to_subscribe) { + if (HasDisallowedParams()) { + out_result_code = mobile_apis::Result::DISALLOWED; + } else { + out_result_code = mobile_apis::Result::INVALID_DATA; + out_info = "No data in the request"; + } + out_result = false; + } + + if (0 == subscribed_items && !is_interface_not_available) { + out_result_code = mobile_apis::Result::IGNORED; + out_info = "Already subscribed on provided VehicleData."; + out_result = false; + } + + if (is_everything_already_subscribed) { + out_result_code = vi_already_subscribed_by_this_app_.size() + ? mobile_apis::Result::IGNORED + : mobile_apis::Result::SUCCESS; + if (!(vi_already_subscribed_by_this_app_.empty())) { + out_info = "Already subscribed on some provided VehicleData."; + } + out_result = true; + } +} + +} // namespace commands +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_vehicle_data_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_vehicle_data_response.cc new file mode 100644 index 0000000000..2f2ddc5acf --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_vehicle_data_response.cc @@ -0,0 +1,54 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/subscribe_vehicle_data_response.h" +#include "application_manager/rpc_service.h" +#include "application_manager/application_impl.h" +#include "interfaces/MOBILE_API.h" + +namespace application_manager { +namespace commands { + +SubscribeVehicleDataResponse::SubscribeVehicleDataResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +SubscribeVehicleDataResponse::~SubscribeVehicleDataResponse() {} + +void SubscribeVehicleDataResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_way_points_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_way_points_request.cc new file mode 100644 index 0000000000..8195697dfc --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_way_points_request.cc @@ -0,0 +1,82 @@ +#include "application_manager/application_manager.h" +#include "application_manager/commands/mobile/subscribe_way_points_request.h" +#include "application_manager/message_helper.h" + +namespace application_manager { + +namespace commands { + +SubscribeWayPointsRequest::SubscribeWayPointsRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +SubscribeWayPointsRequest::~SubscribeWayPointsRequest() {} + +void SubscribeWayPointsRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, + "An application with connection key " + << connection_key() << " is not registered."); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + if (application_manager_.IsAppSubscribedForWayPoints(app)) { + SendResponse(false, mobile_apis::Result::IGNORED); + return; + } + + if (application_manager_.IsAnyAppSubscribedForWayPoints()) { + application_manager_.SubscribeAppForWayPoints(app); + SendResponse(true, mobile_apis::Result::SUCCESS); + return; + } + + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_Navigation); + SendHMIRequest( + hmi_apis::FunctionID::Navigation_SubscribeWayPoints, NULL, true); +} + +void SubscribeWayPointsRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr app = application_manager_.application(connection_key()); + const smart_objects::SmartObject& message = event.smart_object(); + switch (event.id()) { + case hmi_apis::FunctionID::Navigation_SubscribeWayPoints: { + LOG4CXX_INFO(logger_, "Received Navigation_SubscribeWayPoints event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_Navigation); + const hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + std::string response_info; + GetInfo(message, response_info); + const bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_Navigation); + if (result) { + application_manager_.SubscribeAppForWayPoints(app); + } + SendResponse(result, + MessageHelper::HMIToMobileResult(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + break; + } + } +} + +bool SubscribeWayPointsRequest::Init() { + hash_update_mode_ = HashUpdateMode::kDoHashUpdate; + return true; +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_way_points_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_way_points_response.cc new file mode 100644 index 0000000000..8e1e203e52 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_way_points_response.cc @@ -0,0 +1,23 @@ +#include "application_manager/application_manager.h" +#include "application_manager/rpc_service.h" +#include "application_manager/commands/mobile/subscribe_way_points_response.h" + +namespace application_manager { + +namespace commands { + +SubscribeWayPointsResponse::SubscribeWayPointsResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +SubscribeWayPointsResponse::~SubscribeWayPointsResponse() {} + +void SubscribeWayPointsResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/system_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/system_request.cc new file mode 100644 index 0000000000..f0331d0ced --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/system_request.cc @@ -0,0 +1,690 @@ +/* + +Copyright (c) 2013, 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 "application_manager/commands/mobile/system_request.h" + +#include <vector> +#include <string> +#include <stdio.h> +#include <algorithm> +#include <sstream> +#include "application_manager/policies/policy_handler_interface.h" +#include "interfaces/MOBILE_API.h" +#include "utils/file_system.h" +#include "policy/policy_table/enums.h" +#include "formatters/CFormatterJsonBase.h" +#include "json/json.h" +#include "utils/helpers.h" +#include "utils/custom_string.h" + +namespace application_manager { + +CREATE_LOGGERPTR_LOCAL(logger_, "ApplicationManager") +namespace { + +#ifdef ENABLE_LOG +const char* kQueryAppsValidationFailedPrefix = + ":QUERY_APPS_VALIDATION_FAILED: "; +#endif + +const unsigned int kVrSynonymLengthMax = 40U; +const unsigned int kVrSynonymLengthMin = 1U; +const unsigned int kTtsNameLengthMax = 500U; +const unsigned int kVrArraySizeMax = 100U; +const unsigned int kVrArraySizeMin = 1U; +const unsigned int kUrlSchemaLengthMax = 255U; +const unsigned int kPackageNameLengthMax = 255U; +const unsigned int kAppIdLengthMax = 40U; +const unsigned int kAppNameLengthMax = 100U; +const unsigned int kLanguageArraySizeMax = 100U; + +class QueryAppsDataValidator { + public: + typedef std::set<std::string> SynonymsSet; + typedef std::map<std::string, SynonymsSet> SynonymsMap; + + QueryAppsDataValidator(smart_objects::SmartObject& object, + const ApplicationManager& manager) + : data_(object), manager_(manager) {} + + bool Validate() { + LOG4CXX_AUTO_TRACE(logger_); + if (!data_.isValid()) { + LOG4CXX_ERROR(logger_, + kQueryAppsValidationFailedPrefix + << "QueryApps response is not valid."); + return false; + } + if (!HasResponseKey()) { + return false; + } + return ValidateAppDataAndOsAndLanguagesData(); + } + + private: + bool HasResponseKey() const { + if (!data_.keyExists(json::response)) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "QueryApps response does not contain '" + << json::response << "' parameter."); + return false; + } + return true; + } + + bool ValidateAppDataAndOsAndLanguagesData() { + smart_objects::SmartArray* objects_array = data_[json::response].asArray(); + + if (!objects_array) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "QueryApps response is not array."); + return false; + } + + SynonymsMap synonyms_map; + bool has_response_valid_application = false; + + smart_objects::SmartArray::iterator applications_iterator = + objects_array->begin(); + + for (; applications_iterator != objects_array->end();) { + const smart_objects::SmartObject& app_data = *applications_iterator; + + if (!app_data.isValid()) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "Wrong application data in json file."); + return false; + } + + if (!CheckMandatoryParametersPresent(app_data)) { + LOG4CXX_WARN(logger_, + "Application hasn`t some of mandatory parameters. " + "Application will be skipped."); + + applications_iterator = objects_array->erase(applications_iterator); + continue; + } + + if (!ValidateAppIdAndAppName(app_data)) { + return false; + } + + // If we dont have any of android/ios field + // we skip this json in CheckMandatoryParametersPresent + const std::string os_type = + (app_data.keyExists(json::android)) ? json::android : json::ios; + + // Verify os and dependent languages data + if (json::ios == os_type) { + if (app_data[json::ios][json::urlScheme].asString().length() > + kUrlSchemaLengthMax) { + LOG4CXX_WARN( + logger_, + kQueryAppsValidationFailedPrefix + << "An urlscheme length exceeds maximum allowed [" + << app_data[json::ios][json::urlScheme].asString().length() + << "]>[" << kUrlSchemaLengthMax << "]"); + return false; + } + } + + if (json::android == os_type) { + if (app_data[json::android][json::packageName].asString().length() > + kPackageNameLengthMax) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "Package name length [" + << app_data[json::android][json::packageName] + .asString() + .length() << "] exceeds max length [" + << kPackageNameLengthMax << "]in json file."); + return false; + } + } + + // Languages verification + if (!app_data[os_type].keyExists(json::languages)) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "'languages' doesn't exist"); + return false; + } + if (!ValidateLanguages(app_data[os_type][json::languages], + synonyms_map)) { + return false; + } + has_response_valid_application = true; + ++applications_iterator; + } + return has_response_valid_application; + } + + bool ValidateAppIdAndAppName(const smart_objects::SmartObject& app_data) { + // Verify appid length + const std::string app_id(app_data[json::appId].asString()); + if (app_id.length() > kAppIdLengthMax) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "An Object ID length exceeds maximum allowed [" + << app_id.length() << "]>[" << kAppIdLengthMax << "]"); + return false; + } + + // Verify that appid is unique + if (applications_id_set_.find(app_id) != applications_id_set_.end()) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "An Object ID is not unigue [" << app_id << "]"); + return false; + } + applications_id_set_.insert(app_id); + + // Verify that app is not registered yet + ApplicationSharedPtr registered_app = + manager_.application_by_policy_id(app_id); + if (registered_app) { + LOG4CXX_INFO(logger_, + "Application with the id: " << app_id + << " is already registered."); + } + // And app name length + const std::string appName(app_data[json::name].asString()); + if (appName.length() > kAppNameLengthMax) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "Name of application exceeds maximum allowed [" + << appName.length() << "]>[" << kAppNameLengthMax + << "]."); + return false; + } + return true; + } + + bool ValidateLanguages(const smart_objects::SmartObject& languages, + SynonymsMap& synonyms_map) const { + bool default_language_found = false; + const size_t languages_array_size = languages.length(); + if (languages_array_size > kLanguageArraySizeMax) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "'languages' array exceeds max size [" + << languages_array_size << "]>[" << kLanguageArraySizeMax + << "]"); + return false; + } + // Every language has ttsname string and vrsynonyms array + for (size_t idx = 0; idx < languages_array_size; ++idx) { + const smart_objects::SmartObject& language = languages.getElement(idx); + if (smart_objects::SmartType_Map != language.getType()) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "language is not a map."); + return false; + } + if (language.length() != 1) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "language map size is not equal 1."); + return false; + } + const std::string language_name = (*language.map_begin()).first; + if (!language_name.length()) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "language name is empty"); + return false; + } + // Verify default language defined + if (!(language_name).compare(json::default_)) { + default_language_found = true; + } + // Add set for synonyms' duplicates validation + if (synonyms_map.find(language_name) == synonyms_map.end()) { + synonyms_map[language_name] = SynonymsSet(); + } + // ttsName verification + if (!language[language_name].keyExists(json::ttsName)) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "'languages.ttsName' doesn't exist"); + return false; + } + const smart_objects::SmartObject& ttsNameObject = + language[language_name][json::ttsName]; + // ttsName is string + if (smart_objects::SmartType_String == ttsNameObject.getType()) { + const std::string ttsName = + language[language_name][json::ttsName].asString(); + if (ttsName.length() > kTtsNameLengthMax) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "ttsName string exceeds max length [" + << ttsName.length() << "]>[" << kTtsNameLengthMax + << "]"); + return false; + } + } else { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "ttsName is not the string type."); + return false; + } + + if (!ValidateSynonymsAtLanguage(language, language_name, synonyms_map)) { + return false; + } + } + if (!default_language_found) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << " 'languages'.default' doesn't exist"); + return false; + } + return true; + } + + bool ValidateSynonymsAtLanguage(const smart_objects::SmartObject& language, + const std::string& language_name, + SynonymsMap& synonyms_map) const { + if (!language[language_name].keyExists(json::vrSynonyms)) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "'languages.vrSynonyms' doesn't exist"); + return false; + } + const smart_objects::SmartArray* synonyms_array = + language[language_name][json::vrSynonyms].asArray(); + if (!synonyms_array) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "vrSynonyms is not array."); + return false; + } + const size_t synonyms_array_size = synonyms_array->size(); + if (synonyms_array_size < kVrArraySizeMin) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "vrSynomyms array has [" << synonyms_array_size + << "] size < allowed min size [" << kVrArraySizeMin + << "]"); + return false; + } + if (synonyms_array_size > kVrArraySizeMax) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "vrSynomyms array size [" << synonyms_array_size + << "] exceeds maximum allowed size [" << kVrArraySizeMax + << "]"); + return false; + } + + for (std::size_t idx = 0; idx < synonyms_array_size; ++idx) { + const smart_objects::SmartObject& synonym = (*synonyms_array)[idx]; + const std::string vrSynonym = synonym.asString(); + if (vrSynonym.length() > kVrSynonymLengthMax) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "vrSYnomym item [" << idx + << "] exceeds max length [" << vrSynonym.length() + << "]>[" << kVrSynonymLengthMax << "]"); + return false; + } + if (vrSynonym.length() < kVrSynonymLengthMin) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "vrSYnomym item [" << idx << "] length [" + << vrSynonym.length() << "] is less then min length [" + << kVrSynonymLengthMin << "] allowed."); + return false; + } + // Verify duplicates + SynonymsMap::iterator synonyms_map_iter = + synonyms_map.find(language_name); + if (synonyms_map_iter != synonyms_map.end()) { + if (!(*synonyms_map_iter).second.insert(vrSynonym).second) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "vrSYnomym item already defined [" + << vrSynonym.c_str() << "] for language [" + << language_name << "]"); + return false; + } + } + } + return true; + } + + bool CheckMandatoryParametersPresent( + const smart_objects::SmartObject& app_data) const { + if (!app_data.keyExists(json::android) && !app_data.keyExists(json::ios)) { + return false; + } + + if (app_data.keyExists(json::android) && + !app_data[json::android].keyExists(json::packageName)) { + return false; + } + + if (app_data.keyExists(json::ios) && + !app_data[json::ios].keyExists(json::urlScheme)) { + return false; + } + + if (!app_data.keyExists(json::appId)) { + return false; + } + + if (!app_data.keyExists(json::name)) { + return false; + } + + return true; + } + + smart_objects::SmartObject& data_; + std::set<std::string> applications_id_set_; + const ApplicationManager& manager_; + + DISALLOW_COPY_AND_ASSIGN(QueryAppsDataValidator); +}; +} + +namespace commands { + +namespace custom_str = utils::custom_string; + +uint32_t SystemRequest::index = 0; + +const std::string kSYNC = "SYNC"; +const std::string kIVSU = "IVSU"; + +SystemRequest::SystemRequest(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +SystemRequest::~SystemRequest() {} + +void SystemRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + + if (!(application.valid())) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + const mobile_apis::RequestType::eType request_type = + static_cast<mobile_apis::RequestType::eType>( + (*message_)[strings::msg_params][strings::request_type].asInt()); + + const policy::PolicyHandlerInterface& policy_handler = + application_manager_.GetPolicyHandler(); + + const std::string stringified_request_type = + rpc::policy_table_interface_base::EnumToJsonString( + static_cast<rpc::policy_table_interface_base::RequestType>( + request_type)); + + if (!policy_handler.IsRequestTypeAllowed(application->policy_app_id(), + request_type)) { + LOG4CXX_ERROR(logger_, + "RequestType " << stringified_request_type + << " is DISALLOWED by policies"); + SendResponse(false, mobile_apis::Result::DISALLOWED); + return; + } + LOG4CXX_TRACE(logger_, + "RequestType " << stringified_request_type << " is ALLOWED"); + + const bool request_subtype_present = + (*message_)[strings::msg_params].keyExists(strings::request_subtype); + if (request_subtype_present) { + const std::string request_subtype = + (*message_)[strings::msg_params][strings::request_subtype].asString(); + if (!policy_handler.IsRequestSubTypeAllowed(application->policy_app_id(), + request_subtype)) { + LOG4CXX_ERROR(logger_, + "Request subtype: " << request_subtype + << " is DISALLOWED by policies"); + SendResponse(false, mobile_apis::Result::DISALLOWED); + return; + } + LOG4CXX_TRACE(logger_, + "Request subtype: " << request_subtype << " is ALLOWED"); + } + + std::string file_name = kSYNC; + if ((*message_)[strings::msg_params].keyExists(strings::file_name)) { + file_name = (*message_)[strings::msg_params][strings::file_name].asString(); + } + + if (!CheckSyntax(file_name)) { + LOG4CXX_ERROR(logger_, + "Incoming request contains \t\n \\t \\n or whitespace"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + if (!file_system::IsFileNameValid(file_name)) { + const std::string err_msg = "Sync file name contains forbidden symbols."; + LOG4CXX_ERROR(logger_, err_msg); + SendResponse(false, mobile_apis::Result::INVALID_DATA, err_msg.c_str()); + return; + } + + const bool is_system_file = std::string::npos != file_name.find(kSYNC) || + std::string::npos != file_name.find(kIVSU); + + // to avoid override existing file + if (is_system_file) { + const uint8_t max_size = 255; + char buf[max_size] = {'\0'}; + snprintf(buf, max_size - 1, "%d%s", index++, file_name.c_str()); + file_name = buf; + } + + std::vector<uint8_t> binary_data; + std::string binary_data_folder; + if ((*message_)[strings::params].keyExists(strings::binary_data)) { + binary_data = (*message_)[strings::params][strings::binary_data].asBinary(); + binary_data_folder = + application_manager_.get_settings().system_files_path(); + } else { + binary_data_folder = + application_manager_.get_settings().app_storage_folder(); + binary_data_folder += "/"; + binary_data_folder += application->folder_name(); + binary_data_folder += "/"; + } + + std::string file_dst_path = + application_manager_.get_settings().system_files_path(); + file_dst_path += "/"; + file_dst_path += file_name; + + if ((*message_)[strings::params].keyExists(strings::binary_data)) { + LOG4CXX_DEBUG( + logger_, + "Binary data is present. Trying to save it to: " << binary_data_folder); + if (mobile_apis::Result::SUCCESS != + (application_manager_.SaveBinary( + binary_data, binary_data_folder, file_name, 0))) { + LOG4CXX_DEBUG(logger_, "Binary data can't be saved."); + SendResponse(false, mobile_apis::Result::GENERIC_ERROR); + return; + } + } else { + std::string app_full_file_path = binary_data_folder; + app_full_file_path += file_name; + + LOG4CXX_DEBUG(logger_, + "Binary data is not present. Trying to find file " + << file_name << " within previously saved app file in " + << binary_data_folder); + + const AppFile* file = application->GetFile(app_full_file_path); + if (!file || !file->is_download_complete || + !file_system::MoveFile(app_full_file_path, file_dst_path)) { + LOG4CXX_DEBUG(logger_, "Binary data not found."); + SendResponse(false, mobile_apis::Result::REJECTED); + return; + } + processing_file_ = file_dst_path; + } + + LOG4CXX_DEBUG(logger_, "Binary data ok."); + + if (mobile_apis::RequestType::HTTP == request_type && + (*message_)[strings::msg_params].keyExists(strings::file_name)) { + const std::string& file = + (*message_)[strings::msg_params][strings::file_name].asString(); + application_manager_.GetPolicyHandler().ReceiveMessageFromSDK(file, + binary_data); + SendResponse(true, mobile_apis::Result::SUCCESS); + return; + } else if (mobile_apis::RequestType::QUERY_APPS == request_type) { + using namespace NsSmartDeviceLink::NsJSONHandler::Formatters; + + smart_objects::SmartObject sm_object; + Json::Reader reader; + std::string json(binary_data.begin(), binary_data.end()); + Json::Value root; + if (!reader.parse(json.c_str(), root)) { + LOG4CXX_DEBUG(logger_, "Unable to parse query_app json file."); + return; + } + + CFormatterJsonBase::jsonValueToObj(root, sm_object); + if (!ValidateQueryAppData(sm_object)) { + SendResponse(false, mobile_apis::Result::GENERIC_ERROR); + return; + } + + application_manager_.ProcessQueryApp(sm_object, connection_key()); + SendResponse(true, mobile_apis::Result::SUCCESS); + return; + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + if (std::string::npos != file_name.find(kIVSU)) { + msg_params[strings::file_name] = file_name; + } else { + msg_params[strings::file_name] = file_dst_path; + } + + // expected int, mandatory=true, all Policies flow (HTTP,Proprietary,External) + msg_params[strings::app_id] = application->hmi_app_id(); + + msg_params[strings::request_type] = + (*message_)[strings::msg_params][strings::request_type]; + if (request_subtype_present) { + msg_params[strings::request_subtype] = + (*message_)[strings::msg_params][strings::request_subtype]; + } + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_BasicCommunication); + SendHMIRequest(hmi_apis::FunctionID::BasicCommunication_SystemRequest, + &msg_params, + true); +} + +void SystemRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace helpers; + + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::BasicCommunication_SystemRequest: { + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_BasicCommunication); + mobile_apis::Result::eType result_code = + GetMobileResultCode(static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asUInt())); + + const bool result = Compare<mobile_api::Result::eType, EQ, ONE>( + result_code, + mobile_api::Result::SUCCESS, + mobile_api::Result::WARNINGS); + + ApplicationSharedPtr application = + application_manager_.application(connection_key()); + + if (!(application.valid())) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + return; + } + + if (!processing_file_.empty()) { + file_system::DeleteFile(processing_file_); + processing_file_.clear(); + } + + SendResponse(result, result_code, NULL, &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + return; + } + } +} + +bool SystemRequest::ValidateQueryAppData( + smart_objects::SmartObject& data) const { + if (!data.isValid()) { + LOG4CXX_ERROR(logger_, + kQueryAppsValidationFailedPrefix + << "QueryApps response is not valid."); + return false; + } + if (!data.keyExists(json::response)) { + LOG4CXX_ERROR(logger_, + kQueryAppsValidationFailedPrefix + << "QueryApps response does not contain '" + << json::response << "' parameter."); + return false; + } + + QueryAppsDataValidator validator(data, application_manager_); + return validator.Validate(); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/system_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/system_response.cc new file mode 100644 index 0000000000..0d994bb190 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/system_response.cc @@ -0,0 +1,55 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/system_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +SystemResponse::SystemResponse(const MessageSharedPtr& message, + ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +SystemResponse::~SystemResponse() {} + +void SystemResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unregister_app_interface_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unregister_app_interface_request.cc new file mode 100644 index 0000000000..08c3e228cb --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unregister_app_interface_request.cc @@ -0,0 +1,64 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/unregister_app_interface_request.h" +#include "application_manager/rpc_service.h" +#include "application_manager/message_helper.h" + +namespace application_manager { + +namespace commands { + +void UnregisterAppInterfaceRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + if (!application_manager_.application(connection_key())) { + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + LOG4CXX_ERROR(logger_, "Application is not registered"); + return; + } + + application_manager_.GetRPCService().ManageMobileCommand( + MessageHelper::GetOnAppInterfaceUnregisteredNotificationToMobile( + connection_key(), + mobile_api::AppInterfaceUnregisteredReason::INVALID_ENUM), + commands::Command::SOURCE_SDL); + application_manager_.EndNaviServices(connection_key()); + application_manager_.UnregisterApplication(connection_key(), + mobile_apis::Result::SUCCESS); + SendResponse(true, mobile_apis::Result::SUCCESS); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unregister_app_interface_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unregister_app_interface_response.cc new file mode 100644 index 0000000000..49d9276d35 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unregister_app_interface_response.cc @@ -0,0 +1,47 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/unregister_app_interface_response.h" + +namespace application_manager { + +namespace commands { + +void UnregisterAppInterfaceResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + SendResponse((*message_)[strings::msg_params][strings::success].asBool()); +} + +} // namespace commands +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_button_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_button_request.cc new file mode 100644 index 0000000000..7e798bcb4e --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_button_request.cc @@ -0,0 +1,103 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/unsubscribe_button_request.h" + +#include "application_manager/application_impl.h" + +namespace application_manager { + +namespace commands { + +namespace str = strings; + +UnsubscribeButtonRequest::UnsubscribeButtonRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +UnsubscribeButtonRequest::~UnsubscribeButtonRequest() {} + +void UnsubscribeButtonRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "APPLICATION_NOT_REGISTERED"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + const mobile_apis::ButtonName::eType btn_id = + static_cast<mobile_apis::ButtonName::eType>( + (*message_)[str::msg_params][str::button_name].asInt()); + + if (!CheckHMICapabilities(btn_id)) { + LOG4CXX_ERROR(logger_, + "Button " << btn_id << " isn't allowed by HMI capabilities"); + SendResponse(false, mobile_apis::Result::UNSUPPORTED_RESOURCE); + return; + } + + if (!app->UnsubscribeFromButton( + static_cast<mobile_apis::ButtonName::eType>(btn_id))) { + LOG4CXX_ERROR(logger_, "App doesn't subscibe to button " << btn_id); + SendResponse(false, mobile_apis::Result::IGNORED); + return; + } + + SendUnsubscribeButtonNotification(); + SendResponse(true, mobile_apis::Result::SUCCESS); +} + +bool UnsubscribeButtonRequest::Init() { + hash_update_mode_ = HashUpdateMode::kDoHashUpdate; + return true; +} + +void UnsubscribeButtonRequest::SendUnsubscribeButtonNotification() { + using namespace smart_objects; + using namespace hmi_apis; + + // send OnButtonSubscription notification + SmartObject msg_params = SmartObject(SmartType_Map); + msg_params[strings::app_id] = connection_key(); + msg_params[strings::name] = static_cast<Common_ButtonName::eType>( + (*message_)[strings::msg_params][strings::button_name].asInt()); + msg_params[strings::is_suscribed] = false; + CreateHMINotification(FunctionID::Buttons_OnButtonSubscription, msg_params); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_button_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_button_response.cc new file mode 100644 index 0000000000..9ac98a27f7 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_button_response.cc @@ -0,0 +1,65 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/unsubscribe_button_response.h" +#include "smart_objects/smart_object.h" + +namespace application_manager { + +namespace commands { + +UnsubscribeButtonResponse::UnsubscribeButtonResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +UnsubscribeButtonResponse::~UnsubscribeButtonResponse() {} + +void UnsubscribeButtonResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + // check if response false + if (true == (*message_)[strings::msg_params].keyExists(strings::success)) { + if ((*message_)[strings::msg_params][strings::success].asBool() == false) { + LOG4CXX_ERROR(logger_, "Success = false"); + SendResponse(false); + return; + } + } + + // TODO(DK): Some logic + SendResponse(true); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_vehicle_data_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_vehicle_data_request.cc new file mode 100644 index 0000000000..d6ad928bf7 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_vehicle_data_request.cc @@ -0,0 +1,407 @@ +/* + + Copyright (c) 2017, 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 "application_manager/commands/mobile/unsubscribe_vehicle_data_request.h" +#include "application_manager/commands/command_impl.h" + +#include "application_manager/application_impl.h" +#include "application_manager/message_helper.h" +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" +#include "application_manager/smart_object_keys.h" +#include "utils/helpers.h" + +namespace application_manager { +namespace commands { + +UnsubscribeVehicleDataRequest::UnsubscribeVehicleDataRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +UnsubscribeVehicleDataRequest::~UnsubscribeVehicleDataRequest() {} + +#ifdef HMI_DBUS_API +namespace { +struct Subrequest { + hmi_apis::FunctionID::eType func_id; + const char* str; +}; +Subrequest subrequests[] = { + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeGps, strings::gps}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeSpeed, strings::speed}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeRpm, strings::rpm}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeFuelLevel, + strings::fuel_level}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeFuelLevel_State, + strings::fuel_level_state}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeInstantFuelConsumption, + strings::instant_fuel_consumption}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeExternalTemperature, + strings::external_temp}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeVin, strings::vin}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribePrndl, strings::prndl}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeTirePressure, + strings::tire_pressure}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeOdometer, strings::odometer}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeBeltStatus, + strings::belt_status}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeBodyInformation, + strings::body_information}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeDeviceStatus, + strings::device_status}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeDriverBraking, + strings::driver_braking}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeWiperStatus, + strings::wiper_status}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeHeadLampStatus, + strings::head_lamp_status}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeEngineTorque, + strings::engine_torque}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeAccPedalPosition, + strings::acc_pedal_pos}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeSteeringWheelAngle, + strings::steering_wheel_angle}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeECallInfo, + strings::e_call_info}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeAirbagStatus, + strings::airbag_status}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeEmergencyEvent, + strings::emergency_event}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeClusterModeStatus, + strings::cluster_mode_status}, + {hmi_apis::FunctionID::VehicleInfo_UnsubscribeMyKey, strings::my_key}, +}; +} +#endif // #ifdef HMI_DBUS_API + +void UnsubscribeVehicleDataRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + int32_t items_to_unsubscribe = 0; + int32_t unsubscribed_items = 0; + + const VehicleData& vehicle_data = MessageHelper::vehicle_data(); + VehicleData::const_iterator it = vehicle_data.begin(); + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + smart_objects::SmartObject response_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + for (; vehicle_data.end() != it; ++it) { + const std::string& key_name = it->first; + if ((*message_)[strings::msg_params].keyExists(key_name)) { + bool is_key_enabled = (*message_)[strings::msg_params][key_name].asBool(); + if (is_key_enabled) { + ++items_to_unsubscribe; + + mobile_apis::VehicleDataType::eType key_type = it->second; + if (!app->IsSubscribedToIVI(key_type)) { + ++unsubscribed_items; + vi_already_unsubscribed_by_this_app_.insert(key_type); + response_params[key_name][strings::data_type] = key_type; + response_params[key_name][strings::result_code] = + mobile_apis::VehicleDataResultCode::VDRC_DATA_NOT_SUBSCRIBED; + continue; + } + + if (!app->UnsubscribeFromIVI(static_cast<uint32_t>(key_type))) { + LOG4CXX_ERROR(logger_, + "Unable to unsubscribe from " + "VehicleDataType: " + << key_type); + continue; + } + + LOG4CXX_DEBUG(logger_, + "Unsubscribed app with connection key " + << connection_key() + << " from VehicleDataType: " << key_type); + + ++unsubscribed_items; + + if (IsSomeoneSubscribedFor(key_type)) { + LOG4CXX_DEBUG(logger_, + "There are another apps still subscribed for " + "VehicleDataType: " + << key_type); + + vi_still_subscribed_by_another_apps_.insert(key_type); + response_params[key_name][strings::data_type] = key_type; + response_params[key_name][strings::result_code] = + mobile_apis::VehicleDataResultCode::VDRC_SUCCESS; + continue; + } + + msg_params[key_name] = is_key_enabled; + } + } + } + + bool is_everything_already_unsubscribed = + static_cast<uint32_t>(items_to_unsubscribe) == + vi_still_subscribed_by_another_apps_.size() + + vi_already_unsubscribed_by_this_app_.size(); + + if (0 == items_to_unsubscribe) { + if (HasDisallowedParams()) { + SendResponse(false, mobile_apis::Result::DISALLOWED); + } else { + SendResponse( + false, mobile_apis::Result::INVALID_DATA, "No data in the request."); + } + return; + } + + if (0 == unsubscribed_items) { + SendResponse(false, + mobile_apis::Result::IGNORED, + "Was not subscribed on any VehicleData.", + &response_params); + return; + } + + if (is_everything_already_unsubscribed) { + if (!vi_already_unsubscribed_by_this_app_.empty()) { + SendResponse(false, + mobile_apis::Result::IGNORED, + "Some provided VehicleData was not subscribed.", + &response_params); + } else { + SendResponse(true, mobile_apis::Result::SUCCESS, NULL, &response_params); + } + return; + } + +#ifdef HMI_DBUS_API + // Generate list of subrequests + for (size_t i = 0; i < sizeof(subrequests) / sizeof(subrequests[0]); ++i) { + const Subrequest& sr = subrequests[i]; + if (true == (*message_)[strings::msg_params].keyExists(sr.str) && + true == (*message_)[strings::msg_params][sr.str].asBool()) { + HmiRequest hmi_request; + hmi_request.str = sr.str; + hmi_request.func_id = sr.func_id; + hmi_request.complete = false; + hmi_requests_.push_back(hmi_request); + } + } + LOG4CXX_INFO(logger_, + hmi_requests_.size() << " requests are going to be sent to HMI"); + + // Send subrequests + for (HmiRequests::const_iterator it = hmi_requests_.begin(); + it != hmi_requests_.end(); + ++it) + SendHMIRequest(it->func_id, &msg_params, true); +#else + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VehicleInfo); + SendHMIRequest(hmi_apis::FunctionID::VehicleInfo_UnsubscribeVehicleData, + &msg_params, + true); +#endif // #ifdef HMI_DBUS_API +} + +void UnsubscribeVehicleDataRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace helpers; + + const smart_objects::SmartObject& message = event.smart_object(); + + if (hmi_apis::FunctionID::VehicleInfo_UnsubscribeVehicleData != event.id()) { + LOG4CXX_ERROR(logger_, "Received unknown event."); + return; + } + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_VehicleInfo); + + ApplicationSharedPtr app = + application_manager_.application(CommandRequestImpl::connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer."); + return; + } + +#ifdef HMI_DBUS_API + for (HmiRequests::iterator it = hmi_requests_.begin(); + it != hmi_requests_.end(); + ++it) { + HmiRequest& hmi_request = *it; + if (hmi_request.func_id == event.id()) { + hmi_request.status = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + if (hmi_apis::Common_Result::SUCCESS == hmi_request.status) + hmi_request.value = message[strings::msg_params][hmi_request.str]; + hmi_request.complete = true; + break; + } + } + bool all_complete = true; + bool any_arg_success = false; + mobile_api::Result::eType status = mobile_api::Result::eType::SUCCESS; + for (HmiRequests::const_iterator it = hmi_requests_.begin(); + it != hmi_requests_.end(); + ++it) { + if (!it->complete) { + all_complete = false; + break; + } + if (hmi_apis::Common_Result::SUCCESS != it->status) { + if (mobile_api::Result::SUCCESS == status) { + status = static_cast<mobile_apis::Result::eType>(it->status); + } else if (status != + static_cast<mobile_apis::Result::eType>(it->status)) { + status = mobile_api::Result::eType::GENERIC_ERROR; + } + LOG4CXX_TRACE(logger_, + "Status from HMI: " << it->status + << ", so response status become " + << status); + } else { + any_arg_success = true; + } + } + if (all_complete) { + smart_objects::SmartObject response_params(smart_objects::SmartType_Map); + if (any_arg_success) { + for (HmiRequests::const_iterator it = hmi_requests_.begin(); + it != hmi_requests_.end(); + ++it) { + response_params[it->str] = it->value; + } + } + + LOG4CXX_INFO(logger_, "All HMI requests are complete"); + if (true == any_arg_success) { + SetAllowedToTerminate(false); + } + SendResponse(any_arg_success, status, NULL, &response_params); + if (true == any_arg_success) { + app->UpdateHash(); + } + } +#else + hmi_apis::Common_Result::eType hmi_result = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + std::string response_info; + GetInfo(message, response_info); + const bool result = PrepareResultForMobileResponse( + hmi_result, HmiInterfaces::HMI_INTERFACE_VehicleInfo); + + mobile_apis::Result::eType result_code = + MessageHelper::HMIToMobileResult(hmi_result); + + if (result) { + if (vi_already_unsubscribed_by_this_app_.size()) { + result_code = mobile_apis::Result::IGNORED; + response_info = "Some provided VehicleData was not subscribed."; + } + } + + if (!vi_still_subscribed_by_another_apps_.empty() || + !vi_already_unsubscribed_by_this_app_.empty()) { + AddAlreadyUnsubscribedVI( + const_cast<smart_objects::SmartObject&>(message[strings::msg_params])); + } + + if (result) { + SetAllowedToTerminate(false); + } + SendResponse(result, + result_code, + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + if (result) { + application_manager_.TerminateRequest( + connection_key(), correlation_id(), function_id()); + } +#endif // #ifdef HMI_DBUS_API +} + +bool UnsubscribeVehicleDataRequest::Init() { + hash_update_mode_ = HashUpdateMode::kDoHashUpdate; + return true; +} + +struct SubscribedToIVIPredicate { + int32_t vehicle_info_; + SubscribedToIVIPredicate(int32_t vehicle_info) + : vehicle_info_(vehicle_info) {} + bool operator()(const ApplicationSharedPtr app) const { + return app ? app->IsSubscribedToIVI(vehicle_info_) : false; + } +}; + +bool UnsubscribeVehicleDataRequest::IsSomeoneSubscribedFor( + const uint32_t param_id) const { + LOG4CXX_AUTO_TRACE(logger_); + SubscribedToIVIPredicate finder(param_id); + DataAccessor<ApplicationSet> accessor = application_manager_.applications(); + ApplicationSetConstIt it = std::find_if( + accessor.GetData().begin(), accessor.GetData().end(), finder); + return it != accessor.GetData().end(); +} + +void UnsubscribeVehicleDataRequest::AddAlreadyUnsubscribedVI( + smart_objects::SmartObject& response) const { + LOG4CXX_AUTO_TRACE(logger_); + using namespace mobile_apis; + VehicleInfoSubscriptions::const_iterator it_same_app = + vi_already_unsubscribed_by_this_app_.begin(); + for (; vi_already_unsubscribed_by_this_app_.end() != it_same_app; + ++it_same_app) { + response[*it_same_app][strings::result_code] = + VehicleDataResultCode::VDRC_DATA_NOT_SUBSCRIBED; + } + + VehicleInfoSubscriptions::const_iterator it_another_app = + vi_still_subscribed_by_another_apps_.begin(); + for (; vi_still_subscribed_by_another_apps_.end() != it_another_app; + ++it_another_app) { + response[*it_another_app][strings::result_code] = + VehicleDataResultCode::VDRC_SUCCESS; + } +} + +} // namespace commands +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_vehicle_data_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_vehicle_data_response.cc new file mode 100644 index 0000000000..986256d377 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_vehicle_data_response.cc @@ -0,0 +1,63 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/unsubscribe_vehicle_data_response.h" +#include "smart_objects/smart_object.h" + +namespace application_manager { +namespace commands { + +UnsubscribeVehicleDataResponse::UnsubscribeVehicleDataResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +UnsubscribeVehicleDataResponse::~UnsubscribeVehicleDataResponse() {} + +void UnsubscribeVehicleDataResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + // check if response false + if (true == (*message_)[strings::msg_params].keyExists(strings::success)) { + if ((*message_)[strings::msg_params][strings::success].asBool() == false) { + LOG4CXX_ERROR(logger_, "Success = false"); + SendResponse(false); + return; + } + } + + // TODO(DK): Some logic + SendResponse(true); +} + +} // namespace commands +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_way_points_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_way_points_request.cc new file mode 100644 index 0000000000..dc3404c022 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_way_points_request.cc @@ -0,0 +1,76 @@ +#include "application_manager/application_manager.h" +#include "application_manager/commands/mobile/unsubscribe_way_points_request.h" +#include "application_manager/message_helper.h" + +namespace application_manager { + +namespace commands { + +UnSubscribeWayPointsRequest::UnSubscribeWayPointsRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +UnSubscribeWayPointsRequest::~UnSubscribeWayPointsRequest() {} + +void UnSubscribeWayPointsRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, + "An application with connection key " + << connection_key() << " is not registered."); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + if (!application_manager_.IsAppSubscribedForWayPoints(app)) { + SendResponse(false, mobile_apis::Result::IGNORED); + return; + } + + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_Navigation); + SendHMIRequest( + hmi_apis::FunctionID::Navigation_UnsubscribeWayPoints, NULL, true); +} + +void UnSubscribeWayPointsRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr app = application_manager_.application(connection_key()); + const smart_objects::SmartObject& message = event.smart_object(); + switch (event.id()) { + case hmi_apis::FunctionID::Navigation_UnsubscribeWayPoints: { + LOG4CXX_INFO(logger_, "Received Navigation_UnSubscribeWayPoints event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_Navigation); + const hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + std::string response_info; + GetInfo(message, response_info); + const bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_Navigation); + if (result) { + application_manager_.UnsubscribeAppFromWayPoints(app); + } + SendResponse(result, + MessageHelper::HMIToMobileResult(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + break; + } + } +} + +bool UnSubscribeWayPointsRequest::Init() { + hash_update_mode_ = HashUpdateMode::kDoHashUpdate; + return true; +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_way_points_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_way_points_response.cc new file mode 100644 index 0000000000..843a2fd5f0 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_way_points_response.cc @@ -0,0 +1,23 @@ +#include "application_manager/application_manager.h" +#include "application_manager/commands/mobile/unsubscribe_way_points_response.h" +#include "application_manager/rpc_service.h" + +namespace application_manager { + +namespace commands { + +UnsubscribeWayPointsResponse::UnsubscribeWayPointsResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +UnsubscribeWayPointsResponse::~UnsubscribeWayPointsResponse() {} + +void UnsubscribeWayPointsResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/update_turn_list_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/update_turn_list_request.cc new file mode 100644 index 0000000000..44fe9d0d07 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/update_turn_list_request.cc @@ -0,0 +1,234 @@ +/* + + Copyright (c) 2013, 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 <string> +#include "application_manager/commands/mobile/update_turn_list_request.h" + +#include "application_manager/policies/policy_handler.h" +#include "application_manager/application_impl.h" +#include "application_manager/message_helper.h" +#include "interfaces/MOBILE_API.h" +#include "interfaces/HMI_API.h" +#include "utils/custom_string.h" + +namespace application_manager { + +namespace commands { + +namespace custom_str = utils::custom_string; + +UpdateTurnListRequest::UpdateTurnListRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandRequestImpl(message, application_manager) {} + +UpdateTurnListRequest::~UpdateTurnListRequest() {} + +void UpdateTurnListRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationSharedPtr app = application_manager_.application( + (*message_)[strings::params][strings::connection_key].asUInt()); + + if (!app) { + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + LOG4CXX_ERROR(logger_, "Application is not registered"); + return; + } + + if (IsWhiteSpaceExist()) { + LOG4CXX_ERROR(logger_, + "Incoming update turn list has contains \t\n \\t \\n"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + // ProcessSoftButtons checks strings on the contents incorrect character + + mobile_apis::Result::eType processing_result = + MessageHelper::ProcessSoftButtons((*message_)[strings::msg_params], + app, + application_manager_.GetPolicyHandler(), + application_manager_); + + if (mobile_apis::Result::SUCCESS != processing_result) { + LOG4CXX_ERROR(logger_, "INVALID_DATA!"); + SendResponse(false, processing_result); + return; + } + + if ((*message_)[strings::msg_params].keyExists(strings::turn_list)) { + smart_objects::SmartObject& turn_list_array = + ((*message_)[strings::msg_params][strings::turn_list]); + for (uint32_t i = 0; i < turn_list_array.length(); ++i) { + if ((turn_list_array[i].keyExists(strings::turn_icon)) && + (mobile_apis::Result::SUCCESS != + MessageHelper::VerifyImage(turn_list_array[i][strings::turn_icon], + app, + application_manager_))) { + LOG4CXX_ERROR(logger_, + "MessageHelper::VerifyImage return INVALID_DATA"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + } + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_params = (*message_)[strings::msg_params]; + + if ((*message_)[strings::msg_params].keyExists(strings::turn_list)) { + if (!CheckTurnListArray()) { + LOG4CXX_ERROR(logger_, "INVALID_DATA!"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + return; + } + + for (uint32_t i = 0; i < msg_params[strings::turn_list].length(); ++i) { + if (msg_params[strings::turn_list][i].keyExists(hmi_request::navi_text)) { + const custom_str::CustomString& navigation_text = + msg_params[strings::turn_list][i][hmi_request::navi_text] + .asCustomString(); + msg_params[strings::turn_list][i].erase(hmi_request::navi_text); + msg_params[strings::turn_list][i][hmi_request::navi_text] + [hmi_request::field_name] = static_cast<int>( + hmi_apis::Common_TextFieldName::turnText); + msg_params[strings::turn_list][i][hmi_request::navi_text] + [hmi_request::field_text] = navigation_text; + } + } + } + + msg_params[strings::app_id] = app->app_id(); + + if ((*message_)[strings::msg_params].keyExists(strings::soft_buttons)) { + MessageHelper::SubscribeApplicationToSoftButton( + (*message_)[strings::msg_params], app, function_id()); + } + + if ((*message_)[strings::msg_params].keyExists(strings::turn_list) || + (*message_)[strings::msg_params].keyExists(strings::soft_buttons)) { + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_Navigation); + SendHMIRequest( + hmi_apis::FunctionID::Navigation_UpdateTurnList, &msg_params, true); + } else { + // conditional mandatory + LOG4CXX_ERROR(logger_, "INVALID_DATA!"); + SendResponse(false, mobile_apis::Result::INVALID_DATA); + } +} + +void UpdateTurnListRequest::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + + switch (event.id()) { + case hmi_apis::FunctionID::Navigation_UpdateTurnList: { + LOG4CXX_INFO(logger_, "Received Navigation_UpdateTurnList event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_Navigation); + const hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + std::string response_info; + GetInfo(message, response_info); + const bool result = PrepareResultForMobileResponse( + result_code, HmiInterfaces::HMI_INTERFACE_Navigation); + SendResponse(result, + MessageHelper::HMIToMobileResult(result_code), + response_info.empty() ? NULL : response_info.c_str(), + &(message[strings::msg_params])); + break; + } + default: { + LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); + break; + } + } +} + +bool UpdateTurnListRequest::CheckTurnListArray() { + int32_t length = + (*message_)[strings::msg_params][strings::turn_list].length(); + if (0 == length) { + return false; + } + + for (int32_t i = 0; i < length; ++i) { + if (!((*message_)[strings::msg_params][strings::turn_list][i].keyExists( + hmi_request::navi_text)) && + !((*message_)[strings::msg_params][strings::turn_list][i].keyExists( + strings::turn_icon))) { + return false; + } + } + return true; +} + +bool UpdateTurnListRequest::IsWhiteSpaceExist() { + LOG4CXX_AUTO_TRACE(logger_); + const char* str = NULL; + + if ((*message_)[strings::msg_params].keyExists(strings::turn_list)) { + const smart_objects::SmartArray* tl_array = + (*message_)[strings::msg_params][strings::turn_list].asArray(); + + smart_objects::SmartArray::const_iterator it_tl = tl_array->begin(); + smart_objects::SmartArray::const_iterator it_tl_end = tl_array->end(); + + for (; it_tl != it_tl_end; ++it_tl) { + if ((*it_tl).keyExists(strings::navigation_text)) { + str = (*it_tl)[strings::navigation_text].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR( + logger_, + "Invalid turn_list navigation_text text syntax check failed"); + return true; + } + } + + if ((*it_tl).keyExists(strings::turn_icon)) { + str = (*it_tl)[strings::turn_icon][strings::value].asCharArray(); + if (!CheckSyntax(str)) { + LOG4CXX_ERROR( + logger_, "Invalid turn_list turn_icon value syntax check failed"); + return true; + } + } + } + } + return false; +} + +} // namespace commands + +} // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/update_turn_list_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/update_turn_list_response.cc new file mode 100644 index 0000000000..ca5e8c1b34 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/update_turn_list_response.cc @@ -0,0 +1,56 @@ +/* + + Copyright (c) 2013, 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 "application_manager/commands/mobile/update_turn_list_response.h" +#include "application_manager/rpc_service.h" +#include "interfaces/HMI_API.h" + +namespace application_manager { + +namespace commands { + +UpdateTurnListResponse::UpdateTurnListResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : CommandResponseImpl(message, application_manager) {} + +UpdateTurnListResponse::~UpdateTurnListResponse() {} + +void UpdateTurnListResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands + +} // namespace application_manager |