summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kutsan (GitHub) <akutsan@luxoft.com>2020-08-21 18:30:02 +0300
committerGitHub <noreply@github.com>2020-08-21 11:30:02 -0400
commit2bfbdcea6c70219c66eb422fe98bdeda559ff335 (patch)
tree62ce75afc06bea3451dbe7a2757f858e5a933c20
parent71d659da53a230ea352901974ec0adb3711c3ee2 (diff)
downloadsdl_core-2bfbdcea6c70219c66eb422fe98bdeda559ff335.tar.gz
[SDL 0273] WebEngine Projection mode (#3457)
* Temporary commit. Changes rpc_spec submodule reference. NOTE: should be removed before merge * Update Mobile API for the new App HMI type WEB_VIEW * Update HMI API for the new App HMI type WEB_VIEW * Add app registration support of the hmi type WEB_VIEW * Update Unit tests related to app registration Add the new one case to check app registration with AppHMItype WEB_VIEW Update existing Application Manager UTs with the new methods for WEB_VIEW Update Application Mock * Add Unit tests for RAI request test * Implement HMI states management for WEP apps * Add new application exit reason RESOURCE_CONSTRAINT Add RESOURCE_CONSTRAINT to HMI API and its processing to OnExitApplicationNotification, update unit tests * Add web socket connection closing on RESOURCE_CONSTRAINT * Update ProtocolHandlerImpl::OnTMMessageSendFailed * Add Unit test for OnAppInterfaceUnregistedNotification * Remove redundant code * Add WEP media & nonmedia to general test cases * Move function to iface class to allow its testing * Add WEP media/nonmedia apps registration for HMI state checks Added unit test cases for WEP media and non-media applications, which allow to check HMI Level, system context, audio and video streaming states calculation after the following actions: - Initial HMI state after registration - HMI state after app activaion - HMI State after app deactivation - HMI state after app exit Note: HMI state includes HMI level, audio, video streaming state, system context * Make code more clear & easy for debug * Add test case for WEP app in resuming mode * Add missed logging * Close connection after RESOURCE_CONSTRAINT RESOURCE_CONSTRAINT unregister reason will close connection for all applications, but not only Web engine projection * Refactoring no functional changes Use setters instead of direct access to app_hmi_type bool var * Use PolicyHandler::CheckHMIType to avoid code duplication * Update src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc Co-authored-by: JackLivio <jack@livio.io> * Use log to check if web engine is allowed * fixup! Use log to check if web engine is allowed * Revert "fixup! Use log to check if web engine is allowed" This reverts commit baad4aae5ffdeba5502a533b2eeb18de84d92b05. * Revert "Use log to check if web engine is allowed" This reverts commit 94c6a7d9efc6912777834bb5aca22c7b46d43497. * Revert "Update src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc" This reverts commit 3296fcc399588f01624c1a27f64ab8bc9176e197. * Revert "Use PolicyHandler::CheckHMIType to avoid code duplication" This reverts commit 2c695099a63b838915cb9b5c91c46ad7fc013b47. * Use log string to check if WEB engine is not allowed * Update submodules Co-authored-by: Igor Gapchuk <igapchuck@luxoft.com> Co-authored-by: sniukalov <sniukaov@luxoft.com> Co-authored-by: Andriy Byzhynar (GitHub) <AByzhynar@luxoft.com> Co-authored-by: Mykhailo Vorobiov (GitHub) <61186891+mvorobio@users.noreply.github.com> Co-authored-by: Your Name <you@example.com> Co-authored-by: JackLivio <jack@livio.io> Co-authored-by: YarikMamykin <ymamykin@gmail.com> Co-authored-by: Andrii Kalinich <AKalinich@luxoft.com>
-rw-r--r--src/components/application_manager/include/application_manager/application.h3
-rw-r--r--src/components/application_manager/include/application_manager/application_impl.h11
-rw-r--r--src/components/application_manager/include/application_manager/commands/command_notification_impl.h9
-rw-r--r--src/components/application_manager/include/application_manager/state_controller_impl.h9
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/on_app_interface_unregistered_notification.h6
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h24
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_exit_application_notification.cc8
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_app_interface_unregistered_notification.cc10
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc130
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/hmi_notifications_test.cc25
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/on_app_interface_unregistered_notification_test.cc140
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/register_app_interface_request_test.cc328
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/simple_notification_commands_test.cc4
-rw-r--r--src/components/application_manager/src/application_impl.cc67
-rw-r--r--src/components/application_manager/src/commands/command_notification_impl.cc8
-rw-r--r--src/components/application_manager/src/state_controller_impl.cc30
-rw-r--r--src/components/application_manager/test/application_impl_test.cc74
-rw-r--r--src/components/application_manager/test/application_manager_impl_test.cc205
-rw-r--r--src/components/application_manager/test/include/application_manager/mock_application.h2
-rw-r--r--src/components/application_manager/test/state_controller/state_controller_test.cc270
-rw-r--r--src/components/connection_handler/src/connection_handler_impl.cc1
-rw-r--r--src/components/include/application_manager/state_controller.h9
-rw-r--r--src/components/include/test/application_manager/mock_state_controller.h3
-rw-r--r--src/components/interfaces/HMI_API.xml4
-rw-r--r--src/components/protocol_handler/src/protocol_handler_impl.cc20
-rw-r--r--src/components/transport_manager/include/transport_manager/websocket_server/websocket_connection.h14
-rw-r--r--src/components/transport_manager/include/transport_manager/websocket_server/websocket_secure_session.h4
-rw-r--r--src/components/transport_manager/include/transport_manager/websocket_server/websocket_session.h20
-rw-r--r--src/components/transport_manager/src/cloud/websocket_client_connection.cc1
-rw-r--r--src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc14
-rw-r--r--src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc5
-rw-r--r--src/components/transport_manager/src/transport_manager_impl.cc21
-rw-r--r--src/components/transport_manager/src/websocket_server/websocket_connection.cc68
-rw-r--r--src/components/transport_manager/src/websocket_server/websocket_secure_session.cc10
-rw-r--r--src/components/transport_manager/src/websocket_server/websocket_session.cc22
-rw-r--r--src/components/transport_manager/test/transport_manager_impl_test.cc8
m---------tools/rpc_spec0
37 files changed, 1351 insertions, 236 deletions
diff --git a/src/components/application_manager/include/application_manager/application.h b/src/components/application_manager/include/application_manager/application.h
index a595fc7379..082bb10ce3 100644
--- a/src/components/application_manager/include/application_manager/application.h
+++ b/src/components/application_manager/include/application_manager/application.h
@@ -610,6 +610,9 @@ class Application : public virtual InitialApplicationData,
virtual void set_mobile_projection_enabled(bool option) = 0;
virtual bool mobile_projection_enabled() const = 0;
+ virtual void set_webengine_projection_enabled(const bool option) = 0;
+ virtual bool webengine_projection_enabled() const = 0;
+
virtual bool video_streaming_approved() const = 0;
virtual void set_video_streaming_approved(bool state) = 0;
virtual bool audio_streaming_approved() const = 0;
diff --git a/src/components/application_manager/include/application_manager/application_impl.h b/src/components/application_manager/include/application_manager/application_impl.h
index 185d700d58..1e24addf4a 100644
--- a/src/components/application_manager/include/application_manager/application_impl.h
+++ b/src/components/application_manager/include/application_manager/application_impl.h
@@ -113,7 +113,7 @@ class ApplicationImpl : public virtual Application,
inline bool is_navi() const {
return is_navi_;
}
- void set_is_navi(bool allow);
+ void set_is_navi(bool option);
virtual bool is_remote_control_supported() const;
@@ -123,6 +123,9 @@ class ApplicationImpl : public virtual Application,
bool mobile_projection_enabled() const;
+ void set_webengine_projection_enabled(const bool option) OVERRIDE;
+ bool webengine_projection_enabled() const OVERRIDE;
+
bool video_streaming_approved() const;
void set_video_streaming_approved(bool state);
bool audio_streaming_approved() const;
@@ -143,8 +146,7 @@ class ApplicationImpl : public virtual Application,
uint32_t timer_len = 0);
virtual bool is_voice_communication_supported() const;
- virtual void set_voice_communication_supported(
- bool is_voice_communication_supported);
+ virtual void set_voice_communication_supported(bool option);
inline bool app_allowed() const;
bool has_been_activated() const;
bool set_activated(bool is_active);
@@ -184,7 +186,7 @@ class ApplicationImpl : public virtual Application,
bool keep_context();
void set_version(const Version& ver);
void set_name(const custom_str::CustomString& name);
- void set_is_media_application(bool is_media);
+ void set_is_media_application(bool option);
void increment_put_file_in_none_count();
void increment_delete_file_in_none_count();
void increment_list_files_in_none_count();
@@ -565,6 +567,7 @@ class ApplicationImpl : public virtual Application,
bool is_navi_;
bool is_remote_control_supported_;
bool mobile_projection_enabled_;
+ bool webengine_projection_enabled_;
bool video_streaming_approved_;
bool audio_streaming_approved_;
diff --git a/src/components/application_manager/include/application_manager/commands/command_notification_impl.h b/src/components/application_manager/include/application_manager/commands/command_notification_impl.h
index 2274bc5f3b..2f6db37eb8 100644
--- a/src/components/application_manager/include/application_manager/commands/command_notification_impl.h
+++ b/src/components/application_manager/include/application_manager/commands/command_notification_impl.h
@@ -51,7 +51,14 @@ class CommandNotificationImpl : public CommandImpl {
virtual bool Init();
virtual bool CleanUp();
virtual void Run();
- void SendNotification();
+
+ /**
+ * @brief SendNotification Constructs the message with Message Type
+ * Notification and send it to mobile.
+ * @param final_message if true - connection to mobile will be closed
+ * after processing this message
+ */
+ void SendNotification(const bool final_message = false);
private:
DISALLOW_COPY_AND_ASSIGN(CommandNotificationImpl);
diff --git a/src/components/application_manager/include/application_manager/state_controller_impl.h b/src/components/application_manager/include/application_manager/state_controller_impl.h
index c6121f5d1d..04851d66ab 100644
--- a/src/components/application_manager/include/application_manager/state_controller_impl.h
+++ b/src/components/application_manager/include/application_manager/state_controller_impl.h
@@ -125,6 +125,8 @@ class StateControllerImpl : public event_engine::EventObserver,
void ActivateDefaultWindow(ApplicationSharedPtr app) OVERRIDE;
void ExitDefaultWindow(ApplicationSharedPtr app) OVERRIDE;
+ void DeactivateApp(ApplicationSharedPtr app,
+ const WindowID window_id) OVERRIDE;
private:
int64_t RequestHMIStateChange(ApplicationConstSharedPtr app,
@@ -274,13 +276,6 @@ class StateControllerImpl : public event_engine::EventObserver,
void TempStateStopped(HmiState::StateID ID);
/**
- * @brief Sets BACKGROUND or LIMITED hmi level to application
- * depends on application type
- * @param app Application to deactivate
- */
- void DeactivateApp(ApplicationSharedPtr app, const WindowID window_id);
-
- /**
* Function to remove temporary HmiState for application
*/
template <HmiState::StateID ID>
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/on_app_interface_unregistered_notification.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/on_app_interface_unregistered_notification.h
index 28508d386c..3f61631948 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/on_app_interface_unregistered_notification.h
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/on_app_interface_unregistered_notification.h
@@ -71,6 +71,12 @@ class OnAppInterfaceUnregisteredNotification
virtual void Run();
private:
+ /**
+ * @brief Check whether a connection to mobile must be closed after sending
+ * this message
+ **/
+ bool IsFinalMessage() const;
+
DISALLOW_COPY_AND_ASSIGN(OnAppInterfaceUnregisteredNotification);
};
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h
index d59964bbc7..07c32ea5af 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h
@@ -236,6 +236,30 @@ class RegisterAppInterfaceRequest
connection_handler::DeviceHandle* device_id = nullptr,
std::string* mac_address = nullptr) const;
+ /**
+ * @brief Processes AppHMITypes in the received message from mobile and in the
+ * policy table
+ * @param message A message from mobile that could contain AppHMIType
+ * collection
+ * @param app_hmi_types_in_policy AppHMITypes that describes in the policy
+ * table for the app that sent the message
+ * @return Result of processing
+ */
+ mobile_apis::Result::eType ProcessingAppHMITypesPolicies(
+ smart_objects::SmartObject& message,
+ policy::StringArray& app_hmi_types_in_policy);
+
+ /**
+ * @brief Processes AppHMITypes in the received message
+ * @param message A message received from the mobile
+ * @param info Info in a string representation that should be added to the
+ * response info
+ * @param log A log in a string represenation that could contain the
+ * AppHMITypes that are absent in the policy table.
+ */
+ mobile_apis::Result::eType ProcessingAppHMITypesInMessage(
+ const smart_objects::SmartObject& message);
+
private:
std::string response_info_;
mobile_apis::Result::eType result_code_;
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_exit_application_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_exit_application_notification.cc
index 3eec6c5d1a..34365c12e5 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_exit_application_notification.cc
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_exit_application_notification.cc
@@ -112,6 +112,14 @@ void OnExitApplicationNotification::Run() {
break;
}
#endif // CLOUD_APP_WEBSOCKET_TRANSPORT_SUPPORT
+ case Common_ApplicationExitReason::RESOURCE_CONSTRAINT: {
+ const auto message =
+ MessageHelper::GetOnAppInterfaceUnregisteredNotificationToMobile(
+ app_id, AppInterfaceUnregisteredReason::RESOURCE_CONSTRAINT);
+ SendNotificationToMobile(message);
+ application_manager_.UnregisterApplication(app_id, Result::SUCCESS);
+ return;
+ }
default: {
LOG4CXX_WARN(logger_, "Unhandled reason");
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
index 5714043a51..30d9853d97 100644
--- 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
@@ -57,7 +57,15 @@ OnAppInterfaceUnregisteredNotification::
void OnAppInterfaceUnregisteredNotification::Run() {
LOG4CXX_AUTO_TRACE(logger_);
- SendNotification();
+ const bool final_message = IsFinalMessage();
+ SendNotification(final_message);
+}
+
+bool OnAppInterfaceUnregisteredNotification::IsFinalMessage() const {
+ using Reason = mobile_apis::AppInterfaceUnregisteredReason::eType;
+ const auto reason = static_cast<Reason>(
+ (*message_)[strings::msg_params][strings::reason].asInt());
+ return Reason::RESOURCE_CONSTRAINT == reason;
}
} // namespace commands
} // namespace sdl_rpc_plugin
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
index 70bd47e232..bd36f060ed 100644
--- 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
@@ -81,6 +81,8 @@ mobile_apis::AppHMIType::eType StringToAppHMIType(const std::string& str) {
return mobile_apis::AppHMIType::PROJECTION;
} else if ("REMOTE_CONTROL" == str) {
return mobile_apis::AppHMIType::REMOTE_CONTROL;
+ } else if ("WEB_VIEW" == str) {
+ return mobile_apis::AppHMIType::WEB_VIEW;
} else {
return mobile_apis::AppHMIType::INVALID_ENUM;
}
@@ -99,7 +101,8 @@ std::string AppHMITypeToString(mobile_apis::AppHMIType::eType type) {
{mobile_apis::AppHMIType::BACKGROUND_PROCESS, "BACKGROUND_PROCESS"},
{mobile_apis::AppHMIType::TESTING, "TESTING"},
{mobile_apis::AppHMIType::SYSTEM, "SYSTEM"},
- {mobile_apis::AppHMIType::PROJECTION, "PROJECTION"}};
+ {mobile_apis::AppHMIType::PROJECTION, "PROJECTION"},
+ {mobile_apis::AppHMIType::WEB_VIEW, "WEB_VIEW"}};
std::map<mobile_apis::AppHMIType::eType, std::string>::const_iterator iter =
app_hmi_type_map.find(type);
@@ -293,7 +296,7 @@ void RegisterAppInterfaceRequest::Run() {
policy_result,
mobile_apis::Result::SUCCESS,
mobile_apis::Result::WARNINGS)) {
- SendResponse(false, policy_result);
+ SendResponse(false, policy_result, response_info_.c_str());
return;
}
@@ -481,6 +484,10 @@ void RegisterAppInterfaceRequest::Run() {
application->set_remote_control_supported(true);
break;
}
+ case mobile_apis::AppHMIType::WEB_VIEW: {
+ application->set_webengine_projection_enabled(true);
+ break;
+ }
default: {}
}
}
@@ -1140,14 +1147,14 @@ mobile_apis::Result::eType RegisterAppInterfaceRequest::CheckWithPolicyData() {
return mobile_apis::Result::WARNINGS;
}
- smart_objects::SmartObject& message = *message_;
+ auto& message = *message_;
policy::StringArray app_nicknames;
- policy::StringArray app_hmi_types;
+ policy::StringArray app_hmi_types_in_policy;
const std::string mobile_app_id =
application_manager_.GetCorrectMobileIDFromMessage(message_);
const bool init_result = GetPolicyHandler().GetInitialAppData(
- mobile_app_id, &app_nicknames, &app_hmi_types);
+ mobile_app_id, &app_nicknames, &app_hmi_types_in_policy);
if (!init_result) {
LOG4CXX_ERROR(logger_, "Error during initial application data check.");
@@ -1173,36 +1180,20 @@ mobile_apis::Result::eType RegisterAppInterfaceRequest::CheckWithPolicyData() {
}
}
- mobile_apis::Result::eType result = mobile_apis::Result::SUCCESS;
+ auto 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;
- }
+ if (!app_hmi_types_in_policy.empty()) {
+ result = ProcessingAppHMITypesPolicies(message, app_hmi_types_in_policy);
+ } else {
+ result = ProcessingAppHMITypesInMessage(message);
+ if (mobile_apis::Result::DISALLOWED == result) {
+ response_info_ =
+ "WEB_VIEW AppHmiType is absent in application policies, because they "
+ "are empty";
+ LOG4CXX_DEBUG(logger_, response_info_);
+ return result;
}
- // 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;
@@ -1540,6 +1531,81 @@ bool RegisterAppInterfaceRequest::GetDataOnSessionKey(
return true;
}
+mobile_apis::Result::eType
+RegisterAppInterfaceRequest::ProcessingAppHMITypesInMessage(
+ const smart_objects::SmartObject& message) {
+ const bool app_hmi_types_exist =
+ message[strings::msg_params].keyExists(strings::app_hmi_type);
+
+ const auto result = mobile_apis::Result::SUCCESS;
+
+ if (!app_hmi_types_exist) {
+ return result;
+ }
+
+ auto app_types_in_message =
+ *(message[strings::msg_params][strings::app_hmi_type].asArray());
+
+ auto it = std::find(app_types_in_message.begin(),
+ app_types_in_message.end(),
+ mobile_apis::AppHMIType::WEB_VIEW);
+ if (app_types_in_message.end() != it) {
+ return mobile_apis::Result::DISALLOWED;
+ }
+
+ return result;
+}
+
+mobile_apis::Result::eType
+RegisterAppInterfaceRequest::ProcessingAppHMITypesPolicies(
+ smart_objects::SmartObject& message,
+ policy::StringArray& app_hmi_types_in_policy) {
+ auto result = mobile_apis::Result::SUCCESS;
+ const bool app_hmi_types_exist =
+ message[strings::msg_params].keyExists(strings::app_hmi_type);
+
+ if (app_hmi_types_exist) {
+ // If AppHmiTypes are partially same, the system should allow those listed
+ // in the policy table and send warning info on missed values
+ auto app_types_in_message =
+ *(message[strings::msg_params][strings::app_hmi_type].asArray());
+
+ std::string log;
+ CheckMissedTypes checker(app_hmi_types_in_policy, log);
+ std::for_each(
+ app_types_in_message.begin(), app_types_in_message.end(), checker);
+ if (!log.empty()) {
+ result = log.find("WEB_VIEW") != std::string::npos
+ ? mobile_apis::Result::DISALLOWED
+ : mobile_apis::Result::WARNINGS;
+
+ if (mobile_apis::Result::DISALLOWED == result) {
+ response_info_ =
+ "WEB_VIEW AppHmiType is absent in application policies";
+ LOG4CXX_DEBUG(logger_, response_info_);
+ return result;
+ }
+
+ 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);
+
+ auto& app_hmi_type = message[strings::msg_params][strings::app_hmi_type];
+
+ AppHMITypeInserter inserter(app_hmi_type);
+ std::for_each(
+ app_hmi_types_in_policy.begin(), app_hmi_types_in_policy.end(), inserter);
+
+ return result;
+}
+
policy::PolicyHandlerInterface&
RegisterAppInterfaceRequest::GetPolicyHandler() {
return policy_handler_;
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/hmi_notifications_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/hmi_notifications_test.cc
index cbb27bffb2..634f0d0ef2 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/hmi_notifications_test.cc
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/hmi_notifications_test.cc
@@ -257,6 +257,8 @@ class HMICommandsNotificationsTest
ON_CALL(app_mngr_, application(kConnectionKey)).WillByDefault(Return(app_));
ON_CALL(mock_message_helper_, MobileLanguageToString(kMobileLanguage))
.WillByDefault(Return(kDefaultLanguage));
+ ON_CALL(app_mngr_, connection_handler())
+ .WillByDefault(ReturnRef(mock_connection_handler_));
}
am::ApplicationSharedPtr ConfigureApp(NiceMock<MockApplication>** app_mock,
@@ -1025,18 +1027,17 @@ TEST_F(HMICommandsNotificationsTest,
static_cast<int32_t>(am::MessageType::kNotification);
(*notification)[am::strings::params][am::strings::connection_key] = kAppId_;
- std::vector<hmi_apis::Common_ApplicationExitReason::eType> reason_list;
- reason_list.push_back(hmi_apis::Common_ApplicationExitReason::
- UNAUTHORIZED_TRANSPORT_REGISTRATION);
- reason_list.push_back(
- hmi_apis::Common_ApplicationExitReason::UNSUPPORTED_HMI_RESOURCE);
-
- std::vector<mobile_apis::AppInterfaceUnregisteredReason::eType>
- mobile_reason_list;
- mobile_reason_list.push_back(
- mobile_apis::AppInterfaceUnregisteredReason::APP_UNAUTHORIZED);
- mobile_reason_list.push_back(
- mobile_apis::AppInterfaceUnregisteredReason::UNSUPPORTED_HMI_RESOURCE);
+ using ExitReason = hmi_apis::Common_ApplicationExitReason::eType;
+ std::vector<ExitReason> reason_list = {
+ ExitReason::UNAUTHORIZED_TRANSPORT_REGISTRATION,
+ ExitReason::UNSUPPORTED_HMI_RESOURCE,
+ ExitReason::RESOURCE_CONSTRAINT};
+
+ using UnregisteredReason = mobile_apis::AppInterfaceUnregisteredReason::eType;
+ std::vector<UnregisteredReason> mobile_reason_list = {
+ UnregisteredReason::APP_UNAUTHORIZED,
+ UnregisteredReason::UNSUPPORTED_HMI_RESOURCE,
+ UnregisteredReason::RESOURCE_CONSTRAINT};
std::vector<mobile_apis::AppInterfaceUnregisteredReason::eType>::iterator
it_mobile_reason = mobile_reason_list.begin();
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/on_app_interface_unregistered_notification_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/on_app_interface_unregistered_notification_test.cc
new file mode 100644
index 0000000000..64dcec2e0a
--- /dev/null
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/on_app_interface_unregistered_notification_test.cc
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2020, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "mobile/on_app_interface_unregistered_notification.h"
+
+#include <utility>
+
+#include "gtest/gtest.h"
+
+#include "application_manager/commands/commands_test.h"
+#include "application_manager/smart_object_keys.h"
+#include "interfaces/MOBILE_API.h"
+#include "smart_objects/smart_object.h"
+
+namespace test {
+namespace components {
+namespace commands_test {
+namespace mobile_commands_test {
+namespace on_app_interface_unregistered_notification_test {
+
+namespace am = ::application_manager;
+
+using sdl_rpc_plugin::commands::OnAppInterfaceUnregisteredNotification;
+using Reason = mobile_apis::AppInterfaceUnregisteredReason::eType;
+using ::testing::Return;
+
+namespace {
+const uint32_t kAppId = 1u;
+typedef std::shared_ptr<MockApplication> MockAppPtr;
+} // namespace
+
+const auto retrieve_data_to_check = [](const smart_objects::SmartObject& so) {
+ return std::make_pair(
+ so[am::strings::params][am::strings::connection_key].asUInt(),
+ so[am::strings::msg_params][am::strings::reason].asInt());
+};
+
+MATCHER_P(CheckMessageData, initial_data, "") {
+ return retrieve_data_to_check(*arg) == initial_data;
+}
+
+class OnAppInterfaceUnregisteredNotificationTest
+ : public CommandsTest<CommandsTestMocks::kIsNice> {
+ public:
+ OnAppInterfaceUnregisteredNotificationTest()
+ : message_(CreateMessage()), command_(), mock_app_(CreateMockApp()) {
+ (*message_)[am::strings::params][am::strings::connection_key] = kAppId;
+ ON_CALL(app_mngr_, application(kAppId)).WillByDefault(Return(mock_app_));
+ CommandsTest<CommandsTestMocks::kIsNice>::InitCommand(kDefaultTimeout_);
+ command_.reset(
+ new OnAppInterfaceUnregisteredNotification(message_,
+ app_mngr_,
+ mock_rpc_service_,
+ mock_hmi_capabilities_,
+ mock_policy_handler_));
+ }
+
+ void CheckResponseParameters(const bool is_wep_mode_enabled,
+ const bool is_final_message) {
+ ON_CALL(*mock_app_, webengine_projection_enabled())
+ .WillByDefault(Return(is_wep_mode_enabled));
+
+ const auto initial_data = retrieve_data_to_check(*message_);
+ EXPECT_CALL(
+ mock_rpc_service_,
+ SendMessageToMobile(CheckMessageData(initial_data), is_final_message));
+ }
+
+ am::commands::MessageSharedPtr message_;
+ std::unique_ptr<OnAppInterfaceUnregisteredNotification> command_;
+ MockAppPtr mock_app_;
+};
+
+TEST_F(OnAppInterfaceUnregisteredNotificationTest,
+ Run_AnyReasonButResourceConstraint_NonFinalMessageSent) {
+ (*message_)[am::strings::msg_params][am::strings::reason] =
+ Reason::IGNITION_OFF;
+
+ CheckResponseParameters(true, false);
+
+ ASSERT_TRUE(command_->Init());
+ command_->Run();
+}
+
+TEST_F(OnAppInterfaceUnregisteredNotificationTest,
+ Run_ResourceConstraintForNonWebApp_NonFinalMessageSent) {
+ (*message_)[am::strings::msg_params][am::strings::reason] =
+ Reason::RESOURCE_CONSTRAINT;
+
+ CheckResponseParameters(false, true);
+
+ ASSERT_TRUE(command_->Init());
+ command_->Run();
+}
+
+TEST_F(OnAppInterfaceUnregisteredNotificationTest,
+ Run_ResourceConstraintForWebApp_FinalMessageSent) {
+ (*message_)[am::strings::msg_params][am::strings::reason] =
+ Reason::RESOURCE_CONSTRAINT;
+
+ CheckResponseParameters(true, true);
+
+ ASSERT_TRUE(command_->Init());
+ command_->Run();
+}
+
+} // namespace on_app_interface_unregistered_notification_test
+} // namespace mobile_commands_test
+} // namespace commands_test
+} // namespace components
+} // namespace test
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/register_app_interface_request_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/register_app_interface_request_test.cc
index a42aa61400..1be3243cc2 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/register_app_interface_request_test.cc
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/register_app_interface_request_test.cc
@@ -93,6 +93,7 @@ const std::string kFullAppId = "test_app_id_long";
const std::string kDummyString = "test_string";
const std::vector<uint32_t> kDummyDiagModes;
const utils::SemanticVersion mock_semantic_version(1, 0, 0);
+const connection_handler::DeviceHandle kHandle = 1;
} // namespace
class RegisterAppInterfaceRequestTest
@@ -107,7 +108,8 @@ class RegisterAppInterfaceRequestTest
, pending_lock_ptr_(std::make_shared<sync_primitives::Lock>())
, mock_application_helper_(
application_manager_test::MockApplicationHelper::
- application_helper_mock()) {
+ application_helper_mock())
+ , notify_upd_manager_(std::make_shared<utils::CallNothing>()) {
InitGetters();
InitLanguage();
}
@@ -285,6 +287,51 @@ class RegisterAppInterfaceRequestTest
mock_app)));
}
+ void SetCommonPreconditionsToRegisterApplication() {
+ ON_CALL(app_mngr_, IsApplicationForbidden(_, _))
+ .WillByDefault(Return(false));
+ ON_CALL(mock_connection_handler_,
+ GetDataOnSessionKey(kConnectionKey, _, _, _))
+ .WillByDefault(DoAll(SetArgPointee<3>(kDeviceHandle), Return(0)));
+ ON_CALL(mock_session_observer_,
+ GetDataOnDeviceID(kDeviceHandle, _, _, _, _))
+ .WillByDefault(DoAll(SetArgPointee<3>(kMacAddress1), Return(0)));
+ ON_CALL(app_mngr_, reregister_application_by_policy_id(kAppId1))
+ .WillByDefault(Return(ApplicationSharedPtr()));
+ ON_CALL(app_mngr_, application(kMacAddress1, kAppId1))
+ .WillByDefault(Return(ApplicationSharedPtr()));
+ ON_CALL(app_mngr_, applications())
+ .WillByDefault(
+ Return(DataAccessor<am::ApplicationSet>(app_set_, lock_ptr_)));
+ ON_CALL(app_mngr_, pending_applications())
+ .WillByDefault(Return(DataAccessor<am::AppsWaitRegistrationSet>(
+ pending_app_set_, pending_lock_ptr_)));
+ ON_CALL(mock_policy_handler_, PolicyEnabled()).WillByDefault(Return(true));
+ ON_CALL(mock_policy_handler_, GetInitialAppData(kAppId1, _, _))
+ .WillByDefault(Return(true));
+ ON_CALL(mock_rpc_service_,
+ ManageHMICommand(
+ HMIResultCodeIs(
+ hmi_apis::FunctionID::BasicCommunication_OnAppRegistered),
+ _))
+ .WillByDefault(Return(true));
+ ON_CALL(
+ mock_rpc_service_,
+ ManageHMICommand(
+ HMIResultCodeIs(hmi_apis::FunctionID::Buttons_OnButtonSubscription),
+ _))
+ .WillByDefault(Return(true));
+ }
+
+ void SetCommonPreconditionsToCheckWithPolicyData(MockAppPtr mock_app) {
+ ON_CALL(mock_policy_handler_, AddApplication(kMacAddress1, kAppId1, _))
+ .WillByDefault(Return(notify_upd_manager_));
+ ON_CALL(app_mngr_, application(kConnectionKey))
+ .WillByDefault(Return(mock_app));
+ ON_CALL(app_mngr_, RegisterApplication(msg_))
+ .WillByDefault(Return(mock_app));
+ }
+
MessageSharedPtr msg_;
std::shared_ptr<RegisterAppInterfaceRequest> command_;
@@ -314,6 +361,7 @@ class RegisterAppInterfaceRequestTest
MockConnectionHandler mock_connection_handler_;
MockSessionObserver mock_session_observer_;
application_manager_test::MockApplicationHelper& mock_application_helper_;
+ policy::StatusNotifier notify_upd_manager_;
};
TEST_F(RegisterAppInterfaceRequestTest, Init_SUCCESS) {
@@ -331,11 +379,10 @@ TEST_F(RegisterAppInterfaceRequestTest, Run_MinimalData_SUCCESS) {
EXPECT_CALL(app_mngr_, updateRequestTimeout(_, _, _));
EXPECT_CALL(app_mngr_, IsApplicationForbidden(_, _)).WillOnce(Return(false));
- connection_handler::DeviceHandle handle = 1;
ON_CALL(mock_connection_handler_,
GetDataOnSessionKey(kConnectionKey, _, _, _))
- .WillByDefault(DoAll(SetArgPointee<3>(handle), Return(0)));
- ON_CALL(mock_session_observer_, GetDataOnDeviceID(handle, _, _, _, _))
+ .WillByDefault(DoAll(SetArgPointee<3>(kHandle), Return(0)));
+ ON_CALL(mock_session_observer_, GetDataOnDeviceID(kHandle, _, _, _, _))
.WillByDefault(DoAll(SetArgPointee<3>(kMacAddress1), Return(0)));
MockAppPtr mock_app = CreateBasicMockedApp();
@@ -357,10 +404,8 @@ TEST_F(RegisterAppInterfaceRequestTest, Run_MinimalData_SUCCESS) {
ON_CALL(mock_policy_handler_, PolicyEnabled()).WillByDefault(Return(true));
ON_CALL(mock_policy_handler_, GetInitialAppData(kAppId1, _, _))
.WillByDefault(Return(true));
- policy::StatusNotifier notify_upd_manager =
- std::make_shared<utils::CallNothing>();
ON_CALL(mock_policy_handler_, AddApplication(kMacAddress1, kAppId1, _))
- .WillByDefault(Return(notify_upd_manager));
+ .WillByDefault(Return(notify_upd_manager_));
EXPECT_CALL(app_mngr_, RegisterApplication(msg_)).WillOnce(Return(mock_app));
@@ -418,10 +463,9 @@ TEST_F(RegisterAppInterfaceRequestTest,
EXPECT_CALL(app_mngr_, updateRequestTimeout(_, _, _));
EXPECT_CALL(app_mngr_, IsApplicationForbidden(_, _)).WillOnce(Return(false));
- connection_handler::DeviceHandle handle = 1;
ON_CALL(mock_connection_handler_,
GetDataOnSessionKey(kConnectionKey, _, _, _))
- .WillByDefault(DoAll(SetArgPointee<3>(handle), Return(0)));
+ .WillByDefault(DoAll(SetArgPointee<3>(kHandle), Return(0)));
ON_CALL(mock_session_observer_, GetDataOnDeviceID(_, _, _, _, _))
.WillByDefault(DoAll(SetArgPointee<3>(kMacAddress1), Return(0)));
@@ -480,10 +524,8 @@ TEST_F(RegisterAppInterfaceRequestTest,
ON_CALL(mock_policy_handler_, PolicyEnabled()).WillByDefault(Return(true));
ON_CALL(mock_policy_handler_, GetInitialAppData(kAppId1, _, _))
.WillByDefault(Return(true));
- policy::StatusNotifier notify_upd_manager =
- std::make_shared<utils::CallNothing>();
ON_CALL(mock_policy_handler_, AddApplication(kMacAddress1, kAppId1, _))
- .WillByDefault(Return(notify_upd_manager));
+ .WillByDefault(Return(notify_upd_manager_));
EXPECT_CALL(app_mngr_, RegisterApplication(msg_)).WillOnce(Return(mock_app));
@@ -745,10 +787,8 @@ TEST_F(RegisterAppInterfaceRequestTest,
ON_CALL(mock_policy_handler_, PolicyEnabled()).WillByDefault(Return(true));
ON_CALL(mock_policy_handler_, GetInitialAppData(kAppId1, _, _))
.WillByDefault(Return(true));
- policy::StatusNotifier notify_upd_manager =
- std::make_shared<utils::CallNothing>();
ON_CALL(mock_policy_handler_, AddApplication(kMacAddress2, kAppId1, _))
- .WillByDefault(Return(notify_upd_manager));
+ .WillByDefault(Return(notify_upd_manager_));
EXPECT_CALL(app_mngr_, RegisterApplication(msg_)).WillOnce(Return(mock_app2));
@@ -791,6 +831,264 @@ TEST_F(RegisterAppInterfaceRequestTest,
command_->Run();
}
+TEST_F(RegisterAppInterfaceRequestTest,
+ RegisterAppWith_WEB_VIEW_HMITypeSuccess) {
+ SetCommonPreconditionsToRegisterApplication();
+
+ InitBasicMessage();
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][0] =
+ mobile_apis::AppHMIType::WEB_VIEW;
+
+ MockAppPtr mock_app = CreateBasicMockedApp();
+ SetCommonPreconditionsToCheckWithPolicyData(mock_app);
+ std::vector<std::string> present_hmi_types_in_policy{"WEB_VIEW"};
+ ON_CALL(mock_policy_handler_, GetInitialAppData(kAppId1, _, _))
+ .WillByDefault(
+ DoAll(SetArgPointee<2>(present_hmi_types_in_policy), Return(true)));
+
+ auto app = std::static_pointer_cast<am::Application>(mock_app);
+
+ EXPECT_CALL(*mock_app, set_webengine_projection_enabled(true));
+ EXPECT_CALL(app_mngr_, OnApplicationRegistered(app));
+ EXPECT_CALL(mock_policy_handler_,
+ OnAppRegisteredOnMobile(kMacAddress1, kAppId1));
+ EXPECT_CALL(mock_rpc_service_,
+ ManageMobileCommand(_, am::commands::Command::SOURCE_SDL))
+ .Times(2);
+ EXPECT_CALL(app_mngr_, SendDriverDistractionState(app));
+
+ ASSERT_TRUE(command_->Init());
+ command_->Run();
+}
+
+TEST_F(RegisterAppInterfaceRequestTest,
+ RegisterApp_WithoutAppHMITypes_SuccessfulRegistration) {
+ SetCommonPreconditionsToRegisterApplication();
+ InitBasicMessage();
+
+ MockAppPtr mock_app = CreateBasicMockedApp();
+ SetCommonPreconditionsToCheckWithPolicyData(mock_app);
+ std::vector<std::string> present_hmi_types_in_policy{"NAVIGATION"};
+ ON_CALL(mock_policy_handler_, GetInitialAppData(kAppId1, _, _))
+ .WillByDefault(
+ DoAll(SetArgPointee<2>(present_hmi_types_in_policy), Return(true)));
+
+ auto response_to_mobile = CreateMessage();
+ EXPECT_CALL(
+ mock_rpc_service_,
+ ManageMobileCommand(_, am::commands::Command::CommandSource::SOURCE_SDL))
+ .WillOnce(DoAll(SaveArg<0>(&response_to_mobile), Return(true)))
+ .WillOnce(Return(true));
+
+ ASSERT_TRUE(command_->Init());
+ command_->Run();
+
+ const auto result_code = static_cast<mobile_apis::Result::eType>(
+ (*response_to_mobile)[am::strings::msg_params][am::strings::result_code]
+ .asUInt());
+
+ EXPECT_EQ(mobile_apis::Result::SUCCESS, result_code);
+}
+
+TEST_F(
+ RegisterAppInterfaceRequestTest,
+ RegisterAppInterface_AppHMITypesDontExistInPTForSpecifiedApp_SuccessfulRegistration) {
+ SetCommonPreconditionsToRegisterApplication();
+ InitBasicMessage();
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][0] =
+ mobile_apis::AppHMIType::PROJECTION;
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][1] =
+ mobile_apis::AppHMIType::INFORMATION;
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][2] =
+ mobile_apis::AppHMIType::COMMUNICATION;
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][3] =
+ mobile_apis::AppHMIType::NAVIGATION;
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][4] =
+ mobile_apis::AppHMIType::MESSAGING;
+
+ MockAppPtr mock_app = CreateBasicMockedApp();
+ SetCommonPreconditionsToCheckWithPolicyData(mock_app);
+ std::vector<std::string> present_hmi_types_in_policy;
+ ON_CALL(mock_policy_handler_, GetInitialAppData(kAppId1, _, _))
+ .WillByDefault(
+ DoAll(SetArgPointee<2>(present_hmi_types_in_policy), Return(true)));
+
+ auto response_to_mobile = CreateMessage();
+ EXPECT_CALL(
+ mock_rpc_service_,
+ ManageMobileCommand(_, am::commands::Command::CommandSource::SOURCE_SDL))
+ .WillOnce(DoAll(SaveArg<0>(&response_to_mobile), Return(true)))
+ .WillOnce(Return(true));
+
+ ASSERT_TRUE(command_->Init());
+ command_->Run();
+
+ const auto result_code = static_cast<mobile_apis::Result::eType>(
+ (*response_to_mobile)[am::strings::msg_params][am::strings::result_code]
+ .asUInt());
+ EXPECT_EQ(mobile_apis::Result::SUCCESS, result_code);
+}
+
+TEST_F(
+ RegisterAppInterfaceRequestTest,
+ RegisterApp_AppHMITypeNotCoincidedWithCurrentNonEmptyDataStoredInPT_SuccessfulRegistrationWithWarning) {
+ SetCommonPreconditionsToRegisterApplication();
+ InitBasicMessage();
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][0] =
+ mobile_apis::AppHMIType::PROJECTION;
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][1] =
+ mobile_apis::AppHMIType::INFORMATION;
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][2] =
+ mobile_apis::AppHMIType::COMMUNICATION;
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][3] =
+ mobile_apis::AppHMIType::NAVIGATION;
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][4] =
+ mobile_apis::AppHMIType::MESSAGING;
+
+ MockAppPtr mock_app = CreateBasicMockedApp();
+ SetCommonPreconditionsToCheckWithPolicyData(mock_app);
+ std::vector<std::string> present_hmi_types_in_policy{"NAVIGATION"};
+ ON_CALL(mock_policy_handler_, GetInitialAppData(kAppId1, _, _))
+ .WillByDefault(
+ DoAll(SetArgPointee<2>(present_hmi_types_in_policy), Return(true)));
+
+ auto response_to_mobile = CreateMessage();
+ EXPECT_CALL(
+ mock_rpc_service_,
+ ManageMobileCommand(_, am::commands::Command::CommandSource::SOURCE_SDL))
+ .WillOnce(DoAll(SaveArg<0>(&response_to_mobile), Return(true)))
+ .WillOnce(Return(true));
+
+ ASSERT_TRUE(command_->Init());
+ command_->Run();
+
+ const auto result_code = static_cast<mobile_apis::Result::eType>(
+ (*response_to_mobile)[am::strings::msg_params][am::strings::result_code]
+ .asUInt());
+ EXPECT_EQ(mobile_apis::Result::WARNINGS, result_code);
+
+ // Regarding to requairements, response info string should contain all
+ // AppHMITypes that are not contained in the policy table.
+ std::vector<std::string> expected_app_hmi_types_in_info_string{
+ "PROJECTION", "INFORMATION", "COMMUNICATION", "MESSAGING"};
+
+ const std::string info_string_in_response =
+ (*response_to_mobile)[am::strings::msg_params][am::strings::info]
+ .asString();
+
+ for (const auto& app_hmi_type : expected_app_hmi_types_in_info_string) {
+ EXPECT_TRUE(info_string_in_response.find(app_hmi_type) != std::string::npos)
+ << "AppHMItype absent in the response string: " << app_hmi_type;
+ }
+}
+
+TEST_F(RegisterAppInterfaceRequestTest,
+ RegisterAppWithWebView_WebViewNotAllowedInPT_RejectRegistration) {
+ SetCommonPreconditionsToRegisterApplication();
+ InitBasicMessage();
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][0] =
+ mobile_apis::AppHMIType::WEB_VIEW;
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][1] =
+ mobile_apis::AppHMIType::INFORMATION;
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][2] =
+ mobile_apis::AppHMIType::COMMUNICATION;
+
+ MockAppPtr mock_app = CreateBasicMockedApp();
+ SetCommonPreconditionsToCheckWithPolicyData(mock_app);
+ std::vector<std::string> present_hmi_types_in_policy{"INFORMATION",
+ "COMMUNICATION"};
+ ON_CALL(mock_policy_handler_, GetInitialAppData(kAppId1, _, _))
+ .WillByDefault(
+ DoAll(SetArgPointee<2>(present_hmi_types_in_policy), Return(true)));
+
+ EXPECT_CALL(*mock_app, set_webengine_projection_enabled(true)).Times(0);
+
+ auto response_to_mobile = CreateMessage();
+ EXPECT_CALL(
+ mock_rpc_service_,
+ ManageMobileCommand(_, am::commands::Command::CommandSource::SOURCE_SDL))
+ .WillOnce(DoAll(SaveArg<0>(&response_to_mobile), Return(true)));
+
+ ASSERT_TRUE(command_->Init());
+ command_->Run();
+
+ const auto result_code = static_cast<mobile_apis::Result::eType>(
+ (*response_to_mobile)[am::strings::msg_params][am::strings::result_code]
+ .asUInt());
+
+ EXPECT_EQ(mobile_apis::Result::DISALLOWED, result_code);
+}
+
+TEST_F(RegisterAppInterfaceRequestTest,
+ RegisterAppWithWebView_EmptyPT_RejectRegistration) {
+ SetCommonPreconditionsToRegisterApplication();
+ InitBasicMessage();
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][0] =
+ mobile_apis::AppHMIType::PROJECTION;
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][1] =
+ mobile_apis::AppHMIType::INFORMATION;
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][2] =
+ mobile_apis::AppHMIType::WEB_VIEW;
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][3] =
+ mobile_apis::AppHMIType::NAVIGATION;
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][4] =
+ mobile_apis::AppHMIType::MESSAGING;
+
+ MockAppPtr mock_app = CreateBasicMockedApp();
+ SetCommonPreconditionsToCheckWithPolicyData(mock_app);
+ std::vector<std::string> present_hmi_types_in_policy;
+ ON_CALL(mock_policy_handler_, GetInitialAppData(kAppId1, _, _))
+ .WillByDefault(
+ DoAll(SetArgPointee<2>(present_hmi_types_in_policy), Return(true)));
+
+ auto response_to_mobile = CreateMessage();
+ EXPECT_CALL(
+ mock_rpc_service_,
+ ManageMobileCommand(_, am::commands::Command::CommandSource::SOURCE_SDL))
+ .WillOnce(DoAll(SaveArg<0>(&response_to_mobile), Return(true)));
+
+ ASSERT_TRUE(command_->Init());
+ command_->Run();
+
+ const auto result_code = static_cast<mobile_apis::Result::eType>(
+ (*response_to_mobile)[am::strings::msg_params][am::strings::result_code]
+ .asUInt());
+ EXPECT_EQ(mobile_apis::Result::DISALLOWED, result_code);
+}
+
+TEST_F(RegisterAppInterfaceRequestTest,
+ RegisterAppWithWebViewOnly_WebViewNotAllowedInPT_RejectRegistration) {
+ SetCommonPreconditionsToRegisterApplication();
+ InitBasicMessage();
+ (*msg_)[am::strings::msg_params][am::strings::app_hmi_type][0] =
+ mobile_apis::AppHMIType::WEB_VIEW;
+
+ MockAppPtr mock_app = CreateBasicMockedApp();
+ SetCommonPreconditionsToCheckWithPolicyData(mock_app);
+ std::vector<std::string> present_hmi_types_in_policy{"INFORMATION",
+ "COMMUNICATION"};
+ ON_CALL(mock_policy_handler_, GetInitialAppData(kAppId1, _, _))
+ .WillByDefault(
+ DoAll(SetArgPointee<2>(present_hmi_types_in_policy), Return(true)));
+
+ EXPECT_CALL(*mock_app, set_webengine_projection_enabled(true)).Times(0);
+
+ auto response_to_mobile = CreateMessage();
+ EXPECT_CALL(
+ mock_rpc_service_,
+ ManageMobileCommand(_, am::commands::Command::CommandSource::SOURCE_SDL))
+ .WillOnce(DoAll(SaveArg<0>(&response_to_mobile), Return(true)));
+
+ ASSERT_TRUE(command_->Init());
+ command_->Run();
+
+ const auto result_code = static_cast<mobile_apis::Result::eType>(
+ (*response_to_mobile)[am::strings::msg_params][am::strings::result_code]
+ .asUInt());
+
+ EXPECT_EQ(mobile_apis::Result::DISALLOWED, result_code);
+}
+
} // namespace register_app_interface_request
} // namespace mobile_commands_test
} // namespace commands_test
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/simple_notification_commands_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/simple_notification_commands_test.cc
index 6e85aff281..e31f6d209d 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/simple_notification_commands_test.cc
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/simple_notification_commands_test.cc
@@ -39,7 +39,6 @@
#include "application_manager/commands/commands_test.h"
#include "application_manager/mock_message_helper.h"
#include "application_manager/smart_object_keys.h"
-#include "mobile/on_app_interface_unregistered_notification.h"
#include "mobile/on_audio_pass_thru_notification.h"
#include "mobile/on_driver_distraction_notification.h"
#include "mobile/on_language_change_notification.h"
@@ -66,8 +65,7 @@ class MobileNotificationCommandsTest
typedef Command CommandType;
};
-typedef Types<commands::OnAppInterfaceUnregisteredNotification,
- commands::OnAudioPassThruNotification,
+typedef Types<commands::OnAudioPassThruNotification,
commands::OnLanguageChangeNotification,
commands::OnPermissionsChangeNotification,
commands::mobile::OnDriverDistractionNotification>
diff --git a/src/components/application_manager/src/application_impl.cc b/src/components/application_manager/src/application_impl.cc
index c595f8ecf9..27c7411d15 100644
--- a/src/components/application_manager/src/application_impl.cc
+++ b/src/components/application_manager/src/application_impl.cc
@@ -106,6 +106,7 @@ ApplicationImpl::ApplicationImpl(
, is_navi_(false)
, is_remote_control_supported_(false)
, mobile_projection_enabled_(false)
+ , webengine_projection_enabled_(false)
, video_streaming_approved_(false)
, audio_streaming_approved_(false)
, video_streaming_allowed_(false)
@@ -199,33 +200,39 @@ bool ApplicationImpl::is_audio() const {
}
void ApplicationImpl::ChangeSupportingAppHMIType() {
- is_navi_ = false;
- is_voice_communication_application_ = false;
- mobile_projection_enabled_ = false;
+ set_is_navi(false);
+ set_voice_communication_supported(false);
+ set_mobile_projection_enabled(false);
+ set_webengine_projection_enabled(false);
const smart_objects::SmartObject& array_app_types = *app_types_;
uint32_t lenght_app_types = array_app_types.length();
for (uint32_t i = 0; i < lenght_app_types; ++i) {
- if (mobile_apis::AppHMIType::NAVIGATION ==
- static_cast<mobile_apis::AppHMIType::eType>(
- array_app_types[i].asUInt())) {
- is_navi_ = true;
- }
- if (mobile_apis::AppHMIType::COMMUNICATION ==
- static_cast<mobile_apis::AppHMIType::eType>(
- array_app_types[i].asUInt())) {
- is_voice_communication_application_ = true;
- }
- if (mobile_apis::AppHMIType::PROJECTION ==
- static_cast<mobile_apis::AppHMIType::eType>(
- array_app_types[i].asUInt())) {
- mobile_projection_enabled_ = true;
+ const auto app_hmi_type = static_cast<mobile_apis::AppHMIType::eType>(
+ array_app_types[i].asUInt());
+
+ switch (app_hmi_type) {
+ case mobile_apis::AppHMIType::NAVIGATION:
+ set_is_navi(true);
+ break;
+ case mobile_apis::AppHMIType::COMMUNICATION:
+ set_voice_communication_supported(true);
+ break;
+ case mobile_apis::AppHMIType::PROJECTION:
+ set_mobile_projection_enabled(true);
+ break;
+ case mobile_apis::AppHMIType::WEB_VIEW:
+ set_webengine_projection_enabled(true);
+ break;
+ default:
+ break;
}
}
}
-void ApplicationImpl::set_is_navi(bool allow) {
- is_navi_ = allow;
+void ApplicationImpl::set_is_navi(bool option) {
+ LOG4CXX_TRACE(logger_, "option " << std::boolalpha << option);
+ is_navi_ = option;
}
bool ApplicationImpl::is_remote_control_supported() const {
@@ -240,9 +247,9 @@ bool ApplicationImpl::is_voice_communication_supported() const {
return is_voice_communication_application_;
}
-void ApplicationImpl::set_voice_communication_supported(
- bool is_voice_communication_supported) {
- is_voice_communication_application_ = is_voice_communication_supported;
+void ApplicationImpl::set_voice_communication_supported(bool option) {
+ LOG4CXX_TRACE(logger_, "option " << std::boolalpha << option);
+ is_voice_communication_application_ = option;
}
bool ApplicationImpl::IsAudioApplication() const {
@@ -286,7 +293,7 @@ void ApplicationImpl::SetPostponedState(const WindowID window_id,
}
void ApplicationImpl::set_mobile_projection_enabled(bool option) {
- LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_TRACE(logger_, "option " << std::boolalpha << option);
mobile_projection_enabled_ = option;
}
@@ -294,6 +301,15 @@ bool ApplicationImpl::mobile_projection_enabled() const {
return mobile_projection_enabled_;
}
+void ApplicationImpl::set_webengine_projection_enabled(const bool option) {
+ LOG4CXX_TRACE(logger_, "option " << std::boolalpha << option);
+ webengine_projection_enabled_ = option;
+}
+
+bool ApplicationImpl::webengine_projection_enabled() const {
+ return webengine_projection_enabled_;
+}
+
struct StateIDComparator {
HmiState::StateID state_id_;
StateIDComparator(HmiState::StateID state_id) : state_id_(state_id) {}
@@ -457,8 +473,9 @@ void ApplicationImpl::set_name(const custom_str::CustomString& name) {
app_name_ = name;
}
-void ApplicationImpl::set_is_media_application(bool is_media) {
- is_media_ = is_media;
+void ApplicationImpl::set_is_media_application(bool option) {
+ LOG4CXX_TRACE(logger_, "option " << std::boolalpha << option);
+ is_media_ = option;
}
bool IsTTSState(const HmiStatePtr state) {
diff --git a/src/components/application_manager/src/commands/command_notification_impl.cc b/src/components/application_manager/src/commands/command_notification_impl.cc
index cc2606ab6f..31bea114ec 100644
--- a/src/components/application_manager/src/commands/command_notification_impl.cc
+++ b/src/components/application_manager/src/commands/command_notification_impl.cc
@@ -63,16 +63,18 @@ bool CommandNotificationImpl::CleanUp() {
void CommandNotificationImpl::Run() {}
-void CommandNotificationImpl::SendNotification() {
+void CommandNotificationImpl::SendNotification(const bool final_message) {
(*message_)[strings::params][strings::protocol_type] = mobile_protocol_type_;
(*message_)[strings::params][strings::protocol_version] = protocol_version_;
(*message_)[strings::params][strings::message_type] =
static_cast<int32_t>(application_manager::MessageType::kNotification);
- LOG4CXX_INFO(logger_, "SendNotification");
+ LOG4CXX_INFO(
+ logger_,
+ "SendNotification: final_message = " << std::boolalpha << final_message);
MessageHelper::PrintSmartObject(*message_);
- rpc_service_.SendMessageToMobile(message_);
+ rpc_service_.SendMessageToMobile(message_, final_message);
}
} // namespace commands
diff --git a/src/components/application_manager/src/state_controller_impl.cc b/src/components/application_manager/src/state_controller_impl.cc
index b07a5bcc13..ffff294664 100644
--- a/src/components/application_manager/src/state_controller_impl.cc
+++ b/src/components/application_manager/src/state_controller_impl.cc
@@ -88,7 +88,10 @@ void StateControllerImpl::SetRegularState(ApplicationSharedPtr app,
return;
}
- if (app->is_resuming() && !IsResumptionAllowed(app, state)) {
+ const bool app_is_resuming = app->is_resuming();
+ const bool is_resumption_allowed = IsResumptionAllowed(app, state);
+
+ if (app_is_resuming && !is_resumption_allowed) {
return;
}
@@ -333,15 +336,15 @@ void StateControllerImpl::HmiLevelConflictResolver::operator()(
DCHECK_OR_RETURN_VOID(state_to_resolve);
// If applied HMI state is FULL:
- // - all NOT audio/video applications becomes BACKGROUND
+ // - all NOT audio/video applications become BACKGROUND
// - all audio/video applications with other app type
- // (navi, vc, media, projection) in FULL becomes LIMMITED
- // - all audio/video applications with same app type becomes BACKGROUND
+ // (navi, vc, media, projection) in FULL become LIMITED
+ // - all audio/video applications with the same app type become BACKGROUND
//
// If applied HMI state is LIMITED:
- // - all NOT audio/video applications saves their's HMI states
- // - all applications with other app types saves their's HMI states
- // - all audio/video applications with same app type becomes BACKGROUND
+ // - all NOT audio/video applications saves their HMI states
+ // - all applications with the other app types saves their HMI states
+ // - all audio/video applications with the same app type become BACKGROUND
if (!IsStreamableHMILevel(state_->hmi_level())) {
LOG4CXX_DEBUG(logger_,
@@ -478,10 +481,14 @@ bool StateControllerImpl::IsResumptionAllowed(ApplicationSharedPtr app,
return false;
}
+ const bool is_navi_app = app->is_navi();
+ const bool is_mob_projection_app = app->mobile_projection_enabled();
+ const bool is_wep_app = app->webengine_projection_enabled();
+
if (IsTempStateActive(HmiState::StateID::STATE_ID_EMBEDDED_NAVI) &&
- (app->is_navi() || app->mobile_projection_enabled())) {
+ (is_navi_app || is_mob_projection_app || is_wep_app)) {
LOG4CXX_DEBUG(logger_,
- "Resumption for navi or projection app is not allowed. "
+ "Resumption for navi and projection apps is not allowed. "
<< "EMBEDDED_NAVI event is active");
return false;
}
@@ -895,7 +902,7 @@ void StateControllerImpl::OnApplicationRegistered(
const mobile_apis::HMILevel::eType default_level) {
LOG4CXX_AUTO_TRACE(logger_);
- // After app registration HMI level should be set for DEFAUL_WINDOW only
+ // After app registration HMI level should be set for DEFAULT_WINDOW only
OnAppWindowAdded(app,
mobile_apis::PredefinedWindows::DEFAULT_WINDOW,
mobile_apis::WindowType::MAIN,
@@ -1268,7 +1275,8 @@ mobile_apis::VideoStreamingState::eType StateControllerImpl::CalcVideoState(
ApplicationSharedPtr app,
const mobile_apis::HMILevel::eType hmi_level) const {
auto state = mobile_apis::VideoStreamingState::NOT_STREAMABLE;
- if (IsStreamableHMILevel(hmi_level) && app->IsVideoApplication()) {
+
+ if (app->IsVideoApplication() && IsStreamableHMILevel(hmi_level)) {
state = mobile_apis::VideoStreamingState::STREAMABLE;
}
diff --git a/src/components/application_manager/test/application_impl_test.cc b/src/components/application_manager/test/application_impl_test.cc
index 485f0f3b5b..1977044ce3 100644
--- a/src/components/application_manager/test/application_impl_test.cc
+++ b/src/components/application_manager/test/application_impl_test.cc
@@ -597,6 +597,7 @@ TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeNotNaviNotVoice) {
EXPECT_FALSE(app_impl->is_navi());
EXPECT_FALSE(app_impl->is_voice_communication_supported());
EXPECT_FALSE(app_impl->mobile_projection_enabled());
+ EXPECT_FALSE(app_impl->webengine_projection_enabled());
app_impl->set_app_types(type_media);
app_impl->ChangeSupportingAppHMIType();
@@ -604,6 +605,7 @@ TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeNotNaviNotVoice) {
EXPECT_FALSE(app_impl->is_navi());
EXPECT_FALSE(app_impl->is_voice_communication_supported());
EXPECT_FALSE(app_impl->mobile_projection_enabled());
+ EXPECT_FALSE(app_impl->webengine_projection_enabled());
}
TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsVoice) {
@@ -613,6 +615,7 @@ TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsVoice) {
EXPECT_FALSE(app_impl->is_navi());
EXPECT_FALSE(app_impl->is_voice_communication_supported());
EXPECT_FALSE(app_impl->mobile_projection_enabled());
+ EXPECT_FALSE(app_impl->webengine_projection_enabled());
app_impl->set_app_types(type_comm);
app_impl->ChangeSupportingAppHMIType();
@@ -620,6 +623,7 @@ TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsVoice) {
EXPECT_FALSE(app_impl->is_navi());
EXPECT_TRUE(app_impl->is_voice_communication_supported());
EXPECT_FALSE(app_impl->mobile_projection_enabled());
+ EXPECT_FALSE(app_impl->webengine_projection_enabled());
}
TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsNavi) {
@@ -629,6 +633,7 @@ TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsNavi) {
EXPECT_FALSE(app_impl->is_navi());
EXPECT_FALSE(app_impl->is_voice_communication_supported());
EXPECT_FALSE(app_impl->mobile_projection_enabled());
+ EXPECT_FALSE(app_impl->webengine_projection_enabled());
app_impl->set_app_types(type_navi);
app_impl->ChangeSupportingAppHMIType();
@@ -636,6 +641,71 @@ TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsNavi) {
EXPECT_TRUE(app_impl->is_navi());
EXPECT_FALSE(app_impl->is_voice_communication_supported());
EXPECT_FALSE(app_impl->mobile_projection_enabled());
+ EXPECT_FALSE(app_impl->webengine_projection_enabled());
+}
+
+TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsWebView) {
+ smart_objects::SmartObject app_types;
+ app_types[0] = mobile_apis::AppHMIType::WEB_VIEW;
+
+ EXPECT_FALSE(app_impl->is_navi());
+ EXPECT_FALSE(app_impl->is_voice_communication_supported());
+ EXPECT_FALSE(app_impl->mobile_projection_enabled());
+ EXPECT_FALSE(app_impl->webengine_projection_enabled());
+
+ app_impl->set_app_types(app_types);
+ app_impl->ChangeSupportingAppHMIType();
+
+ EXPECT_FALSE(app_impl->is_navi());
+ EXPECT_FALSE(app_impl->is_voice_communication_supported());
+ EXPECT_FALSE(app_impl->mobile_projection_enabled());
+ EXPECT_TRUE(app_impl->webengine_projection_enabled());
+}
+
+TEST_F(ApplicationImplTest,
+ ChangeSupportingAppHMIType_TypeFromWebViewToProjection) {
+ smart_objects::SmartObject app_types;
+ app_types[0] = mobile_apis::AppHMIType::WEB_VIEW;
+
+ EXPECT_FALSE(app_impl->mobile_projection_enabled());
+ EXPECT_FALSE(app_impl->webengine_projection_enabled());
+
+ app_impl->set_app_types(app_types);
+ app_impl->ChangeSupportingAppHMIType();
+
+ EXPECT_FALSE(app_impl->mobile_projection_enabled());
+ EXPECT_TRUE(app_impl->webengine_projection_enabled());
+
+ app_types[0] = mobile_apis::AppHMIType::PROJECTION;
+
+ app_impl->set_app_types(app_types);
+ app_impl->ChangeSupportingAppHMIType();
+
+ EXPECT_FALSE(app_impl->webengine_projection_enabled());
+ EXPECT_TRUE(app_impl->mobile_projection_enabled());
+}
+
+TEST_F(ApplicationImplTest,
+ ChangeSupportingAppHMIType_TypeFromProjectionToWebView) {
+ smart_objects::SmartObject app_types;
+ app_types[0] = mobile_apis::AppHMIType::PROJECTION;
+
+ EXPECT_FALSE(app_impl->mobile_projection_enabled());
+ EXPECT_FALSE(app_impl->webengine_projection_enabled());
+
+ app_impl->set_app_types(app_types);
+ app_impl->ChangeSupportingAppHMIType();
+
+ EXPECT_FALSE(app_impl->webengine_projection_enabled());
+ EXPECT_TRUE(app_impl->mobile_projection_enabled());
+
+ app_types[0] = mobile_apis::AppHMIType::WEB_VIEW;
+
+ app_impl->set_app_types(app_types);
+ app_impl->ChangeSupportingAppHMIType();
+
+ EXPECT_FALSE(app_impl->mobile_projection_enabled());
+ EXPECT_TRUE(app_impl->webengine_projection_enabled());
}
TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsNaviAndVoice) {
@@ -647,6 +717,7 @@ TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsNaviAndVoice) {
EXPECT_FALSE(app_impl->is_navi());
EXPECT_FALSE(app_impl->is_voice_communication_supported());
EXPECT_FALSE(app_impl->mobile_projection_enabled());
+ EXPECT_FALSE(app_impl->webengine_projection_enabled());
app_impl->set_app_types(app_types);
app_impl->ChangeSupportingAppHMIType();
@@ -654,6 +725,7 @@ TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsNaviAndVoice) {
EXPECT_TRUE(app_impl->is_navi());
EXPECT_TRUE(app_impl->is_voice_communication_supported());
EXPECT_FALSE(app_impl->mobile_projection_enabled());
+ EXPECT_FALSE(app_impl->webengine_projection_enabled());
}
TEST_F(ApplicationImplTest,
@@ -667,6 +739,7 @@ TEST_F(ApplicationImplTest,
EXPECT_FALSE(app_impl->is_navi());
EXPECT_FALSE(app_impl->is_voice_communication_supported());
EXPECT_FALSE(app_impl->mobile_projection_enabled());
+ EXPECT_FALSE(app_impl->webengine_projection_enabled());
app_impl->set_app_types(app_types);
app_impl->ChangeSupportingAppHMIType();
@@ -674,6 +747,7 @@ TEST_F(ApplicationImplTest,
EXPECT_TRUE(app_impl->is_navi());
EXPECT_TRUE(app_impl->is_voice_communication_supported());
EXPECT_TRUE(app_impl->mobile_projection_enabled());
+ EXPECT_FALSE(app_impl->webengine_projection_enabled());
}
TEST_F(ApplicationImplTest, UpdateHash_AppMngrNotSuspended) {
diff --git a/src/components/application_manager/test/application_manager_impl_test.cc b/src/components/application_manager/test/application_manager_impl_test.cc
index d19cbbad22..9ff2a49686 100644
--- a/src/components/application_manager/test/application_manager_impl_test.cc
+++ b/src/components/application_manager/test/application_manager_impl_test.cc
@@ -338,6 +338,44 @@ class ApplicationManagerImplTest
void CreatePendingApplication();
#endif
+ void ExpectedHmiState(
+ const ApplicationSharedPtr wep_app,
+ const WindowID main_window_id,
+ const mobile_apis::HMILevel::eType hmi_level,
+ const mobile_apis::VideoStreamingState::eType vss,
+ const mobile_apis::AudioStreamingState::eType audio_str_st,
+ const mobile_apis::SystemContext::eType system_ctx) {
+ EXPECT_EQ(hmi_level, wep_app->hmi_level(main_window_id));
+ EXPECT_EQ(vss, wep_app->video_streaming_state());
+ EXPECT_EQ(audio_str_st, wep_app->audio_streaming_state());
+ EXPECT_EQ(system_ctx, wep_app->system_context(main_window_id));
+ }
+
+ smart_objects::SmartObjectSPtr CreateRAI(const std::string app_hmi_type,
+ const bool is_media_application) {
+ smart_objects::SmartObject rai(smart_objects::SmartType_Map);
+ smart_objects::SmartObject& params = rai[strings::msg_params];
+ params[strings::app_id] = kAppId;
+ params[strings::language_desired] = mobile_api::Language::EN_US;
+ params[strings::hmi_display_language_desired] = mobile_api::Language::EN_US;
+
+ rai[strings::params][strings::connection_key] = kConnectionKey;
+ rai[strings::msg_params][strings::app_name] = kAppName;
+ rai[strings::msg_params][strings::app_hmi_type] = app_hmi_type;
+ rai[strings::msg_params][strings::is_media_application] =
+ is_media_application;
+ rai[strings::msg_params][strings::sync_msg_version]
+ [strings::minor_version] = APIVersion::kAPIV2;
+ rai[strings::msg_params][strings::sync_msg_version]
+ [strings::major_version] = APIVersion::kAPIV6;
+
+ rai[strings::params][strings::protocol_version] =
+ protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_2;
+
+ const auto rai_ptr = std::make_shared<smart_objects::SmartObject>(rai);
+ return rai_ptr;
+ }
+
void CreatePendingLocalApplication(const std::string& policy_app_id);
uint32_t app_id_;
@@ -2046,6 +2084,173 @@ TEST_F(
EXPECT_EQ(1u, app_list.size());
}
+TEST_F(
+ ApplicationManagerImplTest,
+ RegisterApplication_WEPNonMediaAppRegisterActivateDeactivateExit_EXPECT_CORRECT_HMI_STATES) {
+ using namespace mobile_apis;
+ EXPECT_CALL(
+ mock_session_observer_,
+ GetDataOnSessionKey(kConnectionKey,
+ _,
+ _,
+ testing::An<connection_handler::DeviceHandle*>()))
+ .WillOnce(DoAll(SetArgPointee<3u>(kDeviceId), Return(0)));
+
+ const std::string app_hmi_type{"WEB_VIEW"};
+ const bool is_media_app = false;
+ const auto rai_ptr = CreateRAI(app_hmi_type, is_media_app);
+
+ std::unique_ptr<plugin_manager::RPCPluginManager> rpc_plugin_manager(
+ new MockRPCPluginManager());
+ app_manager_impl_->SetPluginManager(rpc_plugin_manager);
+ auto wep_nonmedia_app = app_manager_impl_->RegisterApplication(rai_ptr);
+ wep_nonmedia_app->set_is_media_application(false);
+
+ EXPECT_EQ(protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_2,
+ wep_nonmedia_app->protocol_version());
+ EXPECT_EQ(APIVersion::kAPIV2,
+ wep_nonmedia_app->version().min_supported_api_version);
+ EXPECT_EQ(APIVersion::kAPIV6,
+ wep_nonmedia_app->version().max_supported_api_version);
+
+ // Initial HMI level, audio, video streaming states and system context
+ // set after app registration
+ ExpectedHmiState(wep_nonmedia_app,
+ kDefaultWindowId,
+ HMILevel::INVALID_ENUM,
+ VideoStreamingState::INVALID_ENUM,
+ AudioStreamingState::INVALID_ENUM,
+ SystemContext::SYSCTXT_MAIN);
+
+ // Const shared ptr is required for OnAppActivated due to its signature
+ ApplicationConstSharedPtr const_wep_app = wep_nonmedia_app;
+ EXPECT_CALL(*mock_app_service_manager_, OnAppActivated(const_wep_app));
+
+ // Activate Webengine projection non-media app
+ // to check its audio & video streaming states in FULL Hmi level
+ app_manager_impl_->ActivateApplication(wep_nonmedia_app);
+
+ // WEP non-media app should be always not_streamable
+ // and not_audible even in FULL HMI Level
+ ExpectedHmiState(wep_nonmedia_app,
+ kDefaultWindowId,
+ HMILevel::HMI_FULL,
+ VideoStreamingState::NOT_STREAMABLE,
+ AudioStreamingState::NOT_AUDIBLE,
+ SystemContext::SYSCTXT_MAIN);
+
+ // Deactivate Webengine projection non-media app
+ // to check its new HMI level and audio & video streaming states
+ app_manager_impl_->state_controller().DeactivateApp(wep_nonmedia_app,
+ kDefaultWindowId);
+
+ // WEP non-media app should be deactivated to BACKGROUND
+ // WEP non-media app should be not audible and not streamable
+ // in BACKGROUND HMI Level
+
+ ExpectedHmiState(wep_nonmedia_app,
+ kDefaultWindowId,
+ HMILevel::HMI_BACKGROUND,
+ VideoStreamingState::NOT_STREAMABLE,
+ AudioStreamingState::NOT_AUDIBLE,
+ SystemContext::SYSCTXT_MAIN);
+
+ // Exit of Webengine projection non-media app
+ // to check its new HMI level and audio & video streaming states
+ app_manager_impl_->state_controller().ExitDefaultWindow(wep_nonmedia_app);
+ // WEP non-media app should be deactivated to NONE
+ // WEP non-media app should be not audible and not streamable
+ // in NONE HMI Level
+ ExpectedHmiState(wep_nonmedia_app,
+ kDefaultWindowId,
+ HMILevel::HMI_NONE,
+ VideoStreamingState::NOT_STREAMABLE,
+ AudioStreamingState::NOT_AUDIBLE,
+ SystemContext::SYSCTXT_MAIN);
+}
+
+TEST_F(
+ ApplicationManagerImplTest,
+ RegisterApplication_WEPMediaAppRegisterActivateDeactivateExit_EXPECT_CORRECT_HMI_STATES) {
+ using namespace mobile_apis;
+
+ EXPECT_CALL(
+ mock_session_observer_,
+ GetDataOnSessionKey(kConnectionKey,
+ _,
+ _,
+ testing::An<connection_handler::DeviceHandle*>()))
+ .WillOnce(DoAll(SetArgPointee<3u>(kDeviceId), Return(0)));
+
+ const std::string app_hmi_type{"WEB_VIEW"};
+ const bool is_media_app = true;
+ const auto rai_ptr = CreateRAI(app_hmi_type, is_media_app);
+
+ std::unique_ptr<plugin_manager::RPCPluginManager> rpc_plugin_manager(
+ new MockRPCPluginManager());
+ app_manager_impl_->SetPluginManager(rpc_plugin_manager);
+ auto wep_media_app = app_manager_impl_->RegisterApplication(rai_ptr);
+ wep_media_app->set_is_media_application(true);
+
+ EXPECT_EQ(protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_2,
+ wep_media_app->protocol_version());
+ EXPECT_EQ(APIVersion::kAPIV2,
+ wep_media_app->version().min_supported_api_version);
+ EXPECT_EQ(APIVersion::kAPIV6,
+ wep_media_app->version().max_supported_api_version);
+
+ // Initial HMI level, audio, video streaming states and system context
+ // set after app registration
+ ExpectedHmiState(wep_media_app,
+ kDefaultWindowId,
+ HMILevel::INVALID_ENUM,
+ VideoStreamingState::INVALID_ENUM,
+ AudioStreamingState::INVALID_ENUM,
+ SystemContext::SYSCTXT_MAIN);
+
+ // Const shared ptr is required for OnAppActivated due to its signature
+ ApplicationConstSharedPtr const_wep_app = wep_media_app;
+ EXPECT_CALL(*mock_app_service_manager_, OnAppActivated(const_wep_app));
+
+ // Activate Webengine projection media app
+ // to check its audio & video streaming states in FULL Hmi level
+ app_manager_impl_->ActivateApplication(wep_media_app);
+
+ // WEP media app should be always not_streamable
+ // but audible even in FULL HMI Level
+ ExpectedHmiState(wep_media_app,
+ kDefaultWindowId,
+ HMILevel::HMI_FULL,
+ VideoStreamingState::NOT_STREAMABLE,
+ AudioStreamingState::AUDIBLE,
+ SystemContext::SYSCTXT_MAIN);
+
+ // Deactivate Webengine projection media app
+ // to check its new HMI level and audio & video streaming states
+ app_manager_impl_->state_controller().DeactivateApp(wep_media_app,
+ kDefaultWindowId);
+
+ // WEP media app should be deactivated to LIMITED
+ // WEP media app should be audible but not streamable in LIMITED HMI Level
+ ExpectedHmiState(wep_media_app,
+ kDefaultWindowId,
+ HMILevel::HMI_LIMITED,
+ VideoStreamingState::NOT_STREAMABLE,
+ AudioStreamingState::AUDIBLE,
+ SystemContext::SYSCTXT_MAIN);
+
+ // Exit of Webengine projection media app
+ // to check its new HMI level and audio & video streaming states
+ app_manager_impl_->state_controller().ExitDefaultWindow(wep_media_app);
+ // WEP media app should be exited to NONE
+ ExpectedHmiState(wep_media_app,
+ kDefaultWindowId,
+ HMILevel::HMI_NONE,
+ VideoStreamingState::NOT_STREAMABLE,
+ AudioStreamingState::NOT_AUDIBLE,
+ SystemContext::SYSCTXT_MAIN);
+}
+
TEST_F(ApplicationManagerImplTest, AddAndRemoveQueryAppDevice_SUCCESS) {
const connection_handler::DeviceHandle device_handle = 1u;
ASSERT_FALSE(app_manager_impl_->IsAppsQueriedFrom(device_handle));
diff --git a/src/components/application_manager/test/include/application_manager/mock_application.h b/src/components/application_manager/test/include/application_manager/mock_application.h
index 175c39513e..224fea0456 100644
--- a/src/components/application_manager/test/include/application_manager/mock_application.h
+++ b/src/components/application_manager/test/include/application_manager/mock_application.h
@@ -67,6 +67,8 @@ class MockApplication : public ::application_manager::Application {
MOCK_METHOD1(set_is_navi, void(bool allow));
MOCK_CONST_METHOD0(mobile_projection_enabled, bool());
MOCK_METHOD1(set_mobile_projection_enabled, void(bool allow));
+ MOCK_CONST_METHOD0(webengine_projection_enabled, bool());
+ MOCK_METHOD1(set_webengine_projection_enabled, void(const bool allow));
MOCK_CONST_METHOD0(video_streaming_approved, bool());
MOCK_METHOD1(set_video_streaming_approved, void(bool state));
MOCK_CONST_METHOD0(audio_streaming_approved, bool());
diff --git a/src/components/application_manager/test/state_controller/state_controller_test.cc b/src/components/application_manager/test/state_controller/state_controller_test.cc
index 93565b8719..e9bce76fc5 100644
--- a/src/components/application_manager/test/state_controller/state_controller_test.cc
+++ b/src/components/application_manager/test/state_controller/state_controller_test.cc
@@ -83,6 +83,15 @@ const uint32_t kHMIAppID = 2718u;
const am::WindowID kDefaultWindowId =
mobile_apis::PredefinedWindows::DEFAULT_WINDOW;
const am::WindowID kCustomWindowId = 2;
+
+const uint32_t kAppIdInFull = 1761;
+const uint32_t kHMIAppIdInFull = 15685;
+const uint32_t kAppIdMovedToFull = 1796;
+const uint32_t kHMIAppIdMovedToFull = 30093;
+const uint32_t kAppIdLimited = 1762;
+const uint32_t kHMIAppIdLimited = 17559;
+const uint32_t kAppIDMovedToLimited = 1763;
+const uint32_t kHMIAppIdMovedToLimited = 17663;
} // namespace
struct HmiStatesComparator {
@@ -131,6 +140,8 @@ struct HmiStatesIDComparator {
#define NOT_VC false
#define NAVI true
#define NOT_NAVI false
+#define WEP true
+#define NOT_WEP false
enum ApplicationType {
APP_TYPE_NON_MEDIA,
@@ -211,6 +222,16 @@ class StateControllerImplTest : public ::testing::Test {
uint32_t media_navi_vc_app_id_ = 1922;
uint32_t media_navi_vc_hmi_app_id_ = 21419;
+ am::ApplicationSharedPtr media_wep_app_;
+ NiceMock<application_manager_test::MockApplication>* media_wep_app_ptr_;
+ uint32_t media_wep_app_id_ = 1977;
+ uint32_t media_wep_app_hmi_app_id_ = 21491;
+
+ am::ApplicationSharedPtr non_media_wep_app_;
+ NiceMock<application_manager_test::MockApplication>* non_media_wep_app_ptr_;
+ uint32_t non_media_wep_app_id_ = 1979;
+ uint32_t non_media_wep_app_hmi_app_id_ = 21599;
+
std::vector<am::HmiStatePtr> valid_states_for_audio_app_;
std::vector<am::HmiStatePtr> valid_states_for_not_audio_app_;
std::vector<am::HmiStatePtr> common_invalid_states_;
@@ -557,7 +578,7 @@ class StateControllerImplTest : public ::testing::Test {
}
}
- ApplicationType AppType(uint32_t app_id) {
+ ApplicationType AppType(const uint32_t app_id) {
// TODO(AOleynik): Currently there is ongoing discussion regarding mixed
// application properties, i.e. is_media_application flag from RAI and
// AppHmiTypes (NAVIGATION, etc.). Most likely logic should be changed
@@ -573,7 +594,7 @@ class StateControllerImplTest : public ::testing::Test {
return APP_TYPE_NON_MEDIA;
}
- auto app = it->first;
+ const auto app = it->first;
if (app->is_navi()) {
return APP_TYPE_NAVI;
}
@@ -682,18 +703,21 @@ class StateControllerImplTest : public ::testing::Test {
NiceMock<application_manager_test::MockApplication>** app_mock,
uint32_t app_id,
uint32_t hmi_app_id,
- bool media,
- bool navi,
- bool vc) {
+ const bool media,
+ const bool navi,
+ const bool vc,
+ const bool wep) {
*app_mock = new NiceMock<application_manager_test::MockApplication>;
- Mock::AllowLeak(*app_mock); // WorkAround for gogletest bug
+ Mock::AllowLeak(*app_mock); // WorkAround for googletest bug
am::ApplicationSharedPtr app(*app_mock);
ON_CALL(**app_mock, app_id()).WillByDefault(Return(app_id));
ON_CALL(**app_mock, hmi_app_id()).WillByDefault(Return(hmi_app_id));
ON_CALL(**app_mock, is_media_application()).WillByDefault(Return(media));
ON_CALL(**app_mock, is_navi()).WillByDefault(Return(navi));
+ ON_CALL(**app_mock, webengine_projection_enabled())
+ .WillByDefault(Return(wep));
ON_CALL(**app_mock, is_voice_communication_supported())
.WillByDefault(Return(vc));
ON_CALL(**app_mock, IsAudioApplication())
@@ -898,45 +922,72 @@ class StateControllerImplTest : public ::testing::Test {
simple_hmi_app_id_,
NOT_MEDIA,
NOT_NAVI,
- NOT_VC);
+ NOT_VC,
+ NOT_WEP);
media_app_ = ConfigureApp(&media_app_ptr_,
media_app_id_,
media_hmi_app_id_,
MEDIA,
NOT_NAVI,
- NOT_VC);
+ NOT_VC,
+ NOT_WEP);
navi_app_ = ConfigureApp(&navi_app_ptr_,
navi_app_id_,
navi_hmi_app_id_,
NOT_MEDIA,
NAVI,
- NOT_VC);
- vc_app_ = ConfigureApp(
- &vc_app_ptr_, vc_app_id_, vc_hmi_app_id_, NOT_MEDIA, NOT_NAVI, VC);
+ NOT_VC,
+ NOT_WEP);
+ vc_app_ = ConfigureApp(&vc_app_ptr_,
+ vc_app_id_,
+ vc_hmi_app_id_,
+ NOT_MEDIA,
+ NOT_NAVI,
+ VC,
+ NOT_WEP);
media_navi_app_ = ConfigureApp(&media_navi_app_ptr_,
media_navi_app_id_,
media_navi_hmi_app_id_,
MEDIA,
NAVI,
- NOT_VC);
+ NOT_VC,
+ NOT_WEP);
media_vc_app_ = ConfigureApp(&media_vc_app_ptr_,
media_vc_app_id_,
media_vc_hmi_app_id_,
MEDIA,
NOT_NAVI,
- VC);
+ VC,
+ NOT_WEP);
navi_vc_app_ = ConfigureApp(&navi_vc_app_ptr_,
navi_vc_app_id_,
navi_vc_hmi_app_id_,
NOT_MEDIA,
NAVI,
- VC);
+ VC,
+ NOT_WEP);
media_navi_vc_app_ = ConfigureApp(&media_navi_vc_app_ptr_,
media_navi_vc_app_id_,
media_navi_vc_hmi_app_id_,
MEDIA,
NAVI,
- VC);
+ VC,
+ NOT_WEP);
+ media_wep_app_ = ConfigureApp(&media_wep_app_ptr_,
+ media_wep_app_id_,
+ media_wep_app_hmi_app_id_,
+ MEDIA,
+ NOT_NAVI,
+ NOT_VC,
+ WEP);
+ non_media_wep_app_ = ConfigureApp(&non_media_wep_app_ptr_,
+ non_media_wep_app_id_,
+ non_media_wep_app_hmi_app_id_,
+ NOT_MEDIA,
+ NOT_NAVI,
+ NOT_VC,
+ WEP);
+
applications_list_[simple_app_] = simple_app_ptr_;
applications_list_[media_app_] = media_app_ptr_;
applications_list_[navi_app_] = navi_app_ptr_;
@@ -945,7 +996,10 @@ class StateControllerImplTest : public ::testing::Test {
applications_list_[media_vc_app_] = media_vc_app_ptr_;
applications_list_[navi_vc_app_] = navi_vc_app_ptr_;
applications_list_[media_navi_vc_app_] = media_navi_vc_app_ptr_;
+ applications_list_[media_wep_app_] = media_wep_app_ptr_;
+ applications_list_[non_media_wep_app_] = non_media_wep_app_ptr_;
}
+
void CheckAppConfiguration() {
ASSERT_EQ(simple_app_.get(), simple_app_ptr_);
ASSERT_EQ(media_app_.get(), media_app_ptr_);
@@ -955,6 +1009,8 @@ class StateControllerImplTest : public ::testing::Test {
ASSERT_EQ(media_vc_app_.get(), media_vc_app_ptr_);
ASSERT_EQ(navi_vc_app_.get(), navi_vc_app_ptr_);
ASSERT_EQ(media_navi_vc_app_.get(), media_navi_vc_app_ptr_);
+ ASSERT_EQ(media_wep_app_.get(), media_wep_app_ptr_);
+ ASSERT_EQ(non_media_wep_app_.get(), non_media_wep_app_ptr_);
ASSERT_EQ(simple_app_->app_id(), simple_app_id_);
ASSERT_EQ(media_app_->app_id(), media_app_id_);
@@ -964,6 +1020,8 @@ class StateControllerImplTest : public ::testing::Test {
ASSERT_EQ(media_vc_app_->app_id(), media_vc_app_id_);
ASSERT_EQ(navi_vc_app_->app_id(), navi_vc_app_id_);
ASSERT_EQ(media_navi_vc_app_->app_id(), media_navi_vc_app_id_);
+ ASSERT_EQ(media_wep_app_->app_id(), media_wep_app_id_);
+ ASSERT_EQ(non_media_wep_app_->app_id(), non_media_wep_app_id_);
ASSERT_EQ(simple_app_->hmi_app_id(), simple_hmi_app_id_);
ASSERT_EQ(media_app_->hmi_app_id(), media_hmi_app_id_);
@@ -973,6 +1031,8 @@ class StateControllerImplTest : public ::testing::Test {
ASSERT_EQ(media_vc_app_->hmi_app_id(), media_vc_hmi_app_id_);
ASSERT_EQ(navi_vc_app_->hmi_app_id(), navi_vc_hmi_app_id_);
ASSERT_EQ(media_navi_vc_app_->hmi_app_id(), media_navi_vc_hmi_app_id_);
+ ASSERT_EQ(media_wep_app_->hmi_app_id(), media_wep_app_hmi_app_id_);
+ ASSERT_EQ(non_media_wep_app_->hmi_app_id(), non_media_wep_app_hmi_app_id_);
ASSERT_FALSE(simple_app_->IsAudioApplication());
ASSERT_TRUE(media_app_->IsAudioApplication());
@@ -982,6 +1042,8 @@ class StateControllerImplTest : public ::testing::Test {
ASSERT_TRUE(media_vc_app_->IsAudioApplication());
ASSERT_TRUE(navi_vc_app_->IsAudioApplication());
ASSERT_TRUE(media_navi_vc_app_->IsAudioApplication());
+ ASSERT_TRUE(media_wep_app_->IsAudioApplication());
+ ASSERT_FALSE(non_media_wep_app_->IsAudioApplication());
ASSERT_FALSE(simple_app_->is_media_application());
ASSERT_TRUE(media_app_->is_media_application());
@@ -991,6 +1053,8 @@ class StateControllerImplTest : public ::testing::Test {
ASSERT_TRUE(media_vc_app_->is_media_application());
ASSERT_FALSE(navi_vc_app_->is_media_application());
ASSERT_TRUE(media_navi_vc_app_->is_media_application());
+ ASSERT_TRUE(media_wep_app_->is_media_application());
+ ASSERT_FALSE(non_media_wep_app_->is_media_application());
ASSERT_FALSE(simple_app_->is_navi());
ASSERT_TRUE(navi_app_->is_navi());
@@ -1000,6 +1064,8 @@ class StateControllerImplTest : public ::testing::Test {
ASSERT_FALSE(media_vc_app_->is_navi());
ASSERT_TRUE(navi_vc_app_->is_navi());
ASSERT_TRUE(media_navi_vc_app_->is_navi());
+ ASSERT_FALSE(media_wep_app_->is_navi());
+ ASSERT_FALSE(non_media_wep_app_->is_navi());
ASSERT_FALSE(simple_app_->is_voice_communication_supported());
ASSERT_FALSE(navi_app_->is_voice_communication_supported());
@@ -1009,6 +1075,8 @@ class StateControllerImplTest : public ::testing::Test {
ASSERT_TRUE(media_vc_app_->is_voice_communication_supported());
ASSERT_TRUE(navi_vc_app_->is_voice_communication_supported());
ASSERT_TRUE(media_navi_vc_app_->is_voice_communication_supported());
+ ASSERT_FALSE(media_wep_app_->is_voice_communication_supported());
+ ASSERT_FALSE(non_media_wep_app_->is_voice_communication_supported());
}
virtual void SetUp() OVERRIDE {
@@ -1601,10 +1669,21 @@ TEST_F(StateControllerImplTest,
am::ApplicationSharedPtr app_moved_to_full;
NiceMock<application_manager_test::MockApplication>* app_moved_to_full_mock;
- app_in_full =
- ConfigureApp(&app_in_full_mock, 1761, 15685, NOT_MEDIA, NOT_NAVI, NOT_VC);
- app_moved_to_full = ConfigureApp(
- &app_moved_to_full_mock, 1796, 30093, NOT_MEDIA, NOT_NAVI, NOT_VC);
+ app_in_full = ConfigureApp(&app_in_full_mock,
+ kAppIdInFull,
+ kHMIAppIdInFull,
+ NOT_MEDIA,
+ NOT_NAVI,
+ NOT_VC,
+ NOT_WEP);
+
+ app_moved_to_full = ConfigureApp(&app_moved_to_full_mock,
+ kAppIdMovedToFull,
+ kHMIAppIdMovedToFull,
+ NOT_MEDIA,
+ NOT_NAVI,
+ NOT_VC,
+ NOT_WEP);
InsertApplication(app_in_full);
InsertApplication(app_moved_to_full);
@@ -1678,12 +1757,23 @@ TEST_F(StateControllerImplTest,
namespace HMILevel = mobile_apis::HMILevel;
namespace SystemContext = mobile_apis::SystemContext;
NiceMock<application_manager_test::MockApplication>* app_in_full_mock;
- am::ApplicationSharedPtr app_in_full =
- ConfigureApp(&app_in_full_mock, 1761, 15685, MEDIA, NOT_NAVI, NOT_VC);
+ am::ApplicationSharedPtr app_in_full = ConfigureApp(&app_in_full_mock,
+ kAppIdInFull,
+ kHMIAppIdInFull,
+ MEDIA,
+ NOT_NAVI,
+ NOT_VC,
+ NOT_WEP);
NiceMock<application_manager_test::MockApplication>* app_moved_to_full_mock;
- am::ApplicationSharedPtr app_moved_to_full = ConfigureApp(
- &app_moved_to_full_mock, 1796, 30093, MEDIA, NOT_NAVI, NOT_VC);
+ am::ApplicationSharedPtr app_moved_to_full =
+ ConfigureApp(&app_moved_to_full_mock,
+ kAppIdMovedToFull,
+ kHMIAppIdMovedToFull,
+ MEDIA,
+ NOT_NAVI,
+ NOT_VC,
+ NOT_WEP);
InsertApplication(app_in_full);
InsertApplication(app_moved_to_full);
@@ -1705,12 +1795,23 @@ TEST_F(StateControllerImplTest,
namespace SystemContext = mobile_apis::SystemContext;
NiceMock<application_manager_test::MockApplication>* app_in_limited_mock;
- am::ApplicationSharedPtr app_in_limited =
- ConfigureApp(&app_in_limited_mock, 1761, 15685, NOT_MEDIA, NAVI, NOT_VC);
+ am::ApplicationSharedPtr app_in_limited = ConfigureApp(&app_in_limited_mock,
+ kAppIdLimited,
+ kHMIAppIdLimited,
+ NOT_MEDIA,
+ NAVI,
+ NOT_VC,
+ NOT_WEP);
NiceMock<application_manager_test::MockApplication>* app_moved_to_full_mock;
am::ApplicationSharedPtr app_moved_to_full =
- ConfigureApp(&app_moved_to_full_mock, 1796, 30093, NOT_MEDIA, NAVI, VC);
+ ConfigureApp(&app_moved_to_full_mock,
+ kAppIdMovedToFull,
+ kHMIAppIdMovedToFull,
+ NOT_MEDIA,
+ NAVI,
+ VC,
+ NOT_WEP);
InsertApplication(app_in_limited);
InsertApplication(app_moved_to_full);
@@ -1731,13 +1832,24 @@ TEST_F(StateControllerImplTest,
namespace HMILevel = mobile_apis::HMILevel;
namespace SystemContext = mobile_apis::SystemContext;
NiceMock<application_manager_test::MockApplication>* app_in_limited_mock;
- am::ApplicationSharedPtr app_in_limited =
- ConfigureApp(&app_in_limited_mock, 1761, 15685, NOT_MEDIA, NOT_NAVI, VC);
+ am::ApplicationSharedPtr app_in_limited = ConfigureApp(&app_in_limited_mock,
+ kAppIdLimited,
+ kHMIAppIdLimited,
+ NOT_MEDIA,
+ NOT_NAVI,
+ VC,
+ NOT_WEP);
NiceMock<application_manager_test::MockApplication>*
app_moved_to_limited_mock;
- am::ApplicationSharedPtr app_moved_to_limited = ConfigureApp(
- &app_moved_to_limited_mock, 1796, 30093, NOT_MEDIA, NOT_NAVI, VC);
+ am::ApplicationSharedPtr app_moved_to_limited =
+ ConfigureApp(&app_moved_to_limited_mock,
+ kAppIDMovedToLimited,
+ kHMIAppIdMovedToLimited,
+ NOT_MEDIA,
+ NOT_NAVI,
+ VC,
+ NOT_WEP);
InsertApplication(app_in_limited);
InsertApplication(app_moved_to_limited);
@@ -1886,16 +1998,27 @@ TEST_F(StateControllerImplTest,
namespace SystemContext = mobile_apis::SystemContext;
NiceMock<application_manager_test::MockApplication>* app_moved_to_full_mock;
- am::ApplicationSharedPtr app_moved_to_full = ConfigureApp(
- &app_moved_to_full_mock, 1761, 15685, NOT_MEDIA, NOT_NAVI, NOT_VC);
+ am::ApplicationSharedPtr app_moved_to_full =
+ ConfigureApp(&app_moved_to_full_mock,
+ kAppIdMovedToFull,
+ kHMIAppIdMovedToFull,
+ NOT_MEDIA,
+ NOT_NAVI,
+ NOT_VC,
+ NOT_WEP);
am::ApplicationSharedPtr limited_app = media_app_;
NiceMock<application_manager_test::MockApplication>* limited_app_mock =
media_app_ptr_;
NiceMock<application_manager_test::MockApplication>* full_app_mock;
- am::ApplicationSharedPtr full_app =
- ConfigureApp(&full_app_mock, 1796, 30093, NOT_MEDIA, NOT_NAVI, NOT_VC);
+ am::ApplicationSharedPtr full_app = ConfigureApp(&full_app_mock,
+ kAppIdInFull,
+ kHMIAppIdInFull,
+ NOT_MEDIA,
+ NOT_NAVI,
+ NOT_VC,
+ NOT_WEP);
InsertApplication(app_moved_to_full);
InsertApplication(limited_app);
@@ -1924,16 +2047,32 @@ TEST_F(
namespace SystemContext = mobile_apis::SystemContext;
NiceMock<application_manager_test::MockApplication>* app_moved_to_full_mock;
- am::ApplicationSharedPtr app_moved_to_full = ConfigureApp(
- &app_moved_to_full_mock, 1761, 15685, MEDIA, NOT_NAVI, NOT_VC);
+ am::ApplicationSharedPtr app_moved_to_full =
+ ConfigureApp(&app_moved_to_full_mock,
+ kAppIdMovedToFull,
+ kHMIAppIdMovedToFull,
+ MEDIA,
+ NOT_NAVI,
+ NOT_VC,
+ NOT_WEP);
NiceMock<application_manager_test::MockApplication>* limited_app_mock;
- am::ApplicationSharedPtr limited_app =
- ConfigureApp(&limited_app_mock, 1762, 17559, MEDIA, NOT_NAVI, NOT_VC);
+ am::ApplicationSharedPtr limited_app = ConfigureApp(&limited_app_mock,
+ kAppIdLimited,
+ kHMIAppIdLimited,
+ MEDIA,
+ NOT_NAVI,
+ NOT_VC,
+ NOT_WEP);
NiceMock<application_manager_test::MockApplication>* full_app_mock;
- am::ApplicationSharedPtr full_app =
- ConfigureApp(&full_app_mock, 1796, 30093, NOT_MEDIA, NOT_NAVI, NOT_VC);
+ am::ApplicationSharedPtr full_app = ConfigureApp(&full_app_mock,
+ kAppIdInFull,
+ kHMIAppIdInFull,
+ NOT_MEDIA,
+ NOT_NAVI,
+ NOT_VC,
+ NOT_WEP);
InsertApplication(app_moved_to_full);
InsertApplication(limited_app);
@@ -1962,16 +2101,32 @@ TEST_F(
namespace SystemContext = mobile_apis::SystemContext;
NiceMock<application_manager_test::MockApplication>* app_moved_to_full_mock;
- am::ApplicationSharedPtr app_moved_to_full = ConfigureApp(
- &app_moved_to_full_mock, 1761, 15685, MEDIA, NOT_NAVI, NOT_VC);
+ am::ApplicationSharedPtr app_moved_to_full =
+ ConfigureApp(&app_moved_to_full_mock,
+ kAppIdMovedToFull,
+ kHMIAppIdMovedToFull,
+ MEDIA,
+ NOT_NAVI,
+ NOT_VC,
+ NOT_WEP);
NiceMock<application_manager_test::MockApplication>* limited_app_mock;
- am::ApplicationSharedPtr limited_app =
- ConfigureApp(&limited_app_mock, 1762, 17559, MEDIA, NOT_NAVI, NOT_VC);
+ am::ApplicationSharedPtr limited_app = ConfigureApp(&limited_app_mock,
+ kAppIdLimited,
+ kHMIAppIdLimited,
+ MEDIA,
+ NOT_NAVI,
+ NOT_VC,
+ NOT_WEP);
NiceMock<application_manager_test::MockApplication>* full_app_mock;
- am::ApplicationSharedPtr full_app =
- ConfigureApp(&full_app_mock, 1796, 30093, NOT_MEDIA, NAVI, NOT_VC);
+ am::ApplicationSharedPtr full_app = ConfigureApp(&full_app_mock,
+ kAppIdInFull,
+ kHMIAppIdInFull,
+ NOT_MEDIA,
+ NAVI,
+ NOT_VC,
+ NOT_WEP);
InsertApplication(app_moved_to_full);
InsertApplication(limited_app);
@@ -3388,6 +3543,29 @@ TEST_F(
media_app_, kDefaultWindowId, new_state, send_activate_app);
}
+TEST_F(
+ StateControllerImplTest,
+ SetRegularState_WEPAppIsInResumingModeEmbeddedNaviIsActive_HmiStateIsNotChanged) {
+ am::event_engine::Event embedded_navi_event(
+ hmi_apis::FunctionID::BasicCommunication_OnEventChanged);
+ smart_objects::SmartObject message;
+ message[am::strings::msg_params][am::hmi_notification::is_active] = true;
+ message[am::strings::msg_params][am::hmi_notification::event_name] =
+ hmi_apis::Common_EventTypes::EMBEDDED_NAVI;
+ embedded_navi_event.set_smart_object(message);
+ state_ctrl_->on_event(embedded_navi_event);
+
+ EXPECT_CALL(*media_wep_app_ptr_, is_resuming())
+ .Times(2)
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(*media_wep_app_ptr_, SetRegularState(_, _)).Times(0);
+
+ const auto new_state = FullAudibleState();
+ const bool send_activate_app = true;
+ state_ctrl_->SetRegularState(
+ media_wep_app_, kDefaultWindowId, new_state, send_activate_app);
+}
+
TEST_F(StateControllerImplTest,
SetRegularState_BcActivateAppSendFailed_HmiLevelIsNotChanged) {
const am::HmiStatePtr new_state = FullAudibleState();
diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc
index 1ad938332a..d2b00448e3 100644
--- a/src/components/connection_handler/src/connection_handler_impl.cc
+++ b/src/components/connection_handler/src/connection_handler_impl.cc
@@ -1605,6 +1605,7 @@ void ConnectionHandlerImpl::CloseConnectionSessions(
}
void ConnectionHandlerImpl::SendEndService(uint32_t key, uint8_t service_type) {
+ LOG4CXX_AUTO_TRACE(logger_);
if (protocol_handler_) {
uint32_t connection_handle = 0;
uint8_t session_id = 0;
diff --git a/src/components/include/application_manager/state_controller.h b/src/components/include/application_manager/state_controller.h
index 2fa4b0c218..93d4c4fc39 100644
--- a/src/components/include/application_manager/state_controller.h
+++ b/src/components/include/application_manager/state_controller.h
@@ -223,6 +223,15 @@ class StateController {
* @param app pointer to application to be exited
*/
virtual void ExitDefaultWindow(ApplicationSharedPtr app) = 0;
+
+ /**
+ * @brief Sets BACKGROUND or LIMITED hmi level to application
+ * depends on application type
+ * @param window_id ID of app window to deactivate
+ * @param app Application to deactivate
+ */
+ virtual void DeactivateApp(ApplicationSharedPtr app,
+ const WindowID window_id) = 0;
};
} // namespace application_manager
diff --git a/src/components/include/test/application_manager/mock_state_controller.h b/src/components/include/test/application_manager/mock_state_controller.h
index 545090bf30..26d403ba75 100644
--- a/src/components/include/test/application_manager/mock_state_controller.h
+++ b/src/components/include/test/application_manager/mock_state_controller.h
@@ -108,6 +108,9 @@ class MockStateController : public am::StateController {
MOCK_CONST_METHOD1(IsStateActive, bool(am::HmiState::StateID state_id));
MOCK_METHOD1(ActivateDefaultWindow, void(am::ApplicationSharedPtr app));
MOCK_METHOD1(ExitDefaultWindow, void(am::ApplicationSharedPtr app));
+ MOCK_METHOD2(DeactivateApp,
+ void(am::ApplicationSharedPtr app,
+ const am::WindowID window_id));
};
} // namespace application_manager_test
diff --git a/src/components/interfaces/HMI_API.xml b/src/components/interfaces/HMI_API.xml
index c84f9367e9..8e906a7bbb 100644
--- a/src/components/interfaces/HMI_API.xml
+++ b/src/components/interfaces/HMI_API.xml
@@ -340,6 +340,7 @@
<element name="SYSTEM" />
<element name="PROJECTION" />
<element name="REMOTE_CONTROL" />
+ <element name="WEB_VIEW" />
</enum>
<enum name="CloudConnectionStatus">
@@ -540,6 +541,9 @@
<element name="CLOSE_CLOUD_CONNECTION">
<description>By getting this value, SDL puts the named app to NONE HMILevel. Used by the HMI to close a cloud app connection.</description>
</element>
+ <element name="RESOURCE_CONSTRAINT">
+ <description>By getting this value, SDL should unregister the application to allow the HMI to close the application.</description>
+ </element>
</enum>
<enum name="TextFieldName">
diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc
index 7769696a76..9b7305d48a 100644
--- a/src/components/protocol_handler/src/protocol_handler_impl.cc
+++ b/src/components/protocol_handler/src/protocol_handler_impl.cc
@@ -652,6 +652,7 @@ void ProtocolHandlerImpl::SendEndServicePrivate(int32_t primary_connection_id,
void ProtocolHandlerImpl::SendEndSession(int32_t connection_id,
uint8_t session_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
// A session is always associated with a primary connection ID
SendEndServicePrivate(
connection_id, connection_id, session_id, SERVICE_TYPE_RPC);
@@ -661,6 +662,7 @@ void ProtocolHandlerImpl::SendEndService(int32_t primary_connection_id,
int32_t connection_id,
uint8_t session_id,
uint8_t service_type) {
+ LOG4CXX_AUTO_TRACE(logger_);
SendEndServicePrivate(
primary_connection_id, connection_id, session_id, service_type);
}
@@ -1106,6 +1108,24 @@ void ProtocolHandlerImpl::OnTMMessageSendFailed(
<< "bytes failed, connection_key "
<< message->connection_key()
<< "Error_text: " << error.text());
+
+ uint32_t connection_handle = 0;
+ uint8_t session_id = 0;
+
+ session_observer_.PairFromKey(
+ message->connection_key(), &connection_handle, &session_id);
+
+ const auto connection_it = std::find(ready_to_close_connections_.begin(),
+ ready_to_close_connections_.end(),
+ connection_handle);
+ if (ready_to_close_connections_.end() != connection_it) {
+ ready_to_close_connections_.erase(connection_it);
+ }
+
+ const auto last_message_it = sessions_last_message_id_.find(session_id);
+ if (sessions_last_message_id_.end() != last_message_it) {
+ sessions_last_message_id_.erase(last_message_it);
+ }
}
void ProtocolHandlerImpl::OnConnectionPending(
diff --git a/src/components/transport_manager/include/transport_manager/websocket_server/websocket_connection.h b/src/components/transport_manager/include/transport_manager/websocket_server/websocket_connection.h
index fb904d645e..b3dc04a897 100644
--- a/src/components/transport_manager/include/transport_manager/websocket_server/websocket_connection.h
+++ b/src/components/transport_manager/include/transport_manager/websocket_server/websocket_connection.h
@@ -48,7 +48,6 @@ namespace transport_adapter {
using ::utils::MessageQueue;
-typedef ::protocol_handler::RawMessagePtr Message;
typedef std::queue<Message> AsyncQueue;
class TransportAdapterController;
@@ -75,10 +74,11 @@ class WebSocketConnection
TransportAdapter::Error Disconnect() OVERRIDE;
- TransportAdapter::Error SendData(
- protocol_handler::RawMessagePtr message) OVERRIDE;
+ TransportAdapter::Error SendData(Message message) OVERRIDE;
- void DataReceive(protocol_handler::RawMessagePtr frame);
+ void DataReceive(Message frame);
+ void DataSendDone(Message frame);
+ void DataSendFailed(Message frame);
void Run();
bool IsShuttingDown();
@@ -99,21 +99,17 @@ class WebSocketConnection
class LoopThreadDelegate : public threads::ThreadDelegate {
public:
LoopThreadDelegate(MessageQueue<Message, AsyncQueue>* message_queue,
- DataWriteCallback data_write,
- OnIOErrorCallback on_io_error);
+ DataWriteCallback data_write);
virtual void threadMain() OVERRIDE;
virtual void exitThreadMain() OVERRIDE;
- void OnWrite();
-
void SetShutdown();
private:
void DrainQueue();
MessageQueue<Message, AsyncQueue>& message_queue_;
DataWriteCallback data_write_;
- OnIOErrorCallback on_io_error_;
};
LoopThreadDelegate* thread_delegate_;
diff --git a/src/components/transport_manager/include/transport_manager/websocket_server/websocket_secure_session.h b/src/components/transport_manager/include/transport_manager/websocket_server/websocket_secure_session.h
index a3ead8e5a5..cfeedd16fc 100644
--- a/src/components/transport_manager/include/transport_manager/websocket_server/websocket_secure_session.h
+++ b/src/components/transport_manager/include/transport_manager/websocket_server/websocket_secure_session.h
@@ -45,7 +45,9 @@ class WebSocketSecureSession : public WebSocketSession<ExecutorType> {
WebSocketSecureSession(tcp::socket,
ssl::context& ctx,
DataReceiveCallback data_receive,
- OnIOErrorCallback on_errror);
+ DataSendDoneCallback data_send_done,
+ DataSendFailedCallback data_send_failed,
+ OnIOErrorCallback on_error);
void AsyncAccept() OVERRIDE;
virtual void AsyncHandshake(boost::system::error_code ec);
diff --git a/src/components/transport_manager/include/transport_manager/websocket_server/websocket_session.h b/src/components/transport_manager/include/transport_manager/websocket_server/websocket_session.h
index a8dadc9831..53dd6a366a 100644
--- a/src/components/transport_manager/include/transport_manager/websocket_server/websocket_session.h
+++ b/src/components/transport_manager/include/transport_manager/websocket_server/websocket_session.h
@@ -35,6 +35,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/asio/strand.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
+#include <functional>
+
#include "protocol/raw_message.h"
#include "transport_manager/transport_adapter/transport_adapter.h"
#include "utils/logger.h"
@@ -46,10 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace transport_manager {
namespace transport_adapter {
-using DataReceiveCallback =
- std::function<void(protocol_handler::RawMessagePtr)>;
-using DataWriteCallback = std::function<TransportAdapter::Error(
- protocol_handler::RawMessagePtr message)>;
+using Message = ::protocol_handler::RawMessagePtr;
+using DataReceiveCallback = std::function<void(Message)>;
+using DataSendDoneCallback = DataReceiveCallback;
+using DataSendFailedCallback = DataReceiveCallback;
+using DataWriteCallback = DataReceiveCallback;
using OnIOErrorCallback = std::function<void()>;
using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
@@ -69,12 +72,16 @@ class WebSocketSession
public:
WebSocketSession(boost::asio::ip::tcp::socket socket,
DataReceiveCallback data_receive,
+ DataSendDoneCallback data_send_done,
+ DataSendFailedCallback data_send_failed,
OnIOErrorCallback on_error);
#ifdef ENABLE_SECURITY
WebSocketSession(boost::asio::ip::tcp::socket socket,
ssl::context& ctx,
DataReceiveCallback data_receive,
+ DataSendDoneCallback data_send_done,
+ DataSendFailedCallback data_send_failed,
OnIOErrorCallback on_error);
#endif // ENABLE_SECURITY
@@ -84,8 +91,7 @@ class WebSocketSession
virtual void AsyncRead(boost::system::error_code ec);
- virtual TransportAdapter::Error WriteDown(
- ::protocol_handler::RawMessagePtr message);
+ virtual void WriteDown(Message message);
virtual void Read(boost::system::error_code ec,
std::size_t bytes_transferred);
@@ -98,6 +104,8 @@ class WebSocketSession
boost::asio::strand<boost::asio::io_context::executor_type> strand_;
boost::beast::flat_buffer buffer_;
DataReceiveCallback data_receive_;
+ DataSendDoneCallback data_send_done_;
+ DataSendFailedCallback data_send_failed_;
OnIOErrorCallback on_io_error_;
};
diff --git a/src/components/transport_manager/src/cloud/websocket_client_connection.cc b/src/components/transport_manager/src/cloud/websocket_client_connection.cc
index 794cf57208..955ce17f67 100644
--- a/src/components/transport_manager/src/cloud/websocket_client_connection.cc
+++ b/src/components/transport_manager/src/cloud/websocket_client_connection.cc
@@ -284,6 +284,7 @@ TransportAdapter::Error WebsocketClientConnection::Disconnect() {
}
void WebsocketClientConnection::Shutdown() {
+ LOG4CXX_AUTO_TRACE(logger_);
shutdown_ = true;
if (thread_delegate_) {
diff --git a/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc b/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
index 36f6dd98d0..8301c50a4e 100644
--- a/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
+++ b/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
@@ -521,6 +521,7 @@ DeviceSptr TransportAdapterImpl::GetWebEngineDevice() const {
}
DeviceSptr TransportAdapterImpl::AddDevice(DeviceSptr device) {
+ LOG4CXX_AUTO_TRACE(logger_);
LOG4CXX_TRACE(logger_, "enter. device: " << device);
DeviceSptr existing_device;
bool same_device_found = false;
@@ -530,7 +531,7 @@ DeviceSptr TransportAdapterImpl::AddDevice(DeviceSptr device) {
existing_device = i->second;
if (device->IsSameAs(existing_device.get())) {
same_device_found = true;
- LOG4CXX_DEBUG(logger_, "device " << device << "already exists");
+ LOG4CXX_DEBUG(logger_, "Device " << device << " already exists");
break;
}
}
@@ -539,7 +540,7 @@ DeviceSptr TransportAdapterImpl::AddDevice(DeviceSptr device) {
}
devices_mutex_.Release();
if (same_device_found) {
- LOG4CXX_TRACE(logger_, "exit with TRUE. Condition: same_device_found");
+ LOG4CXX_TRACE(logger_, "Exit with TRUE. Condition: same_device_found");
return existing_device;
} else {
device->set_connection_status(ConnectionStatus::PENDING);
@@ -677,6 +678,7 @@ void TransportAdapterImpl::ConnectionCreated(
ConnectionSPtr connection,
const DeviceUID& device_id,
const ApplicationHandle& app_handle) {
+ LOG4CXX_AUTO_TRACE(logger_);
LOG4CXX_TRACE(logger_,
"enter connection:" << connection
<< ", device_id: " << &device_id
@@ -692,6 +694,7 @@ void TransportAdapterImpl::ConnectionCreated(
void TransportAdapterImpl::DeviceDisconnected(
const DeviceUID& device_handle, const DisconnectDeviceError& error) {
+ LOG4CXX_AUTO_TRACE(logger_);
const DeviceUID device_uid = device_handle;
LOG4CXX_TRACE(
logger_,
@@ -730,6 +733,7 @@ void TransportAdapterImpl::DeviceDisconnected(
bool TransportAdapterImpl::IsSingleApplication(
const DeviceUID& device_uid, const ApplicationHandle& app_uid) {
+ LOG4CXX_AUTO_TRACE(logger_);
sync_primitives::AutoReadLock locker(connections_lock_);
for (ConnectionMap::const_iterator it = connections_.begin();
it != connections_.end();
@@ -749,6 +753,7 @@ bool TransportAdapterImpl::IsSingleApplication(
void TransportAdapterImpl::DisconnectDone(const DeviceUID& device_handle,
const ApplicationHandle& app_handle) {
+ LOG4CXX_AUTO_TRACE(logger_);
const DeviceUID device_uid = device_handle;
const ApplicationHandle app_uid = app_handle;
LOG4CXX_TRACE(
@@ -775,6 +780,7 @@ void TransportAdapterImpl::DisconnectDone(const DeviceUID& device_handle,
RemoveConnection(device_uid, app_uid);
if (device_disconnected) {
+ LOG4CXX_DEBUG(logger_, "Removing device...");
RemoveDevice(device_uid);
}
@@ -1026,6 +1032,7 @@ void TransportAdapterImpl::RemoveFinalizedConnection(
void TransportAdapterImpl::RemoveConnection(
const DeviceUID& device_id, const ApplicationHandle& app_handle) {
+ LOG4CXX_AUTO_TRACE(logger_);
ConnectionSPtr connection;
connections_lock_.AcquireForWriting();
ConnectionMap::const_iterator it =
@@ -1071,6 +1078,7 @@ ApplicationList TransportAdapterImpl::GetApplicationList(
void TransportAdapterImpl::ConnectionFinished(
const DeviceUID& device_id, const ApplicationHandle& app_handle) {
+ LOG4CXX_AUTO_TRACE(logger_);
LOG4CXX_TRACE(
logger_,
"enter. device_id: " << &device_id << ", app_handle: " << &app_handle);
@@ -1088,6 +1096,7 @@ void TransportAdapterImpl::ConnectionAborted(
const DeviceUID& device_id,
const ApplicationHandle& app_handle,
const CommunicationError& error) {
+ LOG4CXX_AUTO_TRACE(logger_);
ConnectionFinished(device_id, app_handle);
for (TransportAdapterListenerList::iterator it = listeners_.begin();
it != listeners_.end();
@@ -1192,6 +1201,7 @@ bool TransportAdapterImpl::ToBeAutoConnected(DeviceSptr device) const {
}
bool TransportAdapterImpl::ToBeAutoDisconnected(DeviceSptr device) const {
+ LOG4CXX_AUTO_TRACE(logger_);
return true;
}
diff --git a/src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc b/src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc
index bf2d3dbdf4..2e411a4f87 100644
--- a/src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc
+++ b/src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc
@@ -203,6 +203,7 @@ void TransportAdapterListenerImpl::OnDisconnectDone(
const TransportAdapter* adapter,
const DeviceUID& device,
const ApplicationHandle& app_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
LOG4CXX_TRACE(logger_,
"enter. adapter: " << adapter << ", device: " << &device
<< ", application_id: " << &app_id);
@@ -245,7 +246,9 @@ void TransportAdapterListenerImpl::OnDisconnectFailed(
}
void TransportAdapterListenerImpl::OnDisconnectDeviceDone(
- const TransportAdapter* adapter, const DeviceUID& device) {}
+ const TransportAdapter* adapter, const DeviceUID& device) {
+ LOG4CXX_AUTO_TRACE(logger_);
+}
void TransportAdapterListenerImpl::OnDisconnectDeviceFailed(
const TransportAdapter* adapter,
diff --git a/src/components/transport_manager/src/transport_manager_impl.cc b/src/components/transport_manager/src/transport_manager_impl.cc
index ddff4f3780..c8e5e431fd 100644
--- a/src/components/transport_manager/src/transport_manager_impl.cc
+++ b/src/components/transport_manager/src/transport_manager_impl.cc
@@ -1305,14 +1305,10 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) {
// TODO(YK): start timer here to wait before notify caller
// and remove unsent messages
LOG4CXX_ERROR(logger_, "Transport adapter failed to send data");
- // TODO(YK): potential error case -> thread unsafe
- // update of message content
- if (event.event_data.use_count() != 0) {
- event.event_data->set_waiting(true);
- } else {
- LOG4CXX_DEBUG(logger_, "Data is invalid");
- }
- LOG4CXX_DEBUG(logger_, "eevent_type = ON_SEND_FAIL");
+ RaiseEvent(&TransportManagerListener::OnTMMessageSendFailed,
+ DataSendError(),
+ event.event_data);
+ LOG4CXX_DEBUG(logger_, "event_type = ON_SEND_FAIL");
break;
}
case EventTypeEnum::ON_RECEIVED_DONE: {
@@ -1423,11 +1419,6 @@ void TransportManagerImpl::Handle(::protocol_handler::RawMessagePtr msg) {
}
TransportAdapter* transport_adapter = connection->transport_adapter;
- LOG4CXX_DEBUG(logger_,
- "Got adapter " << transport_adapter << "["
- << transport_adapter->GetDeviceType() << "]"
- << " by session id " << msg->connection_key());
-
if (NULL == transport_adapter) {
std::string error_text = "Transport adapter is not found";
LOG4CXX_ERROR(logger_, error_text);
@@ -1435,6 +1426,10 @@ void TransportManagerImpl::Handle(::protocol_handler::RawMessagePtr msg) {
DataSendError(error_text),
msg);
} else {
+ LOG4CXX_DEBUG(logger_,
+ "Got adapter " << transport_adapter << "["
+ << transport_adapter->GetDeviceType() << "]"
+ << " by session id " << msg->connection_key());
if (TransportAdapter::OK ==
transport_adapter->SendData(
connection->device, connection->application, msg)) {
diff --git a/src/components/transport_manager/src/websocket_server/websocket_connection.cc b/src/components/transport_manager/src/websocket_server/websocket_connection.cc
index 7bcc4baef2..601110af2f 100644
--- a/src/components/transport_manager/src/websocket_server/websocket_connection.cc
+++ b/src/components/transport_manager/src/websocket_server/websocket_connection.cc
@@ -49,17 +49,15 @@ WebSocketConnection<WebSocketSession<> >::WebSocketConnection(
, app_handle_(app_handle)
, session_(new WebSocketSession<>(
std::move(socket),
- std::bind(
- &WebSocketConnection::DataReceive, this, std::placeholders::_1),
- std::bind(&WebSocketConnection::OnError, this)))
+ [this](Message frame) { DataReceive(frame); },
+ [this](Message frame) { DataSendDone(frame); },
+ [this](Message frame) { DataSendFailed(frame); },
+ [this]() { OnError(); }))
, controller_(controller)
, shutdown_(false)
, thread_delegate_(new LoopThreadDelegate(
&message_queue_,
- std::bind(&WebSocketSession<>::WriteDown,
- session_.get(),
- std::placeholders::_1),
- std::bind(&WebSocketConnection::OnError, this)))
+ [this](Message frame) { session_->WriteDown(frame); }))
, thread_(threads::CreateThread("WS Async Send", thread_delegate_)) {
thread_->start(threads::ThreadOptions());
}
@@ -77,17 +75,15 @@ WebSocketConnection<WebSocketSecureSession<> >::WebSocketConnection(
, session_(new WebSocketSecureSession<>(
std::move(socket),
ctx,
- std::bind(
- &WebSocketConnection::DataReceive, this, std::placeholders::_1),
- std::bind(&WebSocketConnection::OnError, this)))
+ [this](Message frame) { DataReceive(frame); },
+ [this](Message frame) { DataSendDone(frame); },
+ [this](Message frame) { DataSendFailed(frame); },
+ [this]() { OnError(); }))
, controller_(controller)
, shutdown_(false)
, thread_delegate_(new LoopThreadDelegate(
&message_queue_,
- std::bind(&WebSocketSecureSession<>::WriteDown,
- session_.get(),
- std::placeholders::_1),
- std::bind(&WebSocketConnection::OnError, this)))
+ [this](Message frame) { session_->WriteDown(frame); }))
, thread_(threads::CreateThread("WS Async Send", thread_delegate_)) {
thread_->start(threads::ThreadOptions());
}
@@ -105,6 +101,16 @@ template <typename Session>
void WebSocketConnection<Session>::OnError() {
LOG4CXX_AUTO_TRACE(wsc_logger_);
+ if (IsShuttingDown()) {
+ LOG4CXX_DEBUG(wsc_logger_, "Session is shutting down...");
+ return;
+ }
+
+ Message message_ptr;
+ while (message_queue_.pop(message_ptr)) {
+ DataSendFailed(message_ptr);
+ }
+
controller_->ConnectionAborted(
device_uid_, app_handle_, CommunicationError());
@@ -124,7 +130,7 @@ TransportAdapter::Error WebSocketConnection<Session>::Disconnect() {
template <typename Session>
TransportAdapter::Error WebSocketConnection<Session>::SendData(
- ::protocol_handler::RawMessagePtr message) {
+ Message message) {
if (IsShuttingDown()) {
return TransportAdapter::BAD_STATE;
}
@@ -135,12 +141,21 @@ TransportAdapter::Error WebSocketConnection<Session>::SendData(
}
template <typename Session>
-void WebSocketConnection<Session>::DataReceive(
- protocol_handler::RawMessagePtr frame) {
+void WebSocketConnection<Session>::DataReceive(Message frame) {
controller_->DataReceiveDone(device_uid_, app_handle_, frame);
}
template <typename Session>
+void WebSocketConnection<Session>::DataSendDone(Message frame) {
+ controller_->DataSendDone(device_uid_, app_handle_, frame);
+}
+
+template <typename Session>
+void WebSocketConnection<Session>::DataSendFailed(Message frame) {
+ controller_->DataSendFailed(device_uid_, app_handle_, frame, DataSendError());
+}
+
+template <typename Session>
void WebSocketConnection<Session>::Run() {
LOG4CXX_AUTO_TRACE(wsc_logger_);
session_->AsyncAccept();
@@ -169,11 +184,8 @@ bool WebSocketConnection<Session>::IsShuttingDown() {
template <typename Session>
WebSocketConnection<Session>::LoopThreadDelegate::LoopThreadDelegate(
MessageQueue<Message, AsyncQueue>* message_queue,
- DataWriteCallback data_write,
- OnIOErrorCallback on_io_error)
- : message_queue_(*message_queue)
- , data_write_(data_write)
- , on_io_error_(on_io_error) {}
+ DataWriteCallback data_write)
+ : message_queue_(*message_queue), data_write_(data_write) {}
template <typename Session>
void WebSocketConnection<Session>::LoopThreadDelegate::threadMain() {
@@ -186,22 +198,14 @@ void WebSocketConnection<Session>::LoopThreadDelegate::threadMain() {
template <typename Session>
void WebSocketConnection<Session>::LoopThreadDelegate::exitThreadMain() {
- if (!message_queue_.IsShuttingDown()) {
- message_queue_.Shutdown();
- }
+ SetShutdown();
}
template <typename Session>
void WebSocketConnection<Session>::LoopThreadDelegate::DrainQueue() {
Message message_ptr;
while (!message_queue_.IsShuttingDown() && message_queue_.pop(message_ptr)) {
- auto res = data_write_(message_ptr);
- if (TransportAdapter::FAIL == res) {
- LOG4CXX_WARN(wsc_logger_,
- "Writing to websocket stream failed. Will now close "
- "websocket connection.");
- on_io_error_();
- }
+ data_write_(message_ptr);
}
}
diff --git a/src/components/transport_manager/src/websocket_server/websocket_secure_session.cc b/src/components/transport_manager/src/websocket_server/websocket_secure_session.cc
index 9be94119b6..46a1267cab 100644
--- a/src/components/transport_manager/src/websocket_server/websocket_secure_session.cc
+++ b/src/components/transport_manager/src/websocket_server/websocket_secure_session.cc
@@ -42,9 +42,15 @@ WebSocketSecureSession<ExecutorType>::WebSocketSecureSession(
tcp::socket socket,
ssl::context& ctx,
DataReceiveCallback data_receive,
+ DataSendDoneCallback data_send_done,
+ DataSendFailedCallback data_send_failed,
OnIOErrorCallback on_error)
- : WebSocketSession<ExecutorType>(
- std::move(socket), ctx, data_receive, on_error) {}
+ : WebSocketSession<ExecutorType>(std::move(socket),
+ ctx,
+ data_receive,
+ data_send_done,
+ data_send_failed,
+ on_error) {}
template <typename ExecutorType>
void WebSocketSecureSession<ExecutorType>::AsyncAccept() {
diff --git a/src/components/transport_manager/src/websocket_server/websocket_session.cc b/src/components/transport_manager/src/websocket_server/websocket_session.cc
index ab62530963..8826243777 100644
--- a/src/components/transport_manager/src/websocket_server/websocket_session.cc
+++ b/src/components/transport_manager/src/websocket_server/websocket_session.cc
@@ -41,11 +41,15 @@ template <>
WebSocketSession<tcp::socket&>::WebSocketSession(
boost::asio::ip::tcp::socket socket,
DataReceiveCallback data_receive,
+ DataSendDoneCallback data_send_done,
+ DataSendFailedCallback data_send_failed,
OnIOErrorCallback on_error)
: socket_(std::move(socket))
, ws_(socket_)
, strand_(ws_.get_executor())
, data_receive_(data_receive)
+ , data_send_done_(data_send_done)
+ , data_send_failed_(data_send_failed)
, on_io_error_(on_error) {
ws_.binary(true);
}
@@ -56,11 +60,15 @@ WebSocketSession<ssl::stream<tcp::socket&> >::WebSocketSession(
boost::asio::ip::tcp::socket socket,
ssl::context& ctx,
DataReceiveCallback data_receive,
+ DataSendDoneCallback data_send_done,
+ DataSendFailedCallback data_send_failed,
OnIOErrorCallback on_error)
: socket_(std::move(socket))
, ws_(socket_, ctx)
, strand_(ws_.get_executor())
, data_receive_(data_receive)
+ , data_send_done_(data_send_done)
+ , data_send_failed_(data_send_failed)
, on_io_error_(on_error) {
ws_.binary(true);
}
@@ -98,17 +106,17 @@ void WebSocketSession<ExecutorType>::AsyncRead(boost::system::error_code ec) {
}
template <typename ExecutorType>
-TransportAdapter::Error WebSocketSession<ExecutorType>::WriteDown(
- ::protocol_handler::RawMessagePtr message) {
+void WebSocketSession<ExecutorType>::WriteDown(Message message) {
boost::system::error_code ec;
ws_.write(boost::asio::buffer(message->data(), message->data_size()), ec);
if (ec) {
LOG4CXX_ERROR(ws_logger_, "A system error has occurred: " << ec.message());
- return TransportAdapter::FAIL;
+ data_send_failed_(message);
+ on_io_error_();
+ return;
}
-
- return TransportAdapter::OK;
+ data_send_done_(message);
}
template <typename ExecutorType>
@@ -131,8 +139,8 @@ void WebSocketSession<ExecutorType>::Read(boost::system::error_code ec,
"Msg: " << boost::beast::buffers_to_string(buffer_.data())
<< " Size: " << size;);
- ::protocol_handler::RawMessagePtr frame(
- new protocol_handler::RawMessage(0, 0, data, size, false));
+ auto frame =
+ std::make_shared<protocol_handler::RawMessage>(0, 0, data, size, false);
data_receive_(frame);
diff --git a/src/components/transport_manager/test/transport_manager_impl_test.cc b/src/components/transport_manager/test/transport_manager_impl_test.cc
index db4813be9a..227367e750 100644
--- a/src/components/transport_manager/test/transport_manager_impl_test.cc
+++ b/src/components/transport_manager/test/transport_manager_impl_test.cc
@@ -633,15 +633,17 @@ TEST_F(TransportManagerImplTest, SendMessageToDevice_SendDone) {
EXPECT_TRUE(waiter.WaitFor(1, kAsyncExpectationsTimeout));
}
-TEST_F(TransportManagerImplTest, SendMessageFailed_GetHandleSendFailed) {
+TEST_F(
+ TransportManagerImplTest,
+ SendMessageToDevice_AdapterSendDataOkAndOnSendFailEvent_OnTMMessageSendFailed) {
// Arrange
HandleConnection();
TestAsyncWaiter waiter;
EXPECT_CALL(*mock_adapter_,
SendData(mac_address_, application_id_, test_message_))
- .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter),
- Return(TransportAdapter::FAIL)));
+ .WillOnce(
+ DoAll(NotifyTestAsyncWaiter(&waiter), Return(TransportAdapter::OK)));
#ifdef TELEMETRY_MONITOR
EXPECT_CALL(mock_metric_observer_, StartRawMsg(test_message_.get()));
diff --git a/tools/rpc_spec b/tools/rpc_spec
-Subproject 754845ae77411a4b1db5c6dfbafd1c5164d2b29
+Subproject 0d7185781f4dd1a316137a052e1126cdb6e3f47