summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kutsan <akutsan@luxoft.com>2017-08-10 14:07:07 +0300
committerAndrey Oleynik <aoleynik@luxoft.com>2017-08-16 22:32:33 +0300
commit06729e8b744374a4d9694f669101b6c554ce42e0 (patch)
tree7fd73e4e64a831755fa02bbbd8ee8ccfb8f09efd
parent41fe2979a5f1f8a13428ae4fe88f37ee9824c92e (diff)
downloadsdl_core-06729e8b744374a4d9694f669101b6c554ce42e0.tar.gz
Arhitecture changes for support RC plugin
-rw-r--r--CMakeLists.txt19
-rw-r--r--src/appMain/CMakeLists.txt24
-rw-r--r--src/appMain/life_cycle.h4
-rw-r--r--src/components/CMakeLists.txt6
-rw-r--r--src/components/application_manager/include/application_manager/app_extension.h58
-rw-r--r--src/components/application_manager/include/application_manager/core_service.h248
-rw-r--r--src/components/application_manager/include/application_manager/service.h243
-rw-r--r--src/components/application_manager/src/core_service.cc306
-rw-r--r--src/components/config_profile/include/config_profile/profile.h23
-rw-r--r--src/components/config_profile/src/profile.cc11
-rw-r--r--src/components/functional_module/CMakeLists.txt58
-rw-r--r--src/components/functional_module/include/functional_module/function_ids.h61
-rw-r--r--src/components/functional_module/include/functional_module/generic_module.h175
-rw-r--r--src/components/functional_module/include/functional_module/module_observer.h48
-rw-r--r--src/components/functional_module/include/functional_module/plugin_manager.h128
-rw-r--r--src/components/functional_module/include/functional_module/settings.h125
-rw-r--r--src/components/functional_module/include/functional_module/timer/module_timer.h231
-rw-r--r--src/components/functional_module/include/functional_module/timer/timer_director.h92
-rw-r--r--src/components/functional_module/src/generic_module.cc63
-rw-r--r--src/components/functional_module/src/plugin_manager.cc405
-rw-r--r--src/components/functional_module/src/settings.cc64
-rw-r--r--src/components/functional_module/src/timer/timer_director.cc156
-rw-r--r--src/components/functional_module/test/CMakeLists.txt56
-rw-r--r--src/components/functional_module/test/include/driver_generic_module_test.h77
-rw-r--r--src/components/functional_module/test/include/mock_application.h248
-rw-r--r--src/components/functional_module/test/include/mock_module_observer.h50
-rw-r--r--src/components/functional_module/test/include/mock_service.h92
-rw-r--r--src/components/functional_module/test/include/module_timer_test.h56
-rw-r--r--src/components/functional_module/test/plugins/CMakeLists.txt17
-rw-r--r--src/components/functional_module/test/plugins/mock_generic_module.cc23
-rw-r--r--src/components/functional_module/test/plugins/mock_generic_module.h72
-rw-r--r--src/components/functional_module/test/src/generic_module_test.cc137
-rw-r--r--src/components/functional_module/test/src/module_timer_test.cc123
-rw-r--r--src/components/functional_module/test/src/plugin_manager_test.cc206
-rw-r--r--src/components/functional_module/test/src/settings_test.cc92
-rw-r--r--src/components/functional_module/test/test.ini36
-rw-r--r--src/components/hmi_message_handler/include/hmi_message_handler/hmi_message_adapter_impl.h9
-rw-r--r--src/components/hmi_message_handler/include/hmi_message_handler/hmi_message_handler_impl.h28
-rw-r--r--src/components/hmi_message_handler/include/hmi_message_handler/messagebroker_adapter.h7
-rw-r--r--src/components/hmi_message_handler/src/hmi_message_adapter_impl.cc6
-rw-r--r--src/components/hmi_message_handler/src/hmi_message_handler_impl.cc14
-rw-r--r--src/components/include/test/application_manager/mock_application_manager.h25
-rw-r--r--src/components/include/test/application_manager/mock_application_manager_settings.h1
-rw-r--r--src/components/include/utils/macro.h11
44 files changed, 3914 insertions, 20 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6a62aed45c..b8fd497a09 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -52,7 +52,7 @@ option(ENABLE_GCOV "gcov code coverage feature" OFF)
option(ENABLE_SANITIZE "Sanitize tool" OFF)
option(ENABLE_SECURITY "Security Ford protocol protection" ON)
option(ENABLE_HMI_PTU_DECRYPTION "Policy table update parsed by hmi" ON)
-option(ENABLE_EXTENDED_POLICY "Turns extended flow which requires embedded system interaction" ON)
+option(REMOTE_CONTROL "Enable Reverse functionality" ON)
option(USE_COTIRE "Use Cotire to speed up build (currently only for commands tests)" ON)
option(USE_GOLD_LD "Use gold linker intead of GNU linker" ON)
option(USE_CCACHE "Turn on ccache usage" ON)
@@ -160,6 +160,11 @@ if (OS_TYPE_OPTION)
endif()
endif()
+if (REMOTE_CONTROL)
+ add_definitions(-DSDL_REMOTE_CONTROL)
+ message(STATUS "Remote control support is enabled (aka Reverse SDL or SDL-RC)")
+endif()
+
#Jenkins integration section end
add_custom_target(pasa-tarball
@@ -409,6 +414,18 @@ if(CMAKE_SYSTEM_NAME STREQUAL "QNX")
set(RTLIB )
endif()
+SET(RPATH_DIRECTORIES
+ ${CMAKE_INSTALL_PREFIX}/bin/plugins
+ /usr/local/lib
+ /usr/local
+ ${CMAKE_INSTALL_PREFIX}/bin
+)
+SET(CMAKE_SKIP_BUILD_RPATH FALSE)
+SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
+SET(CMAKE_INSTALL_RPATH "${RPATH_DIRECTORIES}")
+SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+
+
# Building tests
if(BUILD_TESTS)
enable_testing()
diff --git a/src/appMain/CMakeLists.txt b/src/appMain/CMakeLists.txt
index cd67dc5f60..64c88bf22f 100644
--- a/src/appMain/CMakeLists.txt
+++ b/src/appMain/CMakeLists.txt
@@ -44,6 +44,7 @@ endif()
include_directories(
${COMPONENTS_DIR}/protocol_handler/include
${COMPONENTS_DIR}/application_manager/include
+ ${COMPONENTS_DIR}/remote_control/include
${COMPONENTS_DIR}/formatters/include
${COMPONENTS_DIR}/transport_manager/include
${COMPONENTS_DIR}/security_manager/include
@@ -56,9 +57,10 @@ include_directories(
${COMPONENTS_DIR}/smart_objects/include
${COMPONENTS_DIR}/media_manager/include
${COMPONENTS_DIR}/telemetry_monitor/include
- ${POLICY_PATH}/include/
+ ${COMPONENTS_DIR}/functional_module/include
+ ${POLICY_PATH}/include
${POLICY_GLOBAL_INCLUDE_PATH}/
- ${COMPONENTS_DIR}/rpc_base/include/
+ ${COMPONENTS_DIR}/rpc_base/include
${COMPONENTS_DIR}/resumption/include
${COMPONENTS_DIR}/dbus/include
${CMAKE_BINARY_DIR}/src/components
@@ -115,6 +117,12 @@ set(LIBRARIES
ConfigProfile
Resumption
)
+if(REMOTE_CONTROL)
+ SET (LIBRARIES
+ ${LIBRARIES}
+ FunctionalModule
+ )
+endif(REMOTE_CONTROL)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
list(APPEND LIBRARIES pthread)
@@ -210,6 +218,18 @@ install(
${CMAKE_SOURCE_DIR}/mycert.pem ${CMAKE_SOURCE_DIR}/mykey.pem
DESTINATION bin
)
+if (REMOTE_CONTROL)
+ install(
+ FILES "${CMAKE_SOURCE_DIR}/src/components/remote_control/remote_sdl_pt.json"
+ DESTINATION ${CMAKE_BINARY_DIR}/bin
+ RENAME sdl_preloaded_pt.json
+ )
+else ()
+ install(
+ FILES sdl_preloaded_pt.json
+ DESTINATION bin
+ )
+endif ()
if (${QT_HMI})
if (CMAKE_SYSTEM_NAME STREQUAL "QNX")
diff --git a/src/appMain/life_cycle.h b/src/appMain/life_cycle.h
index f1b3800254..586711d53e 100644
--- a/src/appMain/life_cycle.h
+++ b/src/appMain/life_cycle.h
@@ -44,6 +44,10 @@
#include "hmi_message_handler/messagebroker_adapter.h"
#endif // #if ( defined (MESSAGEBROKER_HMIADAPTER) || defined(PASA_HMI) )
#include "application_manager/application_manager_impl.h"
+#ifdef SDL_REMOTE_CONTROL
+#include "application_manager/core_service.h"
+#include "functional_module/plugin_manager.h"
+#endif // SDL_REMOTE_CONTROL
#include "connection_handler/connection_handler_impl.h"
#include "protocol_handler/protocol_handler_impl.h"
#include "transport_manager/transport_manager.h"
diff --git a/src/components/CMakeLists.txt b/src/components/CMakeLists.txt
index 0304ce986f..e1071e826f 100644
--- a/src/components/CMakeLists.txt
+++ b/src/components/CMakeLists.txt
@@ -86,6 +86,12 @@ add_subdirectory(./config_profile)
# --- Media Manager
add_subdirectory(./media_manager)
+if(REMOTE_CONTROL)
+ # --- CAN Module
+ add_subdirectory(./remote_control)
+ # --- Functional module
+ add_subdirectory(./functional_module)
+endif()
# --- Telemetry Monitor
if(TELEMETRY_MONITOR)
add_subdirectory(./telemetry_monitor)
diff --git a/src/components/application_manager/include/application_manager/app_extension.h b/src/components/application_manager/include/application_manager/app_extension.h
new file mode 100644
index 0000000000..221601a307
--- /dev/null
+++ b/src/components/application_manager/include/application_manager/app_extension.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_EXTENSION_H_
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_EXTENSION_H_
+
+#include "utils/shared_ptr.h"
+
+namespace application_manager {
+
+typedef int AppExtensionUID;
+
+class AppExtension {
+ public:
+ explicit AppExtension(AppExtensionUID uid) : kUid_(uid) {}
+ virtual ~AppExtension() {}
+ AppExtensionUID uid() const {
+ return kUid_;
+ }
+
+ private:
+ const AppExtensionUID kUid_;
+};
+
+typedef utils::SharedPtr<AppExtension> AppExtensionPtr;
+
+} // namespace application_manager
+
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_EXTENSION_H_
diff --git a/src/components/application_manager/include/application_manager/core_service.h b/src/components/application_manager/include/application_manager/core_service.h
new file mode 100644
index 0000000000..d746b953dc
--- /dev/null
+++ b/src/components/application_manager/include/application_manager/core_service.h
@@ -0,0 +1,248 @@
+/**
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_CORE_SERVICE_H_
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_CORE_SERVICE_H_
+
+#include <string>
+#include <vector>
+#include "application_manager/service.h"
+#include "application_manager/application.h"
+#include "policy/policy_types.h"
+
+namespace Json {
+class Value;
+}
+
+namespace application_manager {
+
+struct CommandParametersPermissions;
+
+/**
+ * @brief Class through which the plug-in can interact with the core
+ */
+class CoreService : public Service {
+ public:
+ /**
+ * @brief CoreService class destructor
+ */
+ explicit CoreService(ApplicationManager& application_manager);
+
+ /**
+ * @brief CoreService class destructor
+ */
+ virtual ~CoreService();
+
+ /**
+ * @brief Checks message permissions and cuts parameters according
+ * to policy table permissions
+ * @param msg message to cut disallowed parameters
+ * @return result according by mobile API
+ */
+ mobile_apis::Result::eType CheckPolicyPermissions(MessagePtr msg) FINAL;
+
+ /**
+ * Checks access to requested equipment of vehicle
+ * @param app_id id of application
+ * @param module type
+ * @param rpc name of rpc
+ * @param params parameters list
+ * @return return allowed if access exist,
+ * manual if need to send question to driver otherwise disallowed
+ */
+ TypeAccess CheckAccess(const ApplicationId& app_id,
+ const std::string& module,
+ const std::string& rpc,
+ const std::vector<std::string>& params) FINAL;
+
+ /**
+ * Checks access to module for application
+ * @param app_id id of application
+ * @param module type
+ * @return true if module is allowed for application
+ */
+ bool CheckModule(const ApplicationId& app_id,
+ const std::string& module) FINAL;
+
+ /**
+ * Sets access to functional group which contains given RPC for application
+ * @param app_id id of application
+ * @param module type
+ * @param allowed true if driver has given access
+ */
+ void SetAccess(const ApplicationId& app_id,
+ const std::string& module,
+ bool allowed) FINAL;
+
+ /**
+ * Resets access by group name for all applications
+ * @param group_name group name
+ */
+ void ResetAccess(const ApplicationId& app_id) FINAL;
+
+ /**
+ * Resets access by module type for all applications
+ * @param module type
+ */
+ void ResetAccess(const std::string& module) FINAL;
+
+ /**
+ * Gets device handler for device with certain ID
+ * @param device_id the ID of the connected device
+ * @return device handler if device with requested ID was found
+ */
+ uint32_t GetDeviceHandlerById(const std::string& device_id) FINAL;
+
+ /**
+ * Sets device as primary device
+ * @param dev_id ID device
+ */
+ void SetPrimaryDevice(const uint32_t dev_id) FINAL;
+
+ /**
+ * Resets driver's device
+ */
+ void ResetPrimaryDevice() FINAL;
+
+ /**
+ * Return id of primary device
+ */
+ uint32_t PrimaryDevice() const FINAL;
+
+ /**
+ * Sets mode of remote control (on/off)
+ * @param enabled true if remote control is turned on
+ */
+ void SetRemoteControl(bool enabled) FINAL;
+
+ /**
+ * @brief Is Remote Control allowed by Policy and User
+ */
+ bool IsRemoteControlAllowed() const FINAL;
+
+ /**
+ * Checks if application has remote control functions
+ * @param app application
+ * @return true if application has remote control functions
+ */
+ bool IsRemoteControlApplication(ApplicationSharedPtr app) const FINAL;
+
+ /**
+ * Removes fake parameters from request to HMI
+ * @param message message to handle
+ */
+ void RemoveHMIFakeParameters(application_manager::MessagePtr& message) FINAL;
+
+ /**
+ * @brief Get pointer to application by application id
+ * @param app_id application id
+ * return pointer to application
+ */
+ ApplicationSharedPtr GetApplication(ApplicationId app_id) FINAL;
+
+ /**
+ * @brief Send message to HMI
+ * @param message Message to HMI
+ */
+ void SendMessageToHMI(const MessagePtr& message) FINAL;
+
+ /**
+ * @brief Send message to mobile device
+ * @param message Message to mobile
+ */
+ void SendMessageToMobile(const MessagePtr& message) FINAL;
+
+ /**
+ * @brief Returns unique correlation ID for next HMI request
+ *
+ * @return Unique correlation ID
+ */
+ uint32_t GetNextCorrelationID() FINAL;
+
+ /**
+ * @brief Returns all applications
+ *
+ * @return List with shared pointers to applications
+ */
+ std::vector<ApplicationSharedPtr> GetApplications(AppExtensionUID uid) FINAL;
+
+ /**
+ * @brief Subscribes to notification from HMI
+ * @param hmi_notification string with notification name
+ */
+ void SubscribeToHMINotification(const std::string& hmi_notification) FINAL;
+
+ /**
+ * @brief Change hmi level of app and notify it
+ * @param app Application to be changed and notified
+ * @param level New HMI level of app
+ */
+ void ChangeNotifyHMILevel(ApplicationSharedPtr app,
+ mobile_apis::HMILevel::eType level) FINAL;
+
+ /**
+ * @brief Notify HMI about app changing HMI Level
+ * only NONE, BACKGROUND and LIMITED levels are sent
+ * @param app Application to be changed and notified
+ * @param level New HMI level of app
+ */
+ void NotifyHMIAboutHMILevel(ApplicationSharedPtr app,
+ mobile_apis::HMILevel::eType level) FINAL;
+
+ /**
+ * Gets all allowed module types
+ * @param app_id unique identifier of application
+ * @param list of allowed module types
+ * @return true if application has allowed modules
+ */
+ bool GetModuleTypes(const std::string& policy_app_id,
+ std::vector<std::string>* modules) const FINAL;
+
+ MessageValidationResult ValidateMessageBySchema(
+ const Message& message) OVERRIDE;
+
+ private:
+ bool AreParametersAllowed(MessagePtr msg,
+ const CommandParametersPermissions& params);
+ bool CheckParams(const Json::Value& object,
+ const policy::RPCParams& allowed_params);
+ bool IsAllowed(const std::string& name,
+ const policy::RPCParams& allowed_params);
+
+ ApplicationManager& application_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(CoreService);
+};
+
+} // namespace application_manager
+
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_CORE_SERVICE_H_
diff --git a/src/components/application_manager/include/application_manager/service.h b/src/components/application_manager/include/application_manager/service.h
new file mode 100644
index 0000000000..4eea2b0b0f
--- /dev/null
+++ b/src/components/application_manager/include/application_manager/service.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2017, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_SERVICE_H_
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_SERVICE_H_
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include "application_manager/application.h"
+#include "application_manager/message.h"
+
+namespace application_manager {
+
+enum TypeAccess { kNone, kDisallowed, kAllowed, kManual };
+
+enum MessageValidationResult {
+ SUCCESS = 0,
+ INVALID_JSON,
+ INVALID_METADATA,
+ SCHEMA_MISMATCH,
+ UNSUPPORTED_PROTOCOL
+};
+
+typedef std::string PluginFunctionID;
+
+/**
+ * @brief Interface to core service
+ */
+class Service {
+ public:
+ virtual ~Service() {}
+
+ /**
+ * @brief Checks message permissions and cuts parameters according
+ * to policy table permissions
+ * @param msg message to cut disallowed parameters
+ * @return result according by mobile API
+ */
+ virtual mobile_apis::Result::eType CheckPolicyPermissions(MessagePtr msg) = 0;
+
+ /**
+ * Checks access to requested equipment of vehicle
+ * @param app_id id of application
+ * @param module type
+ * @param rpc name of rpc
+ * @param params parameters list
+ * @return return allowed if access exist,
+ * manual if need to send question to driver otherwise disallowed
+ */
+ virtual TypeAccess CheckAccess(const ApplicationId& app_id,
+ const std::string& module,
+ const std::string& rpc,
+ const std::vector<std::string>& params) = 0;
+
+ /**
+ * Checks access to module for application
+ * @param app_id id of application
+ * @param module type
+ * @return true if module is allowed for application
+ */
+ virtual bool CheckModule(const ApplicationId& app_id,
+ const std::string& module) = 0;
+
+ /**
+ * Sets access to functional group which contains given RPC for application
+ * @param app_id id of application
+ * @param module type
+ * @param allowed true if driver has given access
+ */
+ virtual void SetAccess(const ApplicationId& app_id,
+ const std::string& module,
+ bool allowed) = 0;
+
+ /**
+ * Resets access application to all resources
+ * @param app_id ID application
+ */
+ virtual void ResetAccess(const ApplicationId& app_id) = 0;
+
+ /**
+ * Resets access by module and interior zone for all applications
+ * @param module type
+ */
+ virtual void ResetAccess(const std::string& module) = 0;
+
+ /**
+ * Gets device handler for device with certain ID
+ * @param device_id the ID of the connected device
+ * @return device handler if device with requested ID was found
+ */
+ virtual uint32_t GetDeviceHandlerById(const std::string& device_id) = 0;
+
+ /**
+ * Sets device as primary device
+ * @param dev_id ID device
+ */
+ virtual void SetPrimaryDevice(const uint32_t dev_id) = 0;
+
+ /**
+ * Resets driver's device
+ */
+ virtual void ResetPrimaryDevice() = 0;
+
+ /**
+ * Return id of primary device
+ */
+ virtual uint32_t PrimaryDevice() const = 0;
+
+ /**
+ * Sets mode of remote control (on/off)
+ * @param enabled true if remote control is turned on
+ */
+ virtual void SetRemoteControl(bool enabled) = 0;
+
+ /**
+ * @brief Is Remote Control allowed by Policy and User
+ */
+ virtual bool IsRemoteControlAllowed() const = 0;
+
+ /**
+ * @brief Get pointer to application by application id
+ * @param app_id application id
+ * return pointer to application
+ */
+ virtual ApplicationSharedPtr GetApplication(ApplicationId app_id) = 0;
+
+ /**
+ * Removes fake parameters from request to HMI
+ * @param message message to handle
+ */
+ virtual void RemoveHMIFakeParameters(
+ application_manager::MessagePtr& message) = 0;
+ /**
+ * @brief Send message to HMI
+ * @param message Message to HMI
+ */
+ virtual void SendMessageToHMI(const MessagePtr& message) = 0;
+
+ /**
+ * @brief Send message to mobile device
+ * @param message Message to mobile
+ */
+ virtual void SendMessageToMobile(const MessagePtr& message) = 0;
+
+ /**
+ * @brief Returns unique correlation ID for next HMI request
+ *
+ * @return Unique correlation ID
+ */
+ virtual uint32_t GetNextCorrelationID() = 0;
+
+ /**
+ * @brief Returns all applications related to plugin
+ * @param uid ID provided by plugin to its extension to app.
+ * @return List with shared pointers to applications
+ */
+ virtual std::vector<ApplicationSharedPtr> GetApplications(
+ AppExtensionUID uid) = 0;
+
+ /**
+ * @brief Subscribes to notification from HMI
+ * @param hmi_notification string with notification name
+ */
+ virtual void SubscribeToHMINotification(
+ const std::string& hmi_notification) = 0;
+
+ /**
+ * @brief Change hmi level of app and notify it
+ * @param app Application to be changed and notified
+ * @param level New HMI level of app
+ */
+ virtual void ChangeNotifyHMILevel(ApplicationSharedPtr app,
+ mobile_apis::HMILevel::eType level) = 0;
+
+ /**
+ * @brief Notify HMI about app changing HMI Level
+ * only NONE, BACKGROUND and LIMITED levels are sent
+ * @param app Application to be changed and notified
+ * @param level New HMI level of app
+ */
+ virtual void NotifyHMIAboutHMILevel(ApplicationSharedPtr app,
+ mobile_apis::HMILevel::eType level) = 0;
+
+ /**
+ * Checks if application has remote control functions
+ * @param app application
+ * @return true if application has remote control functions
+ */
+ virtual bool IsRemoteControlApplication(ApplicationSharedPtr app) const = 0;
+
+ /**
+ * Gets all allowed module types
+ * @param app_id unique identifier of application
+ * @param list of allowed module types
+ * @return true if application has allowed modules
+ */
+ virtual bool GetModuleTypes(const std::string& policy_app_id,
+ std::vector<std::string>* modules) const = 0;
+
+ /**
+ * @brief ValidateMessageBySchema validates message by xml schema
+ * @param message message for validation
+ * @return true if message is valid according to schema, otherwise false
+ */
+ virtual MessageValidationResult ValidateMessageBySchema(
+ const Message& message) = 0;
+};
+
+typedef utils::SharedPtr<Service> ServicePtr;
+
+} // namespace application_manager
+
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_SERVICE_H_
diff --git a/src/components/application_manager/src/core_service.cc b/src/components/application_manager/src/core_service.cc
new file mode 100644
index 0000000000..5aca2e4c34
--- /dev/null
+++ b/src/components/application_manager/src/core_service.cc
@@ -0,0 +1,306 @@
+/**
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <vector>
+#include <algorithm>
+#include "application_manager/core_service.h"
+#include "application_manager/application_manager_impl.h"
+#include "application_manager/policies/policy_handler.h"
+#include "application_manager/message_helper.h"
+#include "json/json.h"
+#include "interfaces/HMI_API.h"
+
+namespace application_manager {
+
+namespace {
+struct AppExtensionPredicate {
+ AppExtensionUID uid;
+ bool operator()(const ApplicationSharedPtr app) {
+ return app ? app->QueryInterface(uid).valid() : false;
+ }
+};
+}
+
+CoreService::CoreService(ApplicationManager& application_manager)
+ : application_manager_(application_manager) {}
+
+CoreService::~CoreService() {}
+
+mobile_apis::Result::eType CoreService::CheckPolicyPermissions(MessagePtr msg) {
+ ApplicationSharedPtr app = GetApplication(msg->connection_key());
+ if (!app) {
+ return mobile_apis::Result::eType::APPLICATION_NOT_REGISTERED;
+ }
+
+#ifdef SDL_REMOTE_CONTROL
+ const RPCParams rpc_params;
+ CommandParametersPermissions params;
+ const mobile_apis::Result::eType ret =
+ application_manager_.CheckPolicyPermissions(
+ app, msg->function_name(), rpc_params, &params);
+
+ if (ret != mobile_apis::Result::eType::SUCCESS) {
+ return ret;
+ }
+
+ if (!AreParametersAllowed(msg, params)) {
+ return mobile_apis::Result::eType::DISALLOWED;
+ }
+
+ return ret;
+#else
+ return mobile_apis::Result::eType::SUCCESS;
+#endif // SDL_REMOTE_CONTROL
+}
+
+TypeAccess CoreService::CheckAccess(const ApplicationId& app_id,
+ const std::string& module,
+ const std::string& rpc,
+ const std::vector<std::string>& params) {
+#ifdef SDL_REMOTE_CONTROL
+ ApplicationSharedPtr app = GetApplication(app_id);
+ if (app) {
+ std::string device_handle = MessageHelper::GetDeviceMacAddressForHandle(
+ app->device(), application_manager_);
+ return application_manager_.GetPolicyHandler().CheckAccess(
+ device_handle, app->policy_app_id(), module, rpc, params);
+ }
+#endif // SDL_REMOTE_CONTROL
+ return kNone;
+}
+
+bool CoreService::CheckModule(const ApplicationId& app_id,
+ const std::string& module) {
+#ifdef SDL_REMOTE_CONTROL
+ ApplicationSharedPtr app = GetApplication(app_id);
+ if (app) {
+ return application_manager_.GetPolicyHandler().CheckModule(
+ app->policy_app_id(), module);
+ }
+#endif // SDL_REMOTE_CONTROL
+ return false;
+}
+
+void CoreService::SetAccess(const ApplicationId& app_id,
+ const std::string& module,
+ bool allowed) {
+#ifdef SDL_REMOTE_CONTROL
+ ApplicationSharedPtr app = GetApplication(app_id);
+ if (app) {
+ std::string device_handle = MessageHelper::GetDeviceMacAddressForHandle(
+ app->device(), application_manager_);
+ application_manager_.GetPolicyHandler().SetAccess(
+ device_handle, app->policy_app_id(), module, allowed);
+ }
+#endif // SDL_REMOTE_CONTROL
+}
+
+void CoreService::ResetAccess(const ApplicationId& app_id) {
+#ifdef SDL_REMOTE_CONTROL
+ ApplicationSharedPtr app = GetApplication(app_id);
+ if (app) {
+ std::string device_handle = MessageHelper::GetDeviceMacAddressForHandle(
+ app->device(), application_manager_);
+ application_manager_.GetPolicyHandler().ResetAccess(device_handle,
+ app->policy_app_id());
+ }
+#endif // SDL_REMOTE_CONTROL
+}
+
+void CoreService::ResetAccess(const std::string& module) {
+#ifdef SDL_REMOTE_CONTROL
+ application_manager_.GetPolicyHandler().ResetAccess(module);
+#endif // SDL_REMOTE_CONTROL
+}
+
+uint32_t CoreService::GetDeviceHandlerById(const std::string& device_id) {
+ uint32_t device_handle = 0;
+ application_manager_.connection_handler().GetDeviceID(device_id,
+ &device_handle);
+ return device_handle;
+}
+
+void CoreService::SetPrimaryDevice(const uint32_t dev_id) {
+#ifdef SDL_REMOTE_CONTROL
+ std::string device_handle =
+ MessageHelper::GetDeviceMacAddressForHandle(dev_id, application_manager_);
+ application_manager_.GetPolicyHandler().SetPrimaryDevice(device_handle);
+#endif // SDL_REMOTE_CONTROL
+}
+
+void CoreService::ResetPrimaryDevice() {
+#ifdef SDL_REMOTE_CONTROL
+ application_manager_.GetPolicyHandler().ResetPrimaryDevice();
+#endif // SDL_REMOTE_CONTROL
+}
+
+uint32_t CoreService::PrimaryDevice() const {
+#ifdef SDL_REMOTE_CONTROL
+ return application_manager_.GetPolicyHandler().PrimaryDevice();
+#endif // SDL_REMOTE_CONTROL
+ return 0;
+}
+
+void CoreService::SetRemoteControl(bool enabled) {
+#ifdef SDL_REMOTE_CONTROL
+ application_manager_.GetPolicyHandler().SetRemoteControl(enabled);
+#endif // SDL_REMOTE_CONTROL
+}
+
+bool CoreService::IsRemoteControlAllowed() const {
+#ifdef SDL_REMOTE_CONTROL
+ return application_manager_.GetPolicyHandler().GetRemoteControl();
+#endif // SDL_REMOTE_CONTROL
+ return false;
+}
+
+bool CoreService::IsRemoteControlApplication(ApplicationSharedPtr app) const {
+#ifdef SDL_REMOTE_CONTROL
+ return application_manager_.GetPolicyHandler().CheckHMIType(
+ app->policy_app_id(),
+ mobile_apis::AppHMIType::eType::REMOTE_CONTROL,
+ app->app_types());
+#endif // SDL_REMOTE_CONTROL
+ return false;
+}
+
+void CoreService::RemoveHMIFakeParameters(
+ application_manager::MessagePtr& message) {
+ application_manager_.RemoveHMIFakeParameters(message);
+}
+
+ApplicationSharedPtr CoreService::GetApplication(ApplicationId app_id) {
+ return application_manager_.application(app_id);
+}
+
+void CoreService::SendMessageToHMI(const MessagePtr& message) {
+ application_manager_.SendPostMessageToHMI(message);
+}
+
+void CoreService::SendMessageToMobile(const MessagePtr& message) {
+ application_manager_.SendPostMessageToMobile(message);
+}
+
+uint32_t CoreService::GetNextCorrelationID() {
+ return application_manager_.GetNextHMICorrelationID();
+}
+
+std::vector<ApplicationSharedPtr> CoreService::GetApplications(
+ AppExtensionUID uid) {
+ ApplicationSet accessor = application_manager_.applications().GetData();
+ AppExtensionPredicate predicate;
+ predicate.uid = uid;
+
+ std::vector<ApplicationSharedPtr> result;
+ ApplicationSetConstIt it =
+ std::find_if(accessor.begin(), accessor.end(), predicate);
+ while (it != accessor.end()) {
+ result.push_back(*it);
+ it = std::find_if(++it, accessor.end(), predicate);
+ }
+ return result;
+}
+
+void CoreService::SubscribeToHMINotification(
+ const std::string& hmi_notification) {
+ if (!hmi_notification.empty()) {
+ application_manager_.SubscribeToHMINotification(hmi_notification);
+ }
+}
+
+void CoreService::ChangeNotifyHMILevel(ApplicationSharedPtr app,
+ mobile_apis::HMILevel::eType level) {
+ application_manager_.ChangeAppsHMILevel(app->app_id(), level);
+ MessageHelper::SendHMIStatusNotification(*app, application_manager_);
+}
+
+void CoreService::NotifyHMIAboutHMILevel(ApplicationSharedPtr app,
+ mobile_apis::HMILevel::eType level) {
+ if (app->hmi_level() != mobile_apis::HMILevel::eType::HMI_FULL) {
+ MessageHelper::SendActivateAppToHMI(
+ app->app_id(),
+ application_manager_,
+ static_cast<hmi_apis::Common_HMILevel::eType>(level),
+ true);
+ }
+}
+
+bool CoreService::AreParametersAllowed(
+ MessagePtr msg, const CommandParametersPermissions& params) {
+ Json::Reader reader;
+ Json::Value json;
+ bool ret = reader.parse(msg->json_message(), json);
+ if (ret) {
+ return CheckParams(json.get(strings::params, Json::Value(Json::nullValue)),
+ params.allowed_params);
+ }
+ return false;
+}
+
+bool CoreService::CheckParams(const Json::Value& object,
+ const RPCParams& allowed_params) {
+ if (!object.isObject()) {
+ return true;
+ }
+ for (Json::Value::iterator i = object.begin(); i != object.end(); ++i) {
+ std::string name = i.memberName();
+ if (!IsAllowed(name, allowed_params)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool CoreService::IsAllowed(const std::string& name,
+ const RPCParams& allowed_params) {
+ return std::find(allowed_params.begin(), allowed_params.end(), name) !=
+ allowed_params.end();
+}
+
+bool CoreService::GetModuleTypes(const std::string& policy_app_id,
+ std::vector<std::string>* modules) const {
+#ifdef SDL_REMOTE_CONTROL
+ return application_manager_.GetPolicyHandler().GetModuleTypes(policy_app_id,
+ modules);
+#endif // SDL_REMOTE_CONTROL
+ return false;
+}
+
+MessageValidationResult CoreService::ValidateMessageBySchema(
+ const Message& message) {
+ const MessageValidationResult result =
+ application_manager_.ValidateMessageBySchema(message);
+ LOG4CXX_DEBUG(logger_, "Validation result : " << result);
+ return result;
+}
+
+} // namespace application_manager
diff --git a/src/components/config_profile/include/config_profile/profile.h b/src/components/config_profile/include/config_profile/profile.h
index 8a25bcf648..a177d7c410 100644
--- a/src/components/config_profile/include/config_profile/profile.h
+++ b/src/components/config_profile/include/config_profile/profile.h
@@ -176,9 +176,9 @@ class Profile : public protocol_handler::ProtocolHandlerSettings,
const uint16_t video_streaming_port() const OVERRIDE;
/**
- * @brief Returns port for audio streaming
- */
- const uint16_t audio_streaming_port() const;
+ * @brief Returns port for audio streaming
+ */
+ const uint16_t audio_streaming_port() const OVERRIDE;
/**
* @brief Returns streaming timeout
@@ -212,6 +212,11 @@ class Profile : public protocol_handler::ProtocolHandlerSettings,
const std::vector<std::string>& vr_commands() const;
/**
+ * @brief Returns folder containing all plugins
+ */
+ const std::string& plugins_folder() const;
+
+ /**
* @brief Maximum command id available for mobile app
*/
const uint32_t& max_cmd_id() const;
@@ -230,7 +235,7 @@ class Profile : public protocol_handler::ProtocolHandlerSettings,
/**
* @brief Returns desirable thread stack size
*/
- const uint64_t& thread_min_stack_size() const;
+ const uint64_t thread_min_stack_size() const;
/**
* @brief Returns true if audio mixing is supported
@@ -365,10 +370,19 @@ class Profile : public protocol_handler::ProtocolHandlerSettings,
// TransportManageSettings interface
+ /*
+ * @brief Returns true if last state singleton is used
+ */
bool use_last_state() const OVERRIDE;
+ /**
+ * @brief Timeout in transport manager before disconnect
+ */
uint32_t transport_manager_disconnect_timeout() const OVERRIDE;
+ /**
+ * @brief Returns port for TCP transport adapter
+ */
uint16_t transport_manager_tcp_adapter_port() const OVERRIDE;
// TransportManageMMESettings interface
@@ -880,6 +894,7 @@ class Profile : public protocol_handler::ProtocolHandlerSettings,
std::string iap_pool_protocol_mask_;
std::string iap_system_config_;
std::string iap2_system_config_;
+ std::string plugins_folder_;
int iap2_hub_connect_attempts_;
int iap_hub_connection_wait_timeout_;
uint16_t tts_global_properties_timeout_;
diff --git a/src/components/config_profile/src/profile.cc b/src/components/config_profile/src/profile.cc
index 58709b876c..6389375bb8 100644
--- a/src/components/config_profile/src/profile.cc
+++ b/src/components/config_profile/src/profile.cc
@@ -141,6 +141,7 @@ const char* kTimeoutPromptKey = "TimeOutPromt";
const char* kHelpTitleKey = "HelpTitle";
const char* kHelpCommandKey = "HelpCommand";
const char* kSystemFilesPathKey = "SystemFilesPath";
+const char* kPluginsFolderKey = "PluginFolder";
const char* kHeartBeatTimeoutKey = "HeartBeatTimeout";
const char* kMaxSupportedProtocolVersionKey = "MaxSupportedProtocolVersion";
const char* kUseLastStateKey = "UseLastState";
@@ -219,6 +220,7 @@ const char* kDefaultPreloadedPTFileName = "sdl_preloaded_pt.json";
const char* kDefaultServerAddress = "127.0.0.1";
const char* kDefaultAppInfoFileName = "app_info.dat";
const char* kDefaultSystemFilesPath = "/tmp/fs/mp/images/ivsu_cache";
+const char* kDefaultPluginsPath = "plugins";
const char* kDefaultTtsDelimiter = ",";
const uint32_t kDefaultAudioDataStoppedTimeout = 1000;
const uint32_t kDefaultVideoDataStoppedTimeout = 1000;
@@ -541,7 +543,7 @@ const uint16_t& Profile::time_testing_port() const {
return time_testing_port_;
}
-const uint64_t& Profile::thread_min_stack_size() const {
+const uint64_t Profile::thread_min_stack_size() const {
return min_tread_stack_size_;
}
@@ -661,6 +663,9 @@ const std::string& Profile::system_files_path() const {
return system_files_path_;
}
+const std::string& Profile::plugins_folder() const {
+ return plugins_folder_;
+}
const std::vector<uint32_t>& Profile::supported_diag_modes() const {
return supported_diag_modes_;
}
@@ -1556,6 +1561,10 @@ void Profile::UpdateValues() {
LOG_UPDATED_VALUE(system_files_path_, kSystemFilesPathKey, kMainSection);
+ // Plugins folder
+ ReadStringValue(
+ &plugins_folder_, kDefaultPluginsPath, kMainSection, kPluginsFolderKey);
+ LOG_UPDATED_VALUE(plugins_folder_, kPluginsFolderKey, kMainSection);
// Heartbeat timeout
ReadUIntValue(&heart_beat_timeout_,
kDefaultHeartBeatTimeout,
diff --git a/src/components/functional_module/CMakeLists.txt b/src/components/functional_module/CMakeLists.txt
new file mode 100644
index 0000000000..756a1dd2fe
--- /dev/null
+++ b/src/components/functional_module/CMakeLists.txt
@@ -0,0 +1,58 @@
+if (ENABLE_GCOV)
+ set(GCOV_FLAGS "-ftest-coverage -fprofile-arcs")
+else()
+ set(GCOV_FLAGS "")
+endif()
+
+set(CMAKE_CXX_FLAGS "-fPIC -std=gnu++0x -Wno-deprecated-declarations -Wall -Werror ${GCOV_FLAGS}")
+
+if (CMAKE_BUILD_TYPE)
+ if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
+ set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
+ set(CMAKE_CXX_FLAGS_DEBUG "")
+ else ()
+ set(CMAKE_CXX_FLAGS_RELEASE "")
+ set(CMAKE_CXX_FLAGS_DEBUG "-g3 -ggdb3 -DDEBUG")
+ endif()
+endif()
+
+set(GCOV gcov)
+
+include_directories (
+ ${COMPONENTS_DIR}/functional_module/include/
+ ${COMPONENTS_DIR}/remote_control/include/
+ ${COMPONENTS_DIR}/include/
+ ${COMPONENTS_DIR}/application_manager/include
+ ${COMPONENTS_DIR}/connection_handler/include/
+ ${COMPONENTS_DIR}/utils/include
+ ${POLICY_PATH}/include/
+ ${POLICY_GLOBAL_INCLUDE_PATH}/
+ ${COMPONENTS_DIR}/config_profile/include
+ ${COMPONENTS_DIR}/smart_objects/include
+ ${JSONCPP_INCLUDE_DIRECTORY}
+ ${LOG4CXX_INCLUDE_DIRECTORY}
+ ${CMAKE_BINARY_DIR}/src/components/
+
+ ${COMPONENTS_DIR}/application_manager/test/include/
+)
+
+set (SOURCES
+ ./src/generic_module.cc
+ ./src/plugin_manager.cc
+ ./src/settings.cc
+ ./src/timer/timer_director.cc
+)
+set (LIBRARIES
+ ApplicationManager
+)
+
+add_library("FunctionalModule" ${SOURCES})
+target_link_libraries("FunctionalModule" ${LIBRARIES} )
+
+if(ENABLE_LOG)
+ target_link_libraries("FunctionalModule" log4cxx -L${LOG4CXX_LIBS_DIRECTORY} ${GCOV})
+endif()
+
+if(BUILD_TESTS)
+ add_subdirectory(test)
+endif()
diff --git a/src/components/functional_module/include/functional_module/function_ids.h b/src/components/functional_module/include/functional_module/function_ids.h
new file mode 100644
index 0000000000..5b8218e37b
--- /dev/null
+++ b/src/components/functional_module/include/functional_module/function_ids.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_FUNCTION_IDS_H_
+#define SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_FUNCTION_IDS_H_
+
+namespace functional_modules {
+
+enum RCFunctionID {
+ // Remote SDL functions ids
+ BUTTON_PRESS = 41,
+ GET_INTERIOR_VEHICLE_DATA = 43,
+ SET_INTERIOR_VEHICLE_DATA = 44,
+ ON_INTERIOR_VEHICLE_DATA = 32783,
+ ON_REMOTE_CONTROL_SETTINGS,
+};
+
+namespace hmi_api {
+const char get_interior_vehicle_data[] = "RC.GetInteriorVehicleData";
+const char set_interior_vehicle_data[] = "RC.SetInteriorVehicleData";
+const char on_interior_vehicle_data[] = "RC.OnInteriorVehicleData";
+const char button_press[] = "Buttons.ButtonPress";
+const char on_remote_control_settings[] = "RC.OnRemoteControlSettings";
+
+const char get_user_consent[] = "RC.GetInteriorVehicleDataConsent";
+const char on_app_deactivated[] = "BasicCommunication.OnAppDeactivated";
+const char sdl_activate_app[] = "SDL.ActivateApp";
+}
+
+} // namespace functional_modules
+
+#endif // SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_FUNCTION_IDS_H_
diff --git a/src/components/functional_module/include/functional_module/generic_module.h b/src/components/functional_module/include/functional_module/generic_module.h
new file mode 100644
index 0000000000..9d003f4e28
--- /dev/null
+++ b/src/components/functional_module/include/functional_module/generic_module.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_GENERIC_MODULE_H_
+#define SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_GENERIC_MODULE_H_
+
+#include <deque>
+#include <string>
+#include "functional_module/module_observer.h"
+#include "functional_module/function_ids.h"
+#include "utils/shared_ptr.h"
+#include "application_manager/service.h"
+
+namespace functional_modules {
+
+enum ProcessResult {
+ NONE = -1,
+ PROCESSED,
+ PARTIALLY_PROCESSED,
+ CANNOT_PROCESS,
+ FAILED
+};
+
+enum ServiceState { IDLE = 0, SUSPENDED, LOWVOLTAGE, HMI_ADAPTER_INITIALIZED };
+
+typedef std::string HMIFunctionID;
+
+class GenericModule;
+typedef utils::SharedPtr<GenericModule> ModulePtr;
+
+struct PluginInfo {
+ std::string name;
+ int version;
+ std::deque<RCFunctionID> rc_function_list;
+ std::deque<HMIFunctionID> hmi_function_list;
+};
+
+class GenericModule {
+ public:
+ typedef std::deque<ModuleObserver*> Observers;
+
+ virtual ~GenericModule();
+ ModuleID GetModuleID() const {
+ return kModuleId_;
+ }
+ virtual PluginInfo GetPluginInfo() const = 0;
+
+ virtual void set_service(application_manager::ServicePtr service);
+
+ /**
+ * @brief Returns pointer to SDL core service interface
+ * @return pointer to core service interface
+ */
+ virtual application_manager::ServicePtr service();
+
+ virtual ProcessResult ProcessMessage(application_manager::MessagePtr msg) = 0;
+ virtual ProcessResult ProcessHMIMessage(
+ application_manager::MessagePtr msg) = 0;
+ virtual void OnServiceStateChanged(ServiceState state);
+
+ /**
+ * @brief Adds pointer to observer of module to be notified about
+ * exceptional sutiations in module.
+ * Raw pointer is passed to avoid circular dependencies.
+ * Module is not responsible for freeing observer's memory.
+ */
+ void AddObserver(ModuleObserver* const observer);
+
+ /**
+ * @brief Removes pointer to observer of module when it's no loger
+ * wants to be notified about exceptional sutiations in module.
+ * Raw pointer is passed to avoid circular dependencies.
+ * Module is not responsible for freeing observer's memory.
+ */
+ void RemoveObserver(ModuleObserver* const observer);
+
+ /**
+ * @brief Remove extension created for specified application
+ * @param app_id application id
+ */
+ virtual void RemoveAppExtension(uint32_t app_id) = 0;
+
+ /**
+ * @brief Check registering app can be handled by plugin
+ * @param msg Registration message
+ * @param app Application basis already create by Core
+ */
+ virtual bool IsAppForPlugin(
+ application_manager::ApplicationSharedPtr app) = 0;
+
+ /**
+ * @brief Notify about change of HMILevel of plugin's app
+ * @param app App with new HMILevel
+ * @param old_level Old HMILevel of app
+ */
+ virtual void OnAppHMILevelChanged(
+ application_manager::ApplicationSharedPtr app,
+ mobile_apis::HMILevel::eType old_level) = 0;
+
+ /**
+ * @brief Checks if plugin hasn't put restrictions on app's HMI Level
+ * @param app App with old HMILevel
+ * @param new_level HMILevel which is about to be set to app
+ */
+ virtual bool CanAppChangeHMILevel(
+ application_manager::ApplicationSharedPtr app,
+ mobile_apis::HMILevel::eType new_level) {
+ return true;
+ }
+
+ /**
+ * Handles removing (disconnecting) device
+ * @param device removed
+ */
+ virtual void OnDeviceRemoved(
+ const connection_handler::DeviceHandle& device) = 0;
+
+ /**
+ * @brief OnUnregisterApplication handles application unregistering event
+ * @param app_id application id which was unregistered
+ */
+ virtual void OnUnregisterApplication(const uint32_t app_id) = 0;
+
+ protected:
+ explicit GenericModule(ModuleID module_id);
+ void NotifyObservers(ModuleObserver::Errors error);
+
+ /**
+ * @brief Remove extension for all applications
+ */
+ virtual void RemoveAppExtensions() = 0;
+
+ private:
+ application_manager::ServicePtr service_;
+ const ModuleID kModuleId_;
+
+ Observers observers_;
+ ServiceState state_;
+
+ friend class DriverGenericModuleTest;
+ DISALLOW_COPY_AND_ASSIGN(GenericModule);
+};
+
+} // namespace functional_modules
+
+#endif // SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_GENERIC_MODULE_H_
diff --git a/src/components/functional_module/include/functional_module/module_observer.h b/src/components/functional_module/include/functional_module/module_observer.h
new file mode 100644
index 0000000000..1608ef5d42
--- /dev/null
+++ b/src/components/functional_module/include/functional_module/module_observer.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_MODULE_OBSERVER_H_
+#define SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_MODULE_OBSERVER_H_
+
+namespace functional_modules {
+
+typedef int ModuleID;
+
+class ModuleObserver {
+ public:
+ enum Errors { NONE = -1, OUT_OF_MEMORY, FS_FAILURE };
+ virtual ~ModuleObserver() {}
+ virtual void OnError(Errors error, ModuleID module_id) = 0;
+};
+} // namespace functional_modules {
+
+#endif // SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_MODULE_OBSERVER_H_
diff --git a/src/components/functional_module/include/functional_module/plugin_manager.h b/src/components/functional_module/include/functional_module/plugin_manager.h
new file mode 100644
index 0000000000..38368ab01a
--- /dev/null
+++ b/src/components/functional_module/include/functional_module/plugin_manager.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_PLUGIN_MANAGER_H_
+#define SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_PLUGIN_MANAGER_H_
+
+#include <map>
+#include <string>
+#include "functional_module/generic_module.h"
+#include "application_manager/service.h"
+#include "application_manager/message.h"
+
+namespace functional_modules {
+
+class PluginManager : public ModuleObserver {
+ public:
+ PluginManager();
+ ~PluginManager();
+ typedef std::map<ModuleID, ModulePtr> Modules;
+ int LoadPlugins(const std::string& plugin_path);
+ void UnloadPlugins();
+ void ProcessMessage(application_manager::MessagePtr msg);
+ ProcessResult ProcessHMIMessage(application_manager::MessagePtr msg);
+ void SetServiceHandler(application_manager::ServicePtr service) {
+ service_ = service;
+ }
+ bool IsMessageForPlugin(application_manager::MessagePtr msg);
+ bool IsHMIMessageForPlugin(application_manager::MessagePtr msg);
+ void OnServiceStateChanged(ServiceState state);
+ void OnHMIResponse(application_manager::MessagePtr msg);
+ void OnError(ModuleObserver::Errors error, ModuleID module_id);
+
+ /**
+ * @brief Remove extension created for specified application
+ * @param app_id application id
+ */
+ void RemoveAppExtension(uint32_t app_id);
+
+ /**
+ * @brief Check if app cooperates with one or more plugins, init it
+ * inside plugin accordingly if needed.
+ * @param app Application in question.
+ */
+ bool IsAppForPlugins(application_manager::ApplicationSharedPtr app);
+
+ /**
+ * Check if app cooperates with plugin
+ * @param app application
+ * @param module_id unique identifier of plugin
+ * @return true if application cooperates with this plugin
+ */
+ bool IsAppForPlugin(application_manager::ApplicationSharedPtr app,
+ ModuleID module_id) const;
+
+ /**
+ * @brief Notify plugins about change of HMILevel of app
+ * if app is related to plugin
+ * @param app App with new HMILevel
+ * @param old_level Old HMILevel of app
+ */
+ void OnAppHMILevelChanged(application_manager::ApplicationSharedPtr app,
+ mobile_apis::HMILevel::eType old_level);
+
+ /**
+ * @brief Checks if plugin hasn't put restrictions on app's HMI Level
+ * @param app App with old HMILevel
+ * @param new_level HMILevel which is about to be set to app
+ * @return false if any of the plugins returns false.
+ */
+ bool CanAppChangeHMILevel(application_manager::ApplicationSharedPtr app,
+ mobile_apis::HMILevel::eType new_level);
+
+ /**
+ * Handles removing (disconnecting) device
+ * @param device removed
+ */
+ void OnDeviceRemoved(const connection_handler::DeviceHandle& device);
+
+ /**
+ * @brief OnUnregisterApplication handles application unregistering event
+ * @param app_id application id which was unregistered
+ */
+ void OnUnregisterApplication(const uint32_t app_id);
+
+ Modules& plugins();
+
+ private:
+ Modules plugins_;
+ std::map<ModuleID, void*> dlls_;
+ std::map<RCFunctionID, ModulePtr> mobile_subscribers_;
+ std::map<HMIFunctionID, ModulePtr> hmi_subscribers_;
+ application_manager::ServicePtr service_;
+
+ DISALLOW_COPY_AND_ASSIGN(PluginManager);
+};
+
+} // namespace functional_modules
+
+#endif // SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_PLUGIN_MANAGER_H_
diff --git a/src/components/functional_module/include/functional_module/settings.h b/src/components/functional_module/include/functional_module/settings.h
new file mode 100644
index 0000000000..cf78c24e8b
--- /dev/null
+++ b/src/components/functional_module/include/functional_module/settings.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_SETTINGS_H_
+#define SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_SETTINGS_H_
+
+#include <string>
+#include <sstream>
+#include "json/json.h"
+#include "utils/macro.h"
+
+namespace functional_modules {
+
+/*
+ * @brief Settings class reads configuration for app from
+ * default location - smartDeviceLink.ini - or set location
+ * and provides access to them basing on template methods.
+ */
+class Settings {
+ public:
+ /*
+ * @brief Constrctor
+ */
+ Settings();
+
+ /*
+ * @brief Destructor
+ */
+ virtual ~Settings();
+
+ /*
+ * @brief Template method reads value from config file
+ * stored under param_name in section_name paragraph
+ * @param section_name Section name i.e [HMI]
+ * @param param_name Parameter name i.e. ServerAddress
+ * @returns True if value was read from config file, false otherwise
+ */
+ template <class T>
+ bool ReadParameter(const std::string& section_name,
+ const std::string& param_name,
+ T* param_value) const;
+
+ /*
+ * @brief Template method reads value from config file
+ * stored under param_name in [MAIN] paragraph
+ * @param param_name Parameter name i.e. ServerAddress
+ * @returns True if value was read from config file, false otherwise
+ */
+ template <class T>
+ bool ReadParameter(const std::string& param_name, T* param_value) const;
+
+ /*
+ * @brief Changes path to configuration file
+ * @param new_path Path to config file
+ */
+ void ChangeConfigFile(const std::string& new_path);
+
+ protected:
+ virtual std::string ReadParameter(const std::string& section_name,
+ const std::string& param_name) const;
+
+ private:
+ const std::string kConfigFile_;
+ std::string config_file_;
+};
+
+template <class T>
+bool Settings::ReadParameter(const std::string& section_name,
+ const std::string& param_name,
+ T* param_value) const {
+ DCHECK(param_value);
+ bool result = false;
+ if (!param_value) {
+ return result;
+ }
+
+ std::string param_string = ReadParameter(section_name, param_name);
+
+ if (!param_string.empty()) {
+ std::stringstream stream(param_string);
+ stream >> (*param_value);
+ result = true;
+ }
+
+ return result;
+}
+
+template <class T>
+bool Settings::ReadParameter(const std::string& param_name,
+ T* param_value) const {
+ return ReadParameter<T>("MAIN", param_name, param_value);
+}
+
+} // namespace functional_modules
+
+#endif // SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_SETTINGS_H_
diff --git a/src/components/functional_module/include/functional_module/timer/module_timer.h b/src/components/functional_module/include/functional_module/timer/module_timer.h
new file mode 100644
index 0000000000..d7fc0ba043
--- /dev/null
+++ b/src/components/functional_module/include/functional_module/timer/module_timer.h
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_TIMER_MODULE_TIMER_H_
+#define SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_TIMER_MODULE_TIMER_H_
+
+#include <list>
+#include <deque>
+#include <algorithm>
+#include <time.h>
+#include "utils/lock.h"
+
+namespace functional_modules {
+
+typedef unsigned int TimeUnit; // seconds
+
+class Trackable {
+ public:
+ Trackable() : start_time_(0) {}
+ virtual ~Trackable() {}
+ virtual TimeUnit custom_interval() const {
+ return 0;
+ }
+ virtual TimeUnit start_time() const {
+ return start_time_;
+ }
+ virtual void set_start_time(TimeUnit start_time) {
+ start_time_ = start_time;
+ }
+
+ private:
+ TimeUnit start_time_;
+};
+
+template <class Trackable>
+class TimerObserver {
+ public:
+ virtual ~TimerObserver() {}
+ virtual void OnTimeoutTriggered(const Trackable& expired) = 0;
+};
+
+template <class Trackable>
+class ModuleTimer {
+ public:
+ ModuleTimer();
+ ~ModuleTimer();
+ void set_period(TimeUnit period) {
+ period_ = period;
+ }
+ TimeUnit period() const {
+ return period_;
+ }
+ void AddObserver(TimerObserver<Trackable>* observer);
+ void RemoveObserver(TimerObserver<Trackable>* observer);
+
+ void CheckTimeout();
+ /**
+ * @brief Gets time in seconds when the nearest request timeout will be
+ * triggered
+ * @return time in seconds when the nearest request timeout will be triggered
+ */
+ TimeUnit GetSecondsToNearestTimeout();
+
+ /*
+ * @brief Adds object to be tracked by timer.
+ If same object is already added replaces it with new one
+ correspondingly updating start time of tracking.
+ */
+ void AddTrackable(const Trackable& object);
+ void RemoveTrackable(const Trackable& object);
+
+ protected:
+ void Notify(const Trackable& object);
+ void OnTimeout(const Trackable& object);
+ TimeUnit CurrentTime() const;
+ typename std::list<Trackable> trackables_;
+ volatile TimeUnit period_;
+
+ private:
+ std::deque<TimerObserver<Trackable>*> observers_;
+ mutable sync_primitives::Lock trackables_lock_;
+ friend class ModuleTimerTest;
+};
+
+template <class Trackable>
+ModuleTimer<Trackable>::ModuleTimer()
+ : period_(10) {}
+
+template <class Trackable>
+ModuleTimer<Trackable>::~ModuleTimer() {
+ observers_.clear();
+ sync_primitives::AutoLock auto_lock(trackables_lock_);
+ trackables_.clear();
+}
+
+template <class Trackable>
+void ModuleTimer<Trackable>::AddObserver(TimerObserver<Trackable>* observer) {
+ DCHECK(observer);
+ if (!observer) {
+ return;
+ }
+ observers_.push_back(observer);
+}
+
+template <class Trackable>
+void ModuleTimer<Trackable>::RemoveObserver(
+ TimerObserver<Trackable>* observer) {
+ DCHECK(observer);
+ if (!observer) {
+ return;
+ }
+ for (typename std::deque<TimerObserver<Trackable>*>::iterator it =
+ observers_.begin();
+ observers_.end() != it;
+ ++it) {
+ if (*it == observer) {
+ observers_.erase(it);
+ return;
+ }
+ }
+}
+
+template <class Trackable>
+void ModuleTimer<Trackable>::CheckTimeout() {
+ sync_primitives::AutoLock trackables_lock(trackables_lock_);
+ for (typename std::list<Trackable>::iterator it = trackables_.begin();
+ trackables_.end() != it;
+ ++it) {
+ TimeUnit period = it->custom_interval();
+ if (!period) {
+ period = period_;
+ }
+ if (CurrentTime() - it->start_time() >= period) {
+ OnTimeout(*it);
+ it = trackables_.erase(it);
+ }
+ }
+}
+
+template <class Trackable>
+TimeUnit ModuleTimer<Trackable>::GetSecondsToNearestTimeout() {
+ sync_primitives::AutoLock trackables_lock(trackables_lock_);
+ TimeUnit result = period_;
+ for (typename std::list<Trackable>::iterator it = trackables_.begin();
+ trackables_.end() != it;
+ ++it) {
+ TimeUnit period = it->custom_interval();
+ if (!period) {
+ period = period_;
+ }
+ const TimeUnit current_secs_to_timeout =
+ period - (CurrentTime() - it->start_time());
+ if (result > current_secs_to_timeout) {
+ result = current_secs_to_timeout;
+ }
+ }
+ return result;
+}
+
+template <class Trackable>
+void ModuleTimer<Trackable>::AddTrackable(const Trackable& object) {
+ sync_primitives::AutoLock trackables_lock(trackables_lock_);
+ trackables_.remove(object);
+ trackables_.push_back(object);
+ trackables_.back().set_start_time(CurrentTime());
+}
+
+template <class Trackable>
+void ModuleTimer<Trackable>::RemoveTrackable(const Trackable& object) {
+ sync_primitives::AutoLock trackables_lock(trackables_lock_);
+ trackables_.remove(object);
+}
+
+template <class Trackable>
+void ModuleTimer<Trackable>::Notify(const Trackable& object) {
+ for (typename std::deque<TimerObserver<Trackable>*>::const_iterator it =
+ observers_.begin();
+ observers_.end() != it;
+ ++it) {
+ (*it)->OnTimeoutTriggered(object);
+ }
+}
+
+template <class Trackable>
+void ModuleTimer<Trackable>::OnTimeout(const Trackable& object) {
+ Notify(object);
+}
+
+template <class Trackable>
+TimeUnit ModuleTimer<Trackable>::CurrentTime() const {
+ // TODO(PV): move outside to platform-dependant parts
+ struct timespec current_time;
+ if (0 == clock_gettime(CLOCK_MONOTONIC, &current_time)) {
+ return current_time.tv_sec;
+ } else {
+ return 0;
+ }
+}
+
+} // namespace functional_modules
+
+#endif // SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_TIMER_MODULE_TIMER_H_
diff --git a/src/components/functional_module/include/functional_module/timer/timer_director.h b/src/components/functional_module/include/functional_module/timer/timer_director.h
new file mode 100644
index 0000000000..65f9f4a6d5
--- /dev/null
+++ b/src/components/functional_module/include/functional_module/timer/timer_director.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_TIMER_TIMER_DIRECTOR_H_
+#define SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_TIMER_TIMER_DIRECTOR_H_
+
+#include <map>
+#include "utils/threads/thread.h"
+#include "utils/conditional_variable.h"
+#include "functional_module/timer/module_timer.h"
+
+namespace functional_modules {
+
+template <class T>
+class TimerThreadDelegate : public threads::ThreadDelegate {
+ public:
+ explicit TimerThreadDelegate(ModuleTimer<T>& timer);
+ void threadMain();
+ void exitThreadMain();
+
+ /**
+ * @brief Reset awaiting timer by notifying cond var
+ */
+ void ResetTimer();
+
+ private:
+ ModuleTimer<T>& timer_;
+ volatile bool keep_running_;
+ mutable sync_primitives::Lock keep_running_lock_;
+ mutable sync_primitives::ConditionalVariable keep_running_cond_;
+ friend class TimerThreadDelegateTest;
+};
+
+class TimerDirector {
+ public:
+ TimerDirector();
+ ~TimerDirector();
+
+ /**
+ * @brief Register timer for execution in separate thread.
+ Registers only one timer of a type. Attempt to register timer
+ of already existing type will fail.
+ */
+ template <class T>
+ void RegisterTimer(ModuleTimer<T>& timer);
+ template <class T>
+ void UnregisterTimer(const ModuleTimer<T>& timer);
+ void UnregisterAllTimers();
+ /**
+ * @brief Reset awaiting timeout for specified module timer
+ * @param timer timer to reset awaiting timeout
+ */
+ template <class T>
+ void ResetTimer(ModuleTimer<T>& timer);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TimerDirector);
+ std::map<std::string, threads::Thread*> timer_threads_;
+};
+
+} // namespace functional_modules
+
+#endif // SRC_COMPONENTS_FUNCTIONAL_MODULE_INCLUDE_FUNCTIONAL_MODULE_TIMER_TIMER_DIRECTOR_H_
diff --git a/src/components/functional_module/src/generic_module.cc b/src/components/functional_module/src/generic_module.cc
new file mode 100644
index 0000000000..eec4f7b6d3
--- /dev/null
+++ b/src/components/functional_module/src/generic_module.cc
@@ -0,0 +1,63 @@
+#include "functional_module/generic_module.h"
+namespace functional_modules {
+
+typedef std::deque<ModuleObserver*>::iterator ModuleObserverIterator;
+
+GenericModule::GenericModule(ModuleID module_id)
+ : kModuleId_(module_id), state_(ServiceState::IDLE) {}
+
+GenericModule::~GenericModule() {
+ observers_.clear();
+}
+
+void GenericModule::AddObserver(ModuleObserver* const observer) {
+ DCHECK(observer);
+ if (!observer) {
+ return;
+ }
+ observers_.push_back(observer);
+}
+
+void GenericModule::RemoveObserver(ModuleObserver* const observer) {
+ DCHECK(observer);
+ if (!observer) {
+ return;
+ }
+ for (ModuleObserverIterator it = observers_.begin(); observers_.end() != it;
+ ++it) {
+ if (*it == observer) {
+ observers_.erase(it);
+ return;
+ }
+ }
+}
+
+void GenericModule::NotifyObservers(ModuleObserver::Errors error) {
+ for (ModuleObserverIterator it = observers_.begin(); observers_.end() != it;
+ ++it) {
+ (*it)->OnError(error, kModuleId_);
+ }
+}
+
+void GenericModule::set_service(application_manager::ServicePtr service) {
+ service_ = service;
+}
+
+void GenericModule::OnServiceStateChanged(ServiceState state) {
+ state_ = state;
+
+ if (HMI_ADAPTER_INITIALIZED == state_) {
+ // We must subscribe to necessary HMI notifications
+ service_->SubscribeToHMINotification(hmi_api::on_interior_vehicle_data);
+ service_->SubscribeToHMINotification(hmi_api::on_remote_control_settings);
+ // Disabled
+ // service_->SubscribeToHMINotification(hmi_api::on_reverse_apps_allowing);
+ // service_->SubscribeToHMINotification(hmi_api::on_device_rank_changed);
+ }
+}
+
+application_manager::ServicePtr GenericModule::service() {
+ return service_;
+}
+
+} // namespace functional_modules
diff --git a/src/components/functional_module/src/plugin_manager.cc b/src/components/functional_module/src/plugin_manager.cc
new file mode 100644
index 0000000000..ab3b0bda05
--- /dev/null
+++ b/src/components/functional_module/src/plugin_manager.cc
@@ -0,0 +1,405 @@
+/*
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <dlfcn.h>
+#include <algorithm>
+#include "functional_module/plugin_manager.h"
+#include "functional_module/function_ids.h"
+#include "utils/file_system.h"
+#include "utils/logger.h"
+#include "json/json.h"
+
+namespace functional_modules {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "PluginManager")
+
+typedef std::map<ModuleID, ModulePtr>::iterator PluginsIterator;
+typedef std::map<RCFunctionID, ModulePtr>::iterator PluginFunctionsIterator;
+typedef std::map<HMIFunctionID, ModulePtr>::iterator PluginHMIFunctionsIterator;
+
+PluginManager::PluginManager() : service_() {
+ LOG4CXX_DEBUG(logger_, "Creating plugin mgr");
+}
+
+PluginManager::~PluginManager() {
+ // TODO(PV): unsubscribe plugins from functions
+ mobile_subscribers_.clear();
+ hmi_subscribers_.clear();
+ UnloadPlugins();
+}
+
+int PluginManager::LoadPlugins(const std::string& plugin_path) {
+ LOG4CXX_INFO(logger_, "Loading plugins from " << plugin_path);
+ std::vector<std::string> plugin_files = file_system::ListFiles(plugin_path);
+ for (size_t i = 0; i < plugin_files.size(); ++i) {
+ size_t pos = plugin_files[i].find_last_of(".");
+ if (std::string::npos != pos) {
+ if (plugin_files[i].substr(pos + 1).compare("so") != 0) {
+ continue;
+ }
+ } else {
+ continue;
+ }
+ std::string full_name = plugin_path + '/' + plugin_files[i];
+ void* generic_plugin_dll = dlopen(full_name.c_str(), RTLD_LAZY);
+ if (NULL == generic_plugin_dll) {
+ LOG4CXX_ERROR(logger_,
+ "Failed to open dll " << plugin_files[i] << "\n"
+ << dlerror());
+ continue;
+ }
+ typedef GenericModule* (*Create)();
+ Create create_manager =
+ reinterpret_cast<Create>(dlsym(generic_plugin_dll, "Create"));
+ char* error_string = dlerror();
+ if (NULL != error_string) {
+ LOG4CXX_ERROR(logger_,
+ "Failed to export dll's " << plugin_files[i] << " symbols\n"
+ << error_string);
+ dlclose(generic_plugin_dll);
+ continue;
+ }
+ ModulePtr module = create_manager();
+ if (!module) {
+ LOG4CXX_ERROR(logger_,
+ "Failed to create plugin main class " << plugin_files[i]);
+ dlclose(generic_plugin_dll);
+ continue;
+ } else {
+ LOG4CXX_DEBUG(logger_,
+ "Opened and working plugin from " << plugin_files[i]
+ << " with id "
+ << module->GetModuleID());
+ dlls_.insert(std::pair<ModuleID, void*>(module->GetModuleID(),
+ generic_plugin_dll));
+ plugins_.insert(
+ std::pair<ModuleID, ModulePtr>(module->GetModuleID(), module));
+ std::deque<RCFunctionID> subscribers =
+ module->GetPluginInfo().rc_function_list;
+ for (size_t i = 0; i < subscribers.size(); ++i) {
+ mobile_subscribers_.insert(
+ std::pair<RCFunctionID, ModulePtr>(subscribers[i], module));
+ }
+
+ std::deque<HMIFunctionID> hmi_subscribers =
+ module->GetPluginInfo().hmi_function_list;
+ for (size_t i = 0; i < hmi_subscribers.size(); ++i) {
+ hmi_subscribers_.insert(
+ std::pair<HMIFunctionID, ModulePtr>(hmi_subscribers[i], module));
+ }
+ module->set_service(service_);
+ module->AddObserver(this);
+ }
+ }
+ return plugins_.size();
+}
+
+void PluginManager::UnloadPlugins() {
+ for (Modules::iterator it = plugins_.begin(); plugins_.end() != it; ++it) {
+ it->second->RemoveObserver(this);
+ }
+ plugins_.clear();
+
+ for (std::map<ModuleID, void*>::iterator it = dlls_.begin();
+ dlls_.end() != it;
+ ++it) {
+ dlclose(it->second);
+ }
+ dlls_.clear();
+}
+
+// TODO(VS): Optimize similar code in ProcessMessage, IsMessageForPlugin,
+// ProcessHMIMessage, IsHMIMessageForPlugin methods
+// (also we have similar code in can module)
+void PluginManager::ProcessMessage(application_manager::MessagePtr msg) {
+ DCHECK(msg);
+ if (!msg) {
+ LOG4CXX_ERROR(logger_, "Null pointer message was received.");
+ return;
+ }
+ if (application_manager::ProtocolVersion::kUnknownProtocol !=
+ msg->protocol_version() &&
+ application_manager::ProtocolVersion::kHMI != msg->protocol_version()) {
+ PluginFunctionsIterator subscribed_plugin_itr =
+ mobile_subscribers_.find(static_cast<RCFunctionID>(msg->function_id()));
+ if (mobile_subscribers_.end() != subscribed_plugin_itr) {
+ if (subscribed_plugin_itr->second->ProcessMessage(msg) !=
+ ProcessResult::PROCESSED) {
+ LOG4CXX_ERROR(logger_, "Failed process message!");
+ }
+ }
+ }
+}
+
+const std::string ExtractMethodName(const Json::Value& value) {
+ const char* kMethod = "method";
+ const char* kResult = "result";
+ const char* kError = "error";
+ const char* kData = "data";
+
+ if (value.isMember(kMethod)) {
+ return value.get(kMethod, "").asCString();
+ // Response from HMI
+ }
+ if (value.isMember(kResult)) {
+ const Json::Value& result = value.get(kResult, Json::Value());
+ return result.get(kMethod, "").asCString();
+ }
+ if (value.isMember(kError)) {
+ const Json::Value& error = value.get(kError, Json::Value());
+ const Json::Value& data = error.get(kData, Json::Value());
+ return data.get(kMethod, "").asCString();
+ }
+ LOG4CXX_WARN(logger_,
+ "Message with HMI protocol version can not be handled by "
+ "plugin manager, because required 'method' field was not "
+ "found, or was containing an invalid string.");
+ return std::string();
+}
+
+ProcessResult PluginManager::ProcessHMIMessage(
+ application_manager::MessagePtr msg) {
+ DCHECK(msg);
+ if (!msg) {
+ LOG4CXX_ERROR(logger_, "Null pointer message was received.");
+ return ProcessResult::CANNOT_PROCESS;
+ }
+
+ Json::Value value;
+ Json::Reader reader;
+ reader.parse(msg->json_message(), value);
+
+ if (application_manager::ProtocolVersion::kHMI == msg->protocol_version()) {
+ const std::string& msg_method = ExtractMethodName(value);
+ if (msg_method.empty()) {
+ return ProcessResult::CANNOT_PROCESS;
+ }
+ PluginHMIFunctionsIterator subscribed_plugin_itr =
+ hmi_subscribers_.find(msg_method);
+ if (hmi_subscribers_.end() != subscribed_plugin_itr) {
+ return subscribed_plugin_itr->second->ProcessHMIMessage(msg);
+ }
+ }
+
+ return ProcessResult::CANNOT_PROCESS;
+}
+
+bool PluginManager::IsMessageForPlugin(application_manager::MessagePtr msg) {
+ DCHECK(msg);
+ if (!msg) {
+ LOG4CXX_ERROR(logger_, "Null pointer message was received.");
+ return false;
+ }
+ if (application_manager::ProtocolVersion::kUnknownProtocol !=
+ msg->protocol_version() &&
+ application_manager::ProtocolVersion::kHMI != msg->protocol_version()) {
+ RCFunctionID id = static_cast<RCFunctionID>(msg->function_id());
+ return (mobile_subscribers_.find(id) != mobile_subscribers_.end());
+ } else {
+ return false;
+ }
+}
+
+bool PluginManager::IsHMIMessageForPlugin(application_manager::MessagePtr msg) {
+ DCHECK(msg);
+ if (!msg) {
+ LOG4CXX_ERROR(logger_, "Null pointer message was received.");
+ return false;
+ }
+
+ Json::Value value;
+ Json::Reader reader;
+ reader.parse(msg->json_message(), value);
+ if (application_manager::ProtocolVersion::kHMI == msg->protocol_version()) {
+ std::string msg_method;
+ // Request or notification from HMI
+ if (value.isMember("method") && value["method"].isString()) {
+ msg_method = value["method"].asCString();
+ // Response from HMI
+ } else if (value.isMember("result") && value["result"].isMember("method") &&
+ value["result"]["method"].isString()) {
+ msg_method = value["result"]["method"].asCString();
+ // Error response from HMI
+ } else if (value.isMember("error") && value["error"].isMember("data") &&
+ value["error"]["data"].isMember("method") &&
+ value["error"]["data"]["method"].isString()) {
+ msg_method = value["error"]["data"]["method"].asCString();
+ } else {
+ LOG4CXX_WARN(logger_,
+ "Message with HMI protocol version can not be handled by "
+ "plugin manager, because required 'method' field was not "
+ "found, or was containing an invalid string.");
+ return false;
+ }
+
+ return (hmi_subscribers_.find(msg_method) != hmi_subscribers_.end());
+ }
+
+ return false;
+}
+
+void PluginManager::OnServiceStateChanged(ServiceState state) {
+ for (PluginsIterator it = plugins_.begin(); plugins_.end() != it; ++it) {
+ it->second->OnServiceStateChanged(state);
+ }
+}
+
+void PluginManager::OnHMIResponse(application_manager::MessagePtr msg) {
+ // TODO(PV)
+}
+
+void PluginManager::OnError(ModuleObserver::Errors error, ModuleID module_id) {
+ std::string error_string;
+ switch (error) {
+ case ModuleObserver::Errors::OUT_OF_MEMORY:
+ error_string = "Module run out of memory.";
+ break;
+ case ModuleObserver::Errors::FS_FAILURE:
+ error_string = "Plugin failed to run file system operation.";
+ break;
+ default:
+ break;
+ }
+ LOG4CXX_ERROR(logger_,
+ "Error " << error_string << " was received from module "
+ << module_id);
+ // TODO(PV)
+}
+
+void PluginManager::RemoveAppExtension(uint32_t app_id) {
+ for (PluginsIterator it = plugins_.begin(); plugins_.end() != it; ++it) {
+ it->second->RemoveAppExtension(app_id);
+ }
+}
+
+bool PluginManager::IsAppForPlugins(
+ application_manager::ApplicationSharedPtr app) {
+ DCHECK(app);
+ if (!app) {
+ return false;
+ }
+
+ bool res = false;
+ for (PluginsIterator it = plugins_.begin(); plugins_.end() != it; ++it) {
+ res = res || it->second->IsAppForPlugin(app);
+ }
+ return res;
+}
+
+bool PluginManager::IsAppForPlugin(
+ application_manager::ApplicationSharedPtr app, ModuleID module_id) const {
+ Modules::const_iterator i = plugins_.find(module_id);
+ return i != plugins_.end() ? i->second->IsAppForPlugin(app) : false;
+}
+
+void PluginManager::OnAppHMILevelChanged(
+ application_manager::ApplicationSharedPtr app,
+ mobile_apis::HMILevel::eType old_level) {
+ DCHECK(app);
+ if (!app) {
+ return;
+ }
+ for (PluginsIterator it = plugins_.begin(); plugins_.end() != it; ++it) {
+ if (it->second->IsAppForPlugin(app)) {
+ LOG4CXX_DEBUG(logger_,
+ "Application " << app->name().AsMBString() << " of plugin "
+ << it->second->GetModuleID()
+ << " has changed level from " << old_level
+ << " to " << app->hmi_level());
+ it->second->OnAppHMILevelChanged(app, old_level);
+ }
+ }
+}
+
+bool PluginManager::CanAppChangeHMILevel(
+ application_manager::ApplicationSharedPtr app,
+ mobile_apis::HMILevel::eType new_level) {
+ DCHECK(app);
+ if (!app) {
+ return false;
+ }
+ bool result = true;
+ for (PluginsIterator it = plugins_.begin(); plugins_.end() != it; ++it) {
+ if (it->second->IsAppForPlugin(app)) {
+ result = result && it->second->CanAppChangeHMILevel(app, new_level);
+ LOG4CXX_DEBUG(logger_,
+ "Application " << app->name().AsMBString() << " of plugin "
+ << it->second->GetModuleID() << " is "
+ << (result ? "allowed" : "not allowed")
+ << " to change level to " << new_level);
+ }
+ }
+ return result;
+}
+
+typedef std::map<ModuleID, ModulePtr>::value_type PluginsValueType;
+struct HandleDeviceRemoved {
+ private:
+ const connection_handler::DeviceHandle& device_;
+
+ public:
+ explicit HandleDeviceRemoved(const connection_handler::DeviceHandle& device)
+ : device_(device) {}
+ void operator()(PluginsValueType& x) {
+ x.second->OnDeviceRemoved(device_);
+ }
+};
+
+void PluginManager::OnDeviceRemoved(
+ const connection_handler::DeviceHandle& device) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ std::for_each(plugins_.begin(), plugins_.end(), HandleDeviceRemoved(device));
+}
+
+struct HandleApplicationUnregistered {
+ private:
+ const uint32_t app_id_;
+
+ public:
+ explicit HandleApplicationUnregistered(const uint32_t app_id)
+ : app_id_(app_id) {}
+ void operator()(PluginsValueType& x) {
+ x.second->OnUnregisterApplication(app_id_);
+ }
+};
+
+void PluginManager::OnUnregisterApplication(const uint32_t app_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ std::for_each(
+ plugins_.begin(), plugins_.end(), HandleApplicationUnregistered(app_id));
+}
+
+PluginManager::Modules& PluginManager::plugins() {
+ return plugins_;
+}
+
+} // namespace functional_modules
diff --git a/src/components/functional_module/src/settings.cc b/src/components/functional_module/src/settings.cc
new file mode 100644
index 0000000000..29a96ba63b
--- /dev/null
+++ b/src/components/functional_module/src/settings.cc
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "functional_module/settings.h"
+#include "config_profile/ini_file.h"
+
+namespace functional_modules {
+
+Settings::Settings() : kConfigFile_("smartDeviceLink.ini") {
+ config_file_ = kConfigFile_;
+}
+
+Settings::~Settings() {
+ config_file_ = "";
+}
+
+void Settings::ChangeConfigFile(const std::string& new_path) {
+ config_file_ = new_path;
+}
+
+std::string Settings::ReadParameter(const std::string& section_name,
+ const std::string& param_name) const {
+ std::string result;
+ char param_string[INI_LINE_LEN + 1];
+ param_string[0] = '\0';
+ if (0 != profile::ini_read_value(config_file_.c_str(),
+ section_name.c_str(),
+ param_name.c_str(),
+ param_string)) {
+ result = param_string;
+ }
+ return result;
+}
+
+} // namespace functional_modules
diff --git a/src/components/functional_module/src/timer/timer_director.cc b/src/components/functional_module/src/timer/timer_director.cc
new file mode 100644
index 0000000000..51d7408fcd
--- /dev/null
+++ b/src/components/functional_module/src/timer/timer_director.cc
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <typeinfo>
+#include "functional_module/timer/timer_director.h"
+#include "remote_control/rc_module_timer.h"
+#include "utils/logger.h"
+
+namespace functional_modules {
+
+template <class T>
+TimerThreadDelegate<T>::TimerThreadDelegate(ModuleTimer<T>& timer)
+ : timer_(timer), keep_running_(false) {}
+
+template <class T>
+void TimerThreadDelegate<T>::threadMain() {
+ if (keep_running_) {
+ this->exitThreadMain();
+ }
+ {
+ sync_primitives::AutoLock run_lock(keep_running_lock_);
+ keep_running_ = true;
+ }
+ sync_primitives::AutoLock run_lock(keep_running_lock_);
+ while (keep_running_) {
+ const TimeUnit msecs_to_wait = timer_.GetSecondsToNearestTimeout() * 1000;
+ sync_primitives::ConditionalVariable::WaitStatus wait_status =
+ keep_running_cond_.WaitFor(run_lock, msecs_to_wait);
+ if (sync_primitives::ConditionalVariable::kTimeout == wait_status &&
+ keep_running_) {
+ timer_.CheckTimeout();
+ }
+ }
+}
+
+template <class T>
+void TimerThreadDelegate<T>::exitThreadMain() {
+ if (keep_running_) {
+ sync_primitives::AutoLock run_lock(keep_running_lock_);
+ keep_running_ = false;
+ keep_running_cond_.NotifyOne();
+ }
+}
+
+template <class T>
+void TimerThreadDelegate<T>::ResetTimer() {
+ if (keep_running_) {
+ sync_primitives::AutoLock run_lock(keep_running_lock_);
+ keep_running_cond_.NotifyOne();
+ }
+}
+
+TimerDirector::TimerDirector() {}
+
+TimerDirector::~TimerDirector() {
+ UnregisterAllTimers();
+}
+
+template <class T>
+void TimerDirector::RegisterTimer(ModuleTimer<T>& timer) {
+ std::string type_name = typeid(timer).name();
+ std::map<std::string, threads::Thread*>::iterator it =
+ timer_threads_.find(type_name);
+ if (timer_threads_.end() != it) {
+ // Attempt to register timer of already existing type fail.
+ return;
+ }
+ TimerThreadDelegate<T>* delegate = new TimerThreadDelegate<T>(timer);
+ threads::Thread* thread = threads::CreateThread(type_name.c_str(), delegate);
+
+ const size_t kStackSize = 16384;
+ if (thread->start(threads::ThreadOptions(kStackSize))) {
+ timer_threads_.insert(std::make_pair(type_name, thread));
+ } else {
+ // Failed to start timer thread for
+ }
+}
+
+template void TimerDirector::RegisterTimer<remote_control::TrackableMessage>(
+ ModuleTimer<remote_control::TrackableMessage>& timer);
+
+template <class T>
+void TimerDirector::UnregisterTimer(const ModuleTimer<T>& timer) {
+ std::string type_name = typeid(timer).name();
+ std::map<std::string, threads::Thread*>::iterator it =
+ timer_threads_.find(type_name);
+ if (timer_threads_.end() == it) {
+ /// Failed to unregister timer that was not registered
+ return;
+ }
+ threads::ThreadDelegate* delegate = it->second->delegate();
+ DeleteThread(it->second);
+ delete delegate;
+ timer_threads_.erase(it);
+}
+
+template void TimerDirector::UnregisterTimer<remote_control::TrackableMessage>(
+ const ModuleTimer<remote_control::TrackableMessage>& timer);
+
+template <class T>
+void TimerDirector::ResetTimer(ModuleTimer<T>& timer) {
+ const std::string type_name = typeid(timer).name();
+ std::map<std::string, threads::Thread*>::iterator it =
+ timer_threads_.find(type_name);
+ if (timer_threads_.end() == it) {
+ return;
+ }
+ TimerThreadDelegate<T>* delegate =
+ static_cast<TimerThreadDelegate<T>*>(it->second->delegate());
+ delegate->ResetTimer();
+}
+
+template void TimerDirector::ResetTimer<remote_control::TrackableMessage>(
+ ModuleTimer<remote_control::TrackableMessage>& timer);
+
+void TimerDirector::UnregisterAllTimers() {
+ for (std::map<std::string, threads::Thread*>::iterator it =
+ timer_threads_.begin();
+ timer_threads_.end() != it;
+ ++it) {
+ threads::ThreadDelegate* delegate = it->second->delegate();
+ DeleteThread(it->second);
+ delete delegate;
+ }
+ timer_threads_.clear();
+}
+
+} // namespace functional_modules
diff --git a/src/components/functional_module/test/CMakeLists.txt b/src/components/functional_module/test/CMakeLists.txt
new file mode 100644
index 0000000000..e1cb673252
--- /dev/null
+++ b/src/components/functional_module/test/CMakeLists.txt
@@ -0,0 +1,56 @@
+include_directories (
+ ${LOG4CXX_INCLUDE_DIRECTORY}
+ ${GMOCK_INCLUDE_DIRECTORY}
+ ${CMAKE_SOURCE_DIR}/src/components/functional_module/include/
+ ${CMAKE_SOURCE_DIR}/src/components/include/
+ ${CMAKE_SOURCE_DIR}/src/components/application_manager/include
+ ${CMAKE_SOURCE_DIR}/src/components/connection_handler/include
+ ${CMAKE_SOURCE_DIR}/src/components/utils/include
+ ${CMAKE_SOURCE_DIR}/src/components/policy/include
+ ${CMAKE_SOURCE_DIR}/src/components/smart_objects/include
+ ${JSONCPP_INCLUDE_DIRECTORY}
+ ${CMAKE_BINARY_DIR}/src/components/
+ include
+ plugins
+)
+
+set (LIBRARIES
+ gtest
+ gmock
+ gmock_main
+ FunctionalModule
+ dl
+ ApplicationManager
+ jsoncpp
+ Utils
+ ConfigProfile
+ gcov
+)
+
+set(SOURCES
+ ./src/generic_module_test.cc
+ ./src/plugin_manager_test.cc
+ ./src/module_timer_test.cc
+ ./src/settings_test.cc
+)
+
+# use, i.e. don't skip the full RPATH for the build tree
+SET(CMAKE_SKIP_BUILD_RPATH FALSE)
+
+# when building, don't use the install RPATH already
+# (but later on when installing)
+SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
+
+SET(RPATH_DIRECTORIES
+ /usr/local/lib
+ /usr/local
+ ${CMAKE_BINARY_DIR}/src/components/utils
+)
+
+SET(CMAKE_INSTALL_RPATH "${RPATH_DIRECTORIES}")
+
+configure_file("test.ini" "test.ini" COPYONLY)
+
+add_subdirectory(plugins)
+
+create_test("function_module_test" "${SOURCES}" "${LIBRARIES}")
diff --git a/src/components/functional_module/test/include/driver_generic_module_test.h b/src/components/functional_module/test/include/driver_generic_module_test.h
new file mode 100644
index 0000000000..f41a274055
--- /dev/null
+++ b/src/components/functional_module/test/include/driver_generic_module_test.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef SRC_COMPONENTS_FUNCTIONAL_MODULE_TEST_INCLUDE_DRIVER_GENERIC_MODULE_TEST_H_
+#define SRC_COMPONENTS_FUNCTIONAL_MODULE_TEST_INCLUDE_DRIVER_GENERIC_MODULE_TEST_H_
+
+#include "functional_module/generic_module.h"
+
+namespace functional_modules {
+
+class DriverGenericModuleTest : public GenericModule {
+ public:
+ explicit DriverGenericModuleTest(ModuleID module_id)
+ : GenericModule(module_id) {}
+ virtual ~DriverGenericModuleTest() {}
+ virtual PluginInfo GetPluginInfo() const {
+ PluginInfo info;
+ info.name = "DriverGenericModuleTest";
+ info.version = 1;
+ return info;
+ }
+ virtual ProcessResult ProcessMessage(application_manager::MessagePtr msg) {
+ NotifyObservers(ModuleObserver::FS_FAILURE);
+ return ProcessResult::FAILED;
+ }
+ virtual ProcessResult ProcessHMIMessage(application_manager::MessagePtr msg) {
+ return ProcessResult::PROCESSED;
+ }
+ virtual void RemoveAppExtension(uint32_t app_id) {}
+ virtual void RemoveAppExtensions() {}
+ bool IsAppForPlugin(application_manager::ApplicationSharedPtr app) {
+ return true;
+ }
+
+ void OnAppHMILevelChanged(application_manager::ApplicationSharedPtr,
+ mobile_apis::HMILevel::eType) {}
+
+ const Observers& observers() {
+ return observers_;
+ }
+
+ void OnDeviceRemoved(const connection_handler::DeviceHandle&) {}
+
+ void OnUnregisterApplication(const uint32_t app_id) {}
+};
+
+} // namespace functional_modules
+
+#endif // SRC_COMPONENTS_FUNCTIONAL_MODULE_TEST_INCLUDE_DRIVER_GENERIC_MODULE_TEST_H_
diff --git a/src/components/functional_module/test/include/mock_application.h b/src/components/functional_module/test/include/mock_application.h
new file mode 100644
index 0000000000..e73851094e
--- /dev/null
+++ b/src/components/functional_module/test/include/mock_application.h
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef SRC_COMPONENTS_FUNCTIONAL_MODULE_TEST_INCLUDE_MOCK_APPLICATION_H_
+#define SRC_COMPONENTS_FUNCTIONAL_MODULE_TEST_INCLUDE_MOCK_APPLICATION_H_
+
+#include "gmock/gmock.h"
+#include "application_manager/application.h"
+#include "application_manager/usage_statistics.h"
+#include "smart_objects/smart_object.h"
+
+namespace application_manager {
+
+class MockApplication : public Application {
+ public:
+ MOCK_CONST_METHOD0(active_message, const smart_objects::SmartObject*());
+ MOCK_CONST_METHOD0(curHash, const std::string&());
+ MOCK_METHOD0(UpdateHash, void());
+ MOCK_METHOD0(CloseActiveMessage, void());
+ MOCK_CONST_METHOD0(IsFullscreen, bool());
+ MOCK_METHOD0(MakeFullscreen, bool());
+ MOCK_CONST_METHOD0(IsAudible, bool());
+ MOCK_METHOD0(MakeNotAudible, void());
+ MOCK_CONST_METHOD0(allowed_support_navigation, bool());
+ MOCK_METHOD1(set_allowed_support_navigation, void(bool allow));
+ MOCK_CONST_METHOD0(hmi_supports_navi_streaming, bool());
+ MOCK_METHOD1(set_hmi_supports_navi_streaming, void(const bool& supports));
+ MOCK_CONST_METHOD0(app_allowed, bool());
+ MOCK_CONST_METHOD0(has_been_activated, bool());
+ MOCK_CONST_METHOD0(version, const Version&());
+ MOCK_METHOD1(set_hmi_application_id, void(uint32_t hmi_app_id));
+ MOCK_CONST_METHOD0(hmi_app_id, uint32_t());
+ MOCK_CONST_METHOD0(app_id, uint32_t());
+ MOCK_CONST_METHOD0(name, const std::string&());
+ MOCK_CONST_METHOD0(folder_name, const std::string());
+ MOCK_CONST_METHOD0(is_media_application, bool());
+ MOCK_CONST_METHOD0(hmi_level, const mobile_api::HMILevel::eType&());
+ MOCK_CONST_METHOD0(put_file_in_none_count, const uint32_t());
+ MOCK_CONST_METHOD0(delete_file_in_none_count, const uint32_t());
+ MOCK_CONST_METHOD0(list_files_in_none_count, const uint32_t());
+ MOCK_CONST_METHOD0(system_context, const mobile_api::SystemContext::eType&());
+ MOCK_CONST_METHOD0(audio_streaming_state,
+ const mobile_api::AudioStreamingState::eType&());
+ MOCK_CONST_METHOD0(app_icon_path, const std::string&());
+ MOCK_CONST_METHOD0(device, connection_handler::DeviceHandle());
+ MOCK_METHOD1(set_tts_speak_state, void(bool state_tts_speak));
+ MOCK_METHOD0(tts_speak_state, bool());
+ MOCK_METHOD1(set_tts_properties_in_none, void(bool active));
+ MOCK_METHOD0(tts_properties_in_none, bool());
+ MOCK_METHOD1(set_tts_properties_in_full, void(bool active));
+ MOCK_METHOD0(tts_properties_in_full, bool());
+ MOCK_METHOD1(set_version, void(const Version& version));
+ MOCK_METHOD1(set_name, void(const std::string& name));
+ MOCK_METHOD1(set_is_media_application, void(bool is_media));
+ MOCK_METHOD1(set_hmi_level,
+ void(const mobile_api::HMILevel::eType& hmi_level));
+ MOCK_METHOD0(increment_put_file_in_none_count, void());
+ MOCK_METHOD0(increment_delete_file_in_none_count, void());
+ MOCK_METHOD0(increment_list_files_in_none_count, void());
+ MOCK_METHOD1(set_system_context,
+ void(const mobile_api::SystemContext::eType& system_context));
+ MOCK_METHOD1(set_audio_streaming_state,
+ void(const mobile_api::AudioStreamingState::eType& state));
+ MOCK_METHOD1(set_app_icon_path, bool(const std::string& file_name));
+ MOCK_METHOD1(set_app_allowed, void(const bool& allowed));
+ MOCK_METHOD1(set_device, void(connection_handler::DeviceHandle device));
+ MOCK_CONST_METHOD0(get_grammar_id, uint32_t());
+ MOCK_METHOD1(set_grammar_id, void(uint32_t value));
+ MOCK_METHOD1(set_protocol_version,
+ void(const ProtocolVersion& protocol_version));
+ MOCK_CONST_METHOD0(protocol_version, ProtocolVersion());
+ MOCK_METHOD1(AddFile, bool(AppFile& file));
+ MOCK_CONST_METHOD0(getAppFiles, const AppFilesMap&());
+ MOCK_METHOD1(UpdateFile, bool(AppFile& file));
+ MOCK_METHOD1(DeleteFile, bool(const std::string& file_name));
+ MOCK_METHOD1(GetFile, const AppFile*(const std::string& file_name));
+ MOCK_METHOD1(SubscribeToButton,
+ bool(mobile_apis::ButtonName::eType btn_name));
+ MOCK_METHOD1(IsSubscribedToButton,
+ bool(mobile_apis::ButtonName::eType btn_name));
+ MOCK_METHOD1(UnsubscribeFromButton,
+ bool(mobile_apis::ButtonName::eType btn_name));
+ MOCK_METHOD1(SubscribeToIVI, bool(uint32_t vehicle_info_type_));
+ MOCK_METHOD1(IsSubscribedToIVI, bool(uint32_t vehicle_info_type_));
+ MOCK_METHOD1(UnsubscribeFromIVI, bool(uint32_t vehicle_info_type_));
+ MOCK_METHOD2(IsCommandLimitsExceeded,
+ bool(mobile_apis::FunctionID::eType cmd_id,
+ TLimitSource source));
+ MOCK_METHOD0(usage_report, UsageStatistics&());
+ MOCK_METHOD2(SubscribeToSoftButtons,
+ void(int32_t cmd_id, const SoftButtonID& softbuttons_id));
+ MOCK_METHOD1(IsSubscribedToSoftButton, bool(const uint32_t softbutton_id));
+ MOCK_METHOD1(UnsubscribeFromSoftButtons, void(int32_t cmd_id));
+ MOCK_METHOD1(QueryInterface, AppExtensionPtr(AppExtensionUID uid));
+ MOCK_METHOD1(AddExtension, bool(AppExtensionPtr extention));
+ MOCK_METHOD1(RemoveExtension, bool(AppExtensionUID uid));
+ MOCK_METHOD0(RemoveExtensions, void());
+ MOCK_CONST_METHOD0(help_prompt, const smart_objects::SmartObject*());
+ MOCK_CONST_METHOD0(timeout_prompt, const smart_objects::SmartObject*());
+ MOCK_CONST_METHOD0(vr_help_title, const smart_objects::SmartObject*());
+ MOCK_CONST_METHOD0(vr_help, const smart_objects::SmartObject*());
+ MOCK_CONST_METHOD0(tbt_state, const mobile_api::TBTState::eType&());
+ MOCK_CONST_METHOD0(show_command, const smart_objects::SmartObject*());
+ MOCK_CONST_METHOD0(tbt_show_command, const smart_objects::SmartObject*());
+ MOCK_CONST_METHOD0(SubscribedButtons,
+ const std::set<mobile_apis::ButtonName::eType>&());
+ MOCK_CONST_METHOD0(SubscribesIVI, const std::set<uint32_t>&());
+ MOCK_CONST_METHOD0(keyboard_props, const smart_objects::SmartObject*());
+ MOCK_CONST_METHOD0(menu_title, const smart_objects::SmartObject*());
+ MOCK_CONST_METHOD0(menu_icon, const smart_objects::SmartObject*());
+ MOCK_METHOD1(set_help_prompt,
+ void(const smart_objects::SmartObject& help_prompt));
+ MOCK_METHOD1(set_timeout_prompt,
+ void(const smart_objects::SmartObject& timeout_prompt));
+ MOCK_METHOD1(set_vr_help_title,
+ void(const smart_objects::SmartObject& vr_help_title));
+ MOCK_METHOD0(reset_vr_help_title, void());
+ MOCK_METHOD1(set_vr_help, void(const smart_objects::SmartObject& vr_help));
+ MOCK_METHOD0(reset_vr_help, void());
+ MOCK_METHOD1(set_tbt_state,
+ void(const mobile_api::TBTState::eType& tbt_state));
+ MOCK_METHOD1(set_show_command,
+ void(const smart_objects::SmartObject& show_command));
+ MOCK_METHOD1(set_tbt_show_command,
+ void(const smart_objects::SmartObject& tbt_show));
+ MOCK_METHOD1(set_keyboard_props,
+ void(const smart_objects::SmartObject& keyboard_props));
+ MOCK_METHOD1(set_menu_title,
+ void(const smart_objects::SmartObject& menu_title));
+ MOCK_METHOD1(set_menu_icon,
+ void(const smart_objects::SmartObject& menu_icon));
+ MOCK_METHOD2(AddCommand,
+ void(uint32_t cmd_id,
+ const smart_objects::SmartObject& command));
+ MOCK_METHOD1(RemoveCommand, void(uint32_t cmd_id));
+ MOCK_METHOD1(FindCommand, smart_objects::SmartObject*(uint32_t cmd_id));
+ MOCK_METHOD2(AddSubMenu,
+ void(uint32_t menu_id, const smart_objects::SmartObject& menu));
+ MOCK_METHOD1(RemoveSubMenu, void(uint32_t menu_id));
+ MOCK_CONST_METHOD1(FindSubMenu,
+ smart_objects::SmartObject*(uint32_t menu_id));
+ MOCK_METHOD1(IsSubMenuNameAlreadyExist, bool(const std::string& name));
+ MOCK_METHOD2(AddChoiceSet,
+ void(uint32_t choice_set_id,
+ const smart_objects::SmartObject& choice_set));
+ MOCK_METHOD1(RemoveChoiceSet, void(uint32_t choice_set_id));
+ MOCK_METHOD1(FindChoiceSet,
+ smart_objects::SmartObject*(uint32_t choice_set_id));
+ MOCK_METHOD2(AddPerformInteractionChoiceSet,
+ void(uint32_t choice_set_id,
+ const smart_objects::SmartObject& choice_set));
+ MOCK_METHOD0(DeletePerformInteractionChoiceSetMap, void());
+ MOCK_CONST_METHOD0(performinteraction_choice_set_map,
+ DataAccessor<PerformChoiceSetMap>());
+ MOCK_CONST_METHOD1(FindPerformInteractionChoiceSet,
+ smart_objects::SmartObject*(uint32_t choice_set_id));
+ MOCK_CONST_METHOD0(commands_map, DataAccessor<CommandsMap>());
+ MOCK_CONST_METHOD0(sub_menu_map, DataAccessor<SubMenuMap>());
+ MOCK_CONST_METHOD0(choice_set_map, DataAccessor<ChoiceSetMap>());
+ MOCK_METHOD1(set_perform_interaction_active, void(uint32_t active));
+ MOCK_CONST_METHOD0(is_perform_interaction_active, uint32_t());
+ MOCK_METHOD1(set_perform_interaction_ui_corrid, void(uint32_t choice));
+ MOCK_CONST_METHOD0(perform_interaction_ui_corrid, uint32_t());
+ MOCK_METHOD1(set_perform_interaction_mode, void(int32_t mode));
+ MOCK_CONST_METHOD0(perform_interaction_mode, int32_t());
+ MOCK_METHOD1(set_reset_global_properties_active, void(bool active));
+ MOCK_CONST_METHOD0(is_reset_global_properties_active, bool());
+ MOCK_CONST_METHOD0(app_types, const smart_objects::SmartObject*());
+ MOCK_CONST_METHOD0(vr_synonyms, const smart_objects::SmartObject*());
+ MOCK_CONST_METHOD0(mobile_app_id, std::string());
+ MOCK_CONST_METHOD0(tts_name, const smart_objects::SmartObject*());
+ MOCK_CONST_METHOD0(ngn_media_screen_name,
+ const smart_objects::SmartObject*());
+ MOCK_CONST_METHOD0(language, const mobile_api::Language::eType&());
+ MOCK_CONST_METHOD0(ui_language, const mobile_api::Language::eType&());
+ MOCK_METHOD1(set_app_types,
+ void(const smart_objects::SmartObject& app_types));
+ MOCK_METHOD1(set_vr_synonyms,
+ void(const smart_objects::SmartObject& vr_synonyms));
+ MOCK_METHOD1(set_mobile_app_id,
+ void(const smart_objects::SmartObject& mobile_app_id));
+ MOCK_METHOD1(set_tts_name, void(const smart_objects::SmartObject& tts_name));
+ MOCK_METHOD1(set_ngn_media_screen_name,
+ void(const smart_objects::SmartObject& ngn_name));
+ MOCK_METHOD1(set_language, void(const mobile_api::Language::eType& language));
+ MOCK_METHOD1(set_ui_language,
+ void(const mobile_api::Language::eType& ui_language));
+ MOCK_METHOD1(load_global_properties,
+ void(const smart_objects::SmartObject& so));
+ MOCK_METHOD1(set_mobile_app_id, void(const std::string& mobile_app_id));
+ MOCK_METHOD0(ChangeSupportingAppHMIType, void());
+ MOCK_CONST_METHOD0(is_navi, bool());
+ MOCK_METHOD1(set_is_navi, void(bool allow));
+ MOCK_CONST_METHOD0(hmi_supports_navi_video_streaming, bool());
+ MOCK_METHOD1(set_hmi_supports_navi_video_streaming, void(bool supports));
+ MOCK_CONST_METHOD0(hmi_supports_navi_audio_streaming, bool());
+ MOCK_METHOD1(set_hmi_supports_navi_audio_streaming, void(bool supports));
+ MOCK_CONST_METHOD0(is_voice_communication_supported, bool());
+ MOCK_METHOD1(set_voice_communication_supported, void(bool));
+ MOCK_METHOD1(set_activated, bool(bool is_active));
+ MOCK_CONST_METHOD0(is_foreground, bool());
+ MOCK_METHOD1(set_foreground, void(bool is_foreground));
+ MOCK_CONST_METHOD0(IsAudioApplication, bool());
+ MOCK_CONST_METHOD0(video_stream_retry_active, bool());
+ MOCK_METHOD1(set_video_stream_retry_active, void(bool active));
+ MOCK_CONST_METHOD0(audio_stream_retry_active, bool());
+ MOCK_METHOD1(set_audio_stream_retry_active, void(bool active));
+ MOCK_METHOD0(OnVideoStreamRetry, void());
+ MOCK_METHOD0(OnAudioStreamRetry, void());
+ MOCK_METHOD1(SubscribeToInteriorVehicleData,
+ bool(smart_objects::SmartObject module));
+ MOCK_METHOD1(IsSubscribedToInteriorVehicleData,
+ bool(smart_objects::SmartObject module));
+ MOCK_METHOD1(UnsubscribeFromInteriorVehicleData,
+ bool(smart_objects::SmartObject module));
+};
+
+} // namespace application_manager
+
+#endif // SRC_COMPONENTS_FUNCTIONAL_MODULE_TEST_INCLUDE_MOCK_APPLICATION_H_
diff --git a/src/components/functional_module/test/include/mock_module_observer.h b/src/components/functional_module/test/include/mock_module_observer.h
new file mode 100644
index 0000000000..bfa5117b29
--- /dev/null
+++ b/src/components/functional_module/test/include/mock_module_observer.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef SRC_COMPONENTS_FUNCTIONAL_MODULE_TEST_INCLUDE_MOCK_MODULE_OBSERVER_H_
+#define SRC_COMPONENTS_FUNCTIONAL_MODULE_TEST_INCLUDE_MOCK_MODULE_OBSERVER_H_
+
+#include "gmock/gmock.h"
+#include "functional_module/module_observer.h"
+
+namespace functional_modules {
+
+class MockModuleObserver : public ModuleObserver {
+ public:
+ MOCK_METHOD2(OnError, void(Errors error, ModuleID module_id));
+ int ObserverMethod() {
+ return 13;
+ }
+};
+
+} // namespace functional_modules
+
+#endif // SRC_COMPONENTS_FUNCTIONAL_MODULE_TEST_INCLUDE_MOCK_MODULE_OBSERVER_H_
diff --git a/src/components/functional_module/test/include/mock_service.h b/src/components/functional_module/test/include/mock_service.h
new file mode 100644
index 0000000000..560fa91359
--- /dev/null
+++ b/src/components/functional_module/test/include/mock_service.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef SRC_COMPONENTS_FUNCTIONAL_MODULE_TEST_INCLUDE_MOCK_SERVICE_H_
+#define SRC_COMPONENTS_FUNCTIONAL_MODULE_TEST_INCLUDE_MOCK_SERVICE_H_
+
+#include "gmock/gmock.h"
+#include "application_manager/service.h"
+
+namespace application_manager {
+
+class MockService : public Service {
+ public:
+ MOCK_METHOD1(CheckPolicyPermissions,
+ mobile_apis::Result::eType(MessagePtr msg));
+ MOCK_METHOD1(GetApplication, ApplicationSharedPtr(ApplicationId app_id));
+ MOCK_METHOD1(SendMessageToHMI, void(const MessagePtr& message));
+ MOCK_METHOD1(SendMessageToMobile, void(const MessagePtr& message));
+ MOCK_METHOD0(GetNextCorrelationID, uint32_t());
+ MOCK_METHOD1(GetApplications,
+ std::vector<ApplicationSharedPtr>(AppExtensionUID));
+ MOCK_METHOD1(SubscribeToHMINotification,
+ void(const std::string& hmi_notification));
+ MOCK_METHOD2(ChangeNotifyHMILevel,
+ void(ApplicationSharedPtr app,
+ mobile_apis::HMILevel::eType level));
+ MOCK_METHOD2(NotifyHMIAboutHMILevel,
+ void(ApplicationSharedPtr app,
+ mobile_apis::HMILevel::eType level));
+ MOCK_METHOD4(CheckAccess,
+ TypeAccess(const ApplicationId& app_id,
+ const std::string& module,
+ const std::string& rpc,
+ const std::vector<std::string>& params));
+ MOCK_METHOD2(CheckModule,
+ bool(const ApplicationId& app_id, const std::string& module));
+ MOCK_METHOD3(SetAccess,
+ void(const ApplicationId& app_id,
+ const std::string& module,
+ bool allowed));
+ MOCK_METHOD1(ResetAccess, void(const ApplicationId& app_id));
+ MOCK_METHOD1(ResetAccess, void(const std::string& module));
+ MOCK_METHOD1(GetDeviceHandlerById, uint32_t(const std::string& device_id));
+ MOCK_METHOD1(SetPrimaryDevice, void(const uint32_t dev_id));
+ MOCK_METHOD0(ResetPrimaryDevice, void());
+ MOCK_CONST_METHOD0(PrimaryDevice, uint32_t());
+ MOCK_METHOD1(SetRemoteControl, void(bool enabled));
+ MOCK_METHOD1(RemoveHMIFakeParameters,
+ void(application_manager::MessagePtr& message));
+ MOCK_CONST_METHOD0(IsRemoteControlAllowed, bool());
+
+ MOCK_CONST_METHOD1(IsRemoteControlApplication,
+ bool(ApplicationSharedPtr app));
+ MOCK_CONST_METHOD2(GetModuleTypes,
+ bool(const std::string& application_id,
+ std::vector<std::string>* modules));
+ MOCK_METHOD1(ValidateMessageBySchema,
+ application_manager::MessageValidationResult(
+ const application_manager::Message& message));
+};
+}
+// namespace application_manager
+
+#endif // SRC_COMPONENTS_FUNCTIONAL_MODULE_TEST_INCLUDE_MOCK_SERVICE_H_
diff --git a/src/components/functional_module/test/include/module_timer_test.h b/src/components/functional_module/test/include/module_timer_test.h
new file mode 100644
index 0000000000..456346b544
--- /dev/null
+++ b/src/components/functional_module/test/include/module_timer_test.h
@@ -0,0 +1,56 @@
+#include "utils/macro.h"
+#include "functional_module/timer/module_timer.h"
+
+namespace functional_modules {
+
+class TestTrackable : public Trackable {
+ public:
+ explicit TestTrackable(TimeUnit interval = 0)
+ : Trackable(), custom_interval_(interval) {}
+
+ virtual TimeUnit custom_interval() const {
+ return custom_interval_;
+ }
+
+ bool operator==(const TestTrackable& other) const {
+ return custom_interval_ == other.custom_interval_;
+ }
+
+ private:
+ TimeUnit custom_interval_;
+};
+
+class ModuleTimerTest {
+ public:
+ ModuleTimerTest(ModuleTimer<TestTrackable>& timer) : timer_(timer) {}
+
+ TimeUnit period() const {
+ return timer_.period_;
+ }
+
+ int observers_size() const {
+ return timer_.observers_.size();
+ }
+
+ int trackables_size() const {
+ return timer_.trackables_.size();
+ }
+
+ TestTrackable trackable(const TestTrackable& track) const {
+ return *std::find(
+ timer_.trackables_.begin(), timer_.trackables_.end(), track);
+ }
+
+ TimeUnit current_time() const {
+ return timer_.CurrentTime();
+ }
+
+ private:
+ ModuleTimer<TestTrackable>& timer_;
+};
+
+class MockTimerObserver : public TimerObserver<TestTrackable> {
+ public:
+ MOCK_METHOD1(OnTimeoutTriggered, void(const TestTrackable& expired));
+};
+} // namespace functional_modules
diff --git a/src/components/functional_module/test/plugins/CMakeLists.txt b/src/components/functional_module/test/plugins/CMakeLists.txt
new file mode 100644
index 0000000000..7afe8387b8
--- /dev/null
+++ b/src/components/functional_module/test/plugins/CMakeLists.txt
@@ -0,0 +1,17 @@
+set(target PluginMock)
+
+include_directories (
+ ${LOG4CXX_INCLUDE_DIRECTORY}
+ ${GMOCK_INCLUDE_DIRECTORY}
+ ${CMAKE_SOURCE_DIR}/src/components/functional_module/include/
+ ${CMAKE_SOURCE_DIR}/src/components/include/
+ ${JSONCPP_INCLUDE_DIRECTORY}
+)
+
+set(SOURCES
+ ./mock_generic_module.cc
+)
+
+add_library(${target} SHARED ${SOURCES})
+target_link_libraries(${target})
+add_dependencies(${target} MOBILE_API HMI_API)
diff --git a/src/components/functional_module/test/plugins/mock_generic_module.cc b/src/components/functional_module/test/plugins/mock_generic_module.cc
new file mode 100644
index 0000000000..dcf6d7d4fe
--- /dev/null
+++ b/src/components/functional_module/test/plugins/mock_generic_module.cc
@@ -0,0 +1,23 @@
+#include "mock_generic_module.h"
+
+using functional_modules::GenericModule;
+using functional_modules::RCFunctionID;
+using functional_modules::PluginInfo;
+
+using ::testing::_;
+using ::testing::Return;
+
+MockGenericModule::MockGenericModule() : GenericModule(19) {
+ PluginInfo info;
+ info.name = "MockGenericModule";
+ info.version = 1;
+ info.rc_function_list.push_back(static_cast<RCFunctionID>(101));
+ info.hmi_function_list.push_back("HMI-Func-1");
+
+ EXPECT_CALL(*this, GetPluginInfo()).Times(2).WillRepeatedly(Return(info));
+ EXPECT_CALL(*this, set_service(_)).Times(1);
+}
+
+extern "C" GenericModule* Create() {
+ return new MockGenericModule();
+}
diff --git a/src/components/functional_module/test/plugins/mock_generic_module.h b/src/components/functional_module/test/plugins/mock_generic_module.h
new file mode 100644
index 0000000000..aef0a68f19
--- /dev/null
+++ b/src/components/functional_module/test/plugins/mock_generic_module.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef TEST_COMPONENTS_FUNCTIONAL_MODULE_PLUGINS_MOCK_GENERIC_MODULE_H_
+#define TEST_COMPONENTS_FUNCTIONAL_MODULE_PLUGINS_MOCK_GENERIC_MODULE_H_
+
+#include "gmock/gmock.h"
+#include "functional_module/generic_module.h"
+
+using functional_modules::GenericModule;
+using functional_modules::PluginInfo;
+using functional_modules::ProcessResult;
+using functional_modules::ServiceState;
+
+using ::testing::_;
+using ::testing::Return;
+
+class MockGenericModule : public GenericModule {
+ public:
+ MockGenericModule();
+ MOCK_CONST_METHOD0(GetPluginInfo, PluginInfo());
+ MOCK_METHOD1(set_service, void(application_manager::ServicePtr service));
+ MOCK_METHOD0(service, application_manager::ServicePtr());
+ MOCK_METHOD1(ProcessMessage,
+ ProcessResult(application_manager::MessagePtr msg));
+ MOCK_METHOD1(ProcessHMIMessage,
+ ProcessResult(application_manager::MessagePtr msg));
+ MOCK_METHOD1(OnServiceStateChanged, void(ServiceState state));
+ MOCK_METHOD1(RemoveAppExtension, void(uint32_t app_id));
+ MOCK_METHOD1(IsAppForPlugin,
+ bool(application_manager::ApplicationSharedPtr app));
+ MOCK_METHOD2(OnAppHMILevelChanged,
+ void(application_manager::ApplicationSharedPtr app,
+ mobile_apis::HMILevel::eType old_level));
+ MOCK_METHOD1(OnDeviceRemoved,
+ void(const connection_handler::DeviceHandle& device));
+ MOCK_METHOD1(OnUnregisterApplication, void(const uint32_t app_id));
+ MOCK_METHOD2(CanAppChangeHMILevel,
+ bool(application_manager::ApplicationSharedPtr app,
+ mobile_apis::HMILevel::eType new_level));
+ MOCK_METHOD0(RemoveAppExtensions, void());
+};
+
+#endif // TEST_COMPONENTS_FUNCTIONAL_MODULE_PLUGINS_MOCK_GENERIC_MODULE_H_
diff --git a/src/components/functional_module/test/src/generic_module_test.cc b/src/components/functional_module/test/src/generic_module_test.cc
new file mode 100644
index 0000000000..b052050cdb
--- /dev/null
+++ b/src/components/functional_module/test/src/generic_module_test.cc
@@ -0,0 +1,137 @@
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+#include "driver_generic_module_test.h"
+
+#include "mock_module_observer.h"
+#include "mock_service.h"
+
+using application_manager::ServicePtr;
+using application_manager::MockService;
+
+using ::testing::_;
+
+namespace functional_modules {
+
+TEST(GenericModuleTest, SetService) {
+ DriverGenericModuleTest module(18);
+ MockService* mock_service = new MockService();
+ ServicePtr exp_service(mock_service);
+
+ module.set_service(exp_service);
+ ServicePtr out_service = module.service();
+
+ EXPECT_EQ(exp_service.get(), out_service.get());
+}
+
+TEST(GenericModuleTest, OnServiceStateChangedFail) {
+ DriverGenericModuleTest module(18);
+ MockService* mock_service = new MockService();
+ ServicePtr exp_service(mock_service);
+ module.set_service(exp_service);
+
+ EXPECT_CALL(*mock_service, SubscribeToHMINotification(_)).Times(0);
+
+ module.OnServiceStateChanged(LOWVOLTAGE);
+}
+
+TEST(GenericModuleTest, OnServiceStateChangedPass) {
+ DriverGenericModuleTest module(18);
+ MockService* mock_service = new MockService();
+ ServicePtr exp_service(mock_service);
+ module.set_service(exp_service);
+
+ EXPECT_CALL(*mock_service, SubscribeToHMINotification(_)).Times(2);
+
+ module.OnServiceStateChanged(HMI_ADAPTER_INITIALIZED);
+}
+
+TEST(GenericModuleTest, AddObserver) {
+ DriverGenericModuleTest module(18);
+ MockModuleObserver observer;
+ module.AddObserver(&observer);
+ const DriverGenericModuleTest::Observers& full = module.observers();
+ ASSERT_EQ(1u, full.size());
+ EXPECT_EQ(&observer, full[0]);
+}
+
+TEST(GenericModuleTest, RemoveObserver) {
+ DriverGenericModuleTest module(18);
+ MockModuleObserver* observer = new MockModuleObserver();
+ module.AddObserver(observer);
+
+ module.RemoveObserver(observer);
+ const DriverGenericModuleTest::Observers& empty = module.observers();
+ ASSERT_TRUE(empty.empty());
+ delete observer;
+}
+
+TEST(GenericModuleTest, EmptyRemoveObserver) {
+ DriverGenericModuleTest module(18);
+ MockModuleObserver* observer = new MockModuleObserver();
+ module.RemoveObserver(observer);
+ const DriverGenericModuleTest::Observers& empty = module.observers();
+ ASSERT_TRUE(empty.empty());
+ delete observer;
+}
+
+TEST(GenericModuleTest, WrongRemoveObserver) {
+ DriverGenericModuleTest module(18);
+ MockModuleObserver observer;
+ module.AddObserver(&observer);
+
+ MockModuleObserver* wrong_observer = new MockModuleObserver();
+ module.RemoveObserver(wrong_observer);
+ const DriverGenericModuleTest::Observers& empty = module.observers();
+ ASSERT_EQ(1u, empty.size());
+ EXPECT_EQ(&observer, empty[0]);
+ delete wrong_observer;
+}
+
+TEST(GenericModuleTest, CrashRemovedObserver) {
+ DriverGenericModuleTest module(18);
+ MockModuleObserver* observer = new MockModuleObserver();
+ module.AddObserver(observer);
+ EXPECT_EQ(13, observer->ObserverMethod());
+ module.RemoveObserver(observer);
+ EXPECT_EQ(13, observer->ObserverMethod());
+ delete observer;
+ MockModuleObserver second_observer;
+ module.AddObserver(&second_observer);
+ EXPECT_EQ(13, second_observer.ObserverMethod());
+ module.RemoveObserver(&second_observer);
+ EXPECT_EQ(13, second_observer.ObserverMethod());
+}
+
+TEST(GenericModuleTest, NotifyObservers) {
+ DriverGenericModuleTest module(3);
+ MockModuleObserver observer;
+ module.AddObserver(&observer);
+
+ EXPECT_CALL(observer, OnError(ModuleObserver::FS_FAILURE, 3)).Times(1);
+
+ application_manager::MessagePtr message;
+ module.ProcessMessage(message);
+}
+
+TEST(GenericModuleTest, NotifyObserversComplex) {
+ DriverGenericModuleTest module(3);
+ MockModuleObserver observer_1;
+ module.AddObserver(&observer_1);
+ MockModuleObserver observer_2;
+ module.AddObserver(&observer_2);
+
+ EXPECT_CALL(observer_1, OnError(ModuleObserver::FS_FAILURE, 3)).Times(1);
+ EXPECT_CALL(observer_2, OnError(ModuleObserver::FS_FAILURE, 3)).Times(1);
+
+ application_manager::MessagePtr message;
+ module.ProcessMessage(message);
+
+ module.RemoveObserver(&observer_1);
+ EXPECT_CALL(observer_1, OnError(ModuleObserver::FS_FAILURE, 3)).Times(0);
+ EXPECT_CALL(observer_2, OnError(ModuleObserver::FS_FAILURE, 3)).Times(1);
+
+ module.ProcessMessage(message);
+}
+
+} // namespace functional_modules
diff --git a/src/components/functional_module/test/src/module_timer_test.cc b/src/components/functional_module/test/src/module_timer_test.cc
new file mode 100644
index 0000000000..668c3e2955
--- /dev/null
+++ b/src/components/functional_module/test/src/module_timer_test.cc
@@ -0,0 +1,123 @@
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "module_timer_test.h"
+
+namespace functional_modules {
+
+TEST(ModuleTimerTest, set_period) {
+ ModuleTimer<TestTrackable> timer;
+ timer.set_period(10000);
+ ModuleTimerTest test(timer);
+ EXPECT_EQ(10000u, test.period());
+}
+
+TEST(ModuleTimerTest, add_observer) {
+ ModuleTimer<TestTrackable> timer;
+ ModuleTimerTest test(timer);
+ for (size_t i = 0; i < 5; ++i) {
+ MockTimerObserver observer;
+ timer.AddObserver(&observer);
+ }
+ EXPECT_EQ(5, test.observers_size());
+}
+
+TEST(ModuleTimerTest, remove_observer) {
+ ModuleTimer<TestTrackable> timer;
+ ModuleTimerTest test(timer);
+
+ MockTimerObserver observer;
+ timer.AddObserver(&observer);
+ MockTimerObserver observer2;
+ timer.AddObserver(&observer2);
+ timer.RemoveObserver(&observer);
+ EXPECT_EQ(1, test.observers_size());
+ MockTimerObserver observer3;
+ timer.RemoveObserver(&observer3);
+ EXPECT_EQ(1, test.observers_size());
+ timer.RemoveObserver(&observer2);
+ EXPECT_EQ(0, test.observers_size());
+}
+
+TEST(ModuleTimerTest, start) {
+ ModuleTimer<TestTrackable> timer;
+ ModuleTimerTest test(timer);
+ timer.set_period(1);
+ MockTimerObserver observer;
+ timer.AddObserver(&observer);
+ TestTrackable track;
+ timer.AddTrackable(track);
+ sleep(2);
+ EXPECT_CALL(observer, OnTimeoutTriggered(track)).Times(1);
+ timer.CheckTimeout();
+ EXPECT_EQ(0, test.trackables_size());
+ timer.set_period(4);
+ timer.AddTrackable(track);
+ sleep(2);
+ EXPECT_CALL(observer, OnTimeoutTriggered(track)).Times(0);
+ timer.CheckTimeout();
+ EXPECT_EQ(1, test.trackables_size());
+ TestTrackable track2(1);
+ timer.AddTrackable(track2);
+ timer.AddTrackable(track);
+ sleep(2);
+ EXPECT_CALL(observer, OnTimeoutTriggered(track2)).Times(1);
+ EXPECT_CALL(observer, OnTimeoutTriggered(track)).Times(0);
+ timer.CheckTimeout();
+ EXPECT_EQ(1, test.trackables_size());
+}
+
+TEST(ModuleTimerTest, add_trackable) {
+ ModuleTimer<TestTrackable> timer;
+ ModuleTimerTest test(timer);
+ timer.AddTrackable(TestTrackable());
+ ASSERT_EQ(1, test.trackables_size());
+ // adding the same object twice
+ timer.AddTrackable(TestTrackable());
+ EXPECT_EQ(1, test.trackables_size());
+ // adding another object
+ TestTrackable track(3);
+ timer.AddTrackable(track);
+ ASSERT_EQ(2, test.trackables_size());
+ EXPECT_TRUE(test.trackable(track).start_time() - test.current_time() < 1);
+ timer.AddTrackable(track);
+ sleep(3);
+ EXPECT_TRUE(test.current_time() - test.trackable(track).start_time() < 4 &&
+ test.current_time() - test.trackable(track).start_time() > 2);
+}
+
+TEST(ModuleTimerTest, remove_trackable) {
+ ModuleTimer<TestTrackable> timer;
+ ModuleTimerTest test(timer);
+ EXPECT_EQ(0, test.trackables_size());
+ TestTrackable track1;
+ TestTrackable track2(1);
+ timer.AddTrackable(track1);
+ timer.AddTrackable(track2);
+ EXPECT_EQ(2, test.trackables_size());
+ timer.RemoveTrackable(track2);
+ ASSERT_EQ(1, test.trackables_size());
+ TestTrackable track3(2);
+ timer.RemoveTrackable(track3);
+ ASSERT_EQ(1, test.trackables_size());
+ timer.RemoveTrackable(track1);
+ ASSERT_EQ(0, test.trackables_size());
+}
+
+TEST(ModuleTimerTest, notify) {
+ ModuleTimer<TestTrackable> timer;
+ ModuleTimerTest test(timer);
+ timer.set_period(1);
+ MockTimerObserver observer;
+ timer.AddObserver(&observer);
+ TestTrackable track;
+ timer.AddTrackable(track);
+ TestTrackable track2(2);
+ timer.AddTrackable(track2);
+ sleep(2);
+ EXPECT_CALL(observer, OnTimeoutTriggered(track)).Times(1);
+ EXPECT_CALL(observer, OnTimeoutTriggered(track2)).Times(0);
+ timer.CheckTimeout();
+ EXPECT_EQ(1, test.trackables_size());
+}
+
+} // namespace functional_modules
diff --git a/src/components/functional_module/test/src/plugin_manager_test.cc b/src/components/functional_module/test/src/plugin_manager_test.cc
new file mode 100644
index 0000000000..09a44ceb58
--- /dev/null
+++ b/src/components/functional_module/test/src/plugin_manager_test.cc
@@ -0,0 +1,206 @@
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "functional_module/plugin_manager.h"
+#include "mock_generic_module.h"
+#include "mock_service.h"
+#include "application_manager/mock_application.h"
+#include "utils/shared_ptr.h"
+#include "utils/make_shared.h"
+
+using application_manager::Message;
+using application_manager::ProtocolVersion;
+using application_manager::MockService;
+using ::testing::NiceMock;
+using ::testing::Expectation;
+using ::testing::ReturnRef;
+
+namespace functional_modules {
+
+class PluginManagerTest : public ::testing::Test {
+ public:
+ PluginManagerTest()
+ : manager(utils::MakeShared<PluginManager>())
+ , service(utils::MakeShared<MockService>()) {}
+
+ protected:
+ utils::SharedPtr<PluginManager> manager;
+ utils::SharedPtr<MockService> service;
+ MockGenericModule* module;
+
+ void SetUp() OVERRIDE {
+ manager->SetServiceHandler(service);
+
+ ASSERT_EQ(1, manager->LoadPlugins("./plugins/"));
+ const PluginManager::Modules& plugins = manager->plugins();
+ PluginManager::Modules::const_iterator i = plugins.begin();
+ module = static_cast<MockGenericModule*>(i->second.get());
+ }
+};
+
+TEST_F(PluginManagerTest, ChangePluginsState) {
+ ServiceState kState = ServiceState::SUSPENDED;
+ EXPECT_CALL(*module, OnServiceStateChanged(kState));
+ manager->OnServiceStateChanged(kState);
+}
+
+TEST_F(PluginManagerTest, IsMessageForPluginFail) {
+ Message* msg = new Message(protocol_handler::MessagePriority::FromServiceType(
+ protocol_handler::ServiceType::kRpc));
+ msg->set_protocol_version(ProtocolVersion::kUnknownProtocol);
+ EXPECT_FALSE(manager->IsMessageForPlugin(msg));
+}
+
+TEST_F(PluginManagerTest, IsMessageForPluginPass) {
+ Message* msg = new Message(protocol_handler::MessagePriority::FromServiceType(
+ protocol_handler::ServiceType::kRpc));
+ msg->set_protocol_version(ProtocolVersion::kV3);
+ msg->set_function_id(101); // see MockGenericModule
+ EXPECT_TRUE(manager->IsMessageForPlugin(msg));
+}
+
+TEST_F(PluginManagerTest, IsHMIMessageForPluginFail) {
+ Message* msg = new Message(protocol_handler::MessagePriority::FromServiceType(
+ protocol_handler::ServiceType::kRpc));
+ msg->set_protocol_version(ProtocolVersion::kUnknownProtocol);
+ EXPECT_FALSE(manager->IsHMIMessageForPlugin(msg));
+}
+
+TEST_F(PluginManagerTest, IsHMIMessageForPluginPass) {
+ Message* msg = new Message(protocol_handler::MessagePriority::FromServiceType(
+ protocol_handler::ServiceType::kRpc));
+ msg->set_protocol_version(ProtocolVersion::kHMI);
+ std::string json = "{\"method\": \"HMI-Func-1\"}"; // see MockGenericModule
+ msg->set_json_message(json);
+ EXPECT_TRUE(manager->IsHMIMessageForPlugin(msg));
+}
+
+TEST_F(PluginManagerTest, RemoveAppExtension) {
+ const uint32_t kAppId = 2;
+ EXPECT_CALL(*module, RemoveAppExtension(kAppId)).Times(1);
+ manager->RemoveAppExtension(kAppId);
+}
+
+TEST_F(PluginManagerTest, ProcessMessageFail) {
+ Message* msg = new Message(protocol_handler::MessagePriority::FromServiceType(
+ protocol_handler::ServiceType::kRpc));
+ application_manager::MessagePtr message(msg);
+ msg->set_protocol_version(ProtocolVersion::kUnknownProtocol);
+ EXPECT_CALL(*module, ProcessMessage(message)).Times(0);
+ manager->ProcessMessage(message);
+}
+
+TEST_F(PluginManagerTest, ProcessMessagePass) {
+ Message* msg = new Message(protocol_handler::MessagePriority::FromServiceType(
+ protocol_handler::ServiceType::kRpc));
+ application_manager::MessagePtr message(msg);
+ msg->set_protocol_version(ProtocolVersion::kV3);
+ msg->set_function_id(101); // see MockGenericModule
+ EXPECT_CALL(*module, ProcessMessage(message))
+ .Times(1)
+ .WillOnce(Return(ProcessResult::PROCESSED));
+ manager->ProcessMessage(message);
+}
+
+TEST_F(PluginManagerTest, ProcessHMIMessageFail) {
+ Message* msg = new Message(protocol_handler::MessagePriority::FromServiceType(
+ protocol_handler::ServiceType::kRpc));
+ application_manager::MessagePtr message(msg);
+ message->set_protocol_version(ProtocolVersion::kUnknownProtocol);
+ EXPECT_CALL(*module, ProcessHMIMessage(message)).Times(0);
+ manager->ProcessHMIMessage(message);
+}
+
+TEST_F(PluginManagerTest, ProcessHMIMessagePass) {
+ Message* msg = new Message(protocol_handler::MessagePriority::FromServiceType(
+ protocol_handler::ServiceType::kRpc));
+ application_manager::MessagePtr message(msg);
+ message->set_protocol_version(ProtocolVersion::kHMI);
+ std::string json = "{\"method\": \"HMI-Func-1\"}"; // see MockGenericModule
+ message->set_json_message(json);
+ EXPECT_CALL(*module, ProcessHMIMessage(message))
+ .Times(1)
+ .WillOnce(Return(ProcessResult::PROCESSED));
+ manager->ProcessHMIMessage(message);
+}
+
+TEST_F(PluginManagerTest, IsAppForPlugins) {
+ using test::components::application_manager_test::MockApplication;
+ MockApplication* app = new MockApplication();
+ application_manager::ApplicationSharedPtr app_ptr(app);
+ EXPECT_CALL(*module, IsAppForPlugin(app_ptr)).Times(1);
+ manager->IsAppForPlugins(app_ptr);
+}
+
+TEST_F(PluginManagerTest, OnAppHMILevelChanged) {
+ using test::components::application_manager_test::MockApplication;
+ NiceMock<MockApplication>* app = new NiceMock<MockApplication>();
+ application_manager::ApplicationSharedPtr app_ptr(app);
+
+ const application_manager::custom_str::CustomString name("name");
+ ON_CALL(*app, name()).WillByDefault(ReturnRef(name));
+ mobile_apis::HMILevel::eType level = mobile_apis::HMILevel::eType::HMI_NONE;
+ ON_CALL(*app, hmi_level()).WillByDefault(Return(level));
+
+ Expectation is_for_plugin =
+ EXPECT_CALL(*module, IsAppForPlugin(app_ptr)).WillOnce(Return(true));
+ EXPECT_CALL(*module, OnAppHMILevelChanged(app_ptr, _))
+ .Times(1)
+ .After(is_for_plugin);
+ manager->OnAppHMILevelChanged(app_ptr,
+ mobile_apis::HMILevel::eType::HMI_FULL);
+}
+
+TEST_F(PluginManagerTest, CanAppChangeHMILevel) {
+ using test::components::application_manager_test::MockApplication;
+ NiceMock<MockApplication>* app = new NiceMock<MockApplication>();
+ application_manager::ApplicationSharedPtr app_ptr(app);
+
+ const application_manager::custom_str::CustomString name("name");
+ ON_CALL(*app, name()).WillByDefault(ReturnRef(name));
+
+ Expectation is_for_plugin =
+ EXPECT_CALL(*module, IsAppForPlugin(app_ptr)).WillOnce(Return(true));
+ EXPECT_CALL(*module, CanAppChangeHMILevel(app_ptr, _))
+ .Times(1)
+ .After(is_for_plugin)
+ .WillOnce(Return(true));
+ ASSERT_TRUE(manager->CanAppChangeHMILevel(
+ app_ptr, mobile_apis::HMILevel::eType::HMI_FULL));
+}
+
+TEST_F(PluginManagerTest, CanAppChangeHMILevelNegative) {
+ using test::components::application_manager_test::MockApplication;
+ NiceMock<MockApplication>* app = new NiceMock<MockApplication>();
+ application_manager::ApplicationSharedPtr app_ptr(app);
+
+ const application_manager::custom_str::CustomString name("name");
+ ON_CALL(*app, name()).WillByDefault(ReturnRef(name));
+
+ Expectation is_for_plugin =
+ EXPECT_CALL(*module, IsAppForPlugin(app_ptr)).WillOnce(Return(true));
+ EXPECT_CALL(*module, CanAppChangeHMILevel(app_ptr, _))
+ .Times(1)
+ .After(is_for_plugin)
+ .WillOnce(Return(false));
+ ASSERT_FALSE(manager->CanAppChangeHMILevel(
+ app_ptr, mobile_apis::HMILevel::eType::HMI_BACKGROUND));
+}
+
+TEST_F(PluginManagerTest, CanAppChangeHMILevelNotForPlugin) {
+ using test::components::application_manager_test::MockApplication;
+ NiceMock<MockApplication>* app = new NiceMock<MockApplication>();
+ application_manager::ApplicationSharedPtr app_ptr(app);
+
+ const application_manager::custom_str::CustomString name("name");
+ ON_CALL(*app, name()).WillByDefault(ReturnRef(name));
+
+ Expectation is_for_plugin =
+ EXPECT_CALL(*module, IsAppForPlugin(app_ptr)).WillOnce(Return(false));
+ EXPECT_CALL(*module, CanAppChangeHMILevel(app_ptr, _))
+ .Times(0)
+ .After(is_for_plugin);
+ ASSERT_TRUE(manager->CanAppChangeHMILevel(
+ app_ptr, mobile_apis::HMILevel::eType::HMI_BACKGROUND));
+}
+
+} // namespace functional_modules
diff --git a/src/components/functional_module/test/src/settings_test.cc b/src/components/functional_module/test/src/settings_test.cc
new file mode 100644
index 0000000000..ad7324c350
--- /dev/null
+++ b/src/components/functional_module/test/src/settings_test.cc
@@ -0,0 +1,92 @@
+#include "gtest/gtest.h"
+#include "functional_module/settings.h"
+
+namespace functional_modules {
+
+TEST(Settings, ChangeConfigFile) {
+ Settings set;
+ set.ChangeConfigFile("test.ini");
+ int port = 0;
+ bool result = set.ReadParameter("HMI", "ServerPort", &port);
+ ASSERT_TRUE(result);
+ ASSERT_EQ(8087, port);
+ set.ChangeConfigFile("not_existing_file.ini");
+ result = set.ReadParameter("HMI", "ServerPort", &port);
+ ASSERT_FALSE(result);
+}
+
+TEST(Settings, ReadParamIntWithSectionSuccess) {
+ Settings set;
+ set.ChangeConfigFile("test.ini");
+ int port = 0;
+ bool result = set.ReadParameter<int>("HMI", "ServerPort", &port);
+ ASSERT_TRUE(result);
+ ASSERT_EQ(8087, port);
+}
+
+TEST(Settings, ReadParamIntWithSectionFail) {
+ Settings set;
+ set.ChangeConfigFile("test.ini");
+ int port = 0;
+ bool result = set.ReadParameter<int>("HMI", "ServerPo", &port);
+ ASSERT_FALSE(result);
+ ASSERT_EQ(0, port);
+}
+
+TEST(Settings, ReadParamBoolWithSectionSuccess) {
+ Settings set;
+ set.ChangeConfigFile("test.ini");
+ bool launch = true;
+ bool result = set.ReadParameter<bool>("HMI", "LaunchHMI", &launch);
+ ASSERT_TRUE(result);
+ ASSERT_FALSE(launch);
+}
+
+TEST(Settings, ReadParamBoolWithSectionFail) {
+ Settings set;
+ set.ChangeConfigFile("test.ini");
+ bool launch = true;
+ bool result = set.ReadParameter<bool>("HMI", "LaunchH", &launch);
+ ASSERT_FALSE(result);
+ ASSERT_TRUE(launch);
+}
+
+TEST(Settings, ReadParamStringWithSectionSuccess) {
+ Settings set;
+ set.ChangeConfigFile("test.ini");
+ std::string file_path;
+ bool result = set.ReadParameter<std::string>(
+ "Remote Control", "InteriorVDCapabilitiesFile", &file_path);
+ ASSERT_TRUE(result);
+ ASSERT_EQ("./plugins/InteriorVehicleDataCapabilities.json", file_path);
+}
+
+TEST(Settings, ReadParamStringWithSectionFail) {
+ Settings set;
+ set.ChangeConfigFile("test.ini");
+ std::string file_path;
+ bool result =
+ set.ReadParameter("Remote Control", "InteriorVDCFile", &file_path);
+ ASSERT_FALSE(result);
+ ASSERT_EQ("", file_path);
+}
+
+TEST(Settings, ReadParamStringNoSectionSuccess) {
+ Settings set;
+ set.ChangeConfigFile("test.ini");
+ std::string caps;
+ bool result = set.ReadParameter<std::string>("HMICapabilities", &caps);
+ ASSERT_TRUE(result);
+ ASSERT_EQ("hmi_capabilities.json", caps);
+}
+
+TEST(Settings, ReadParamStringNoSectionFail) {
+ Settings set;
+ set.ChangeConfigFile("test.ini");
+ std::string caps;
+ bool result = set.ReadParameter("HMICaps", &caps);
+ ASSERT_FALSE(result);
+ ASSERT_EQ("", caps);
+}
+
+} // namespace functional_modules
diff --git a/src/components/functional_module/test/test.ini b/src/components/functional_module/test/test.ini
new file mode 100644
index 0000000000..211b7edc78
--- /dev/null
+++ b/src/components/functional_module/test/test.ini
@@ -0,0 +1,36 @@
+ ; The INI-file consists of different chapters.
+; Each chapter begins with the line containing
+; the name in square brackets. Syntax:
+; [chapter]
+; The chapters consists of a set of items with a
+; assinged value. The syntax is:
+; item=value
+; All white spaces an second encounters of chapters
+; or items will be ignored.
+; Remarks start with semicolon or star as first character.
+; It is alowed for names of chapters and items to
+; contain semicolon and star. Possible syntax is:
+; [ chapter ] ;Remark
+; item = value ;Remark
+
+[HMI]
+LaunchHMI = false
+ServerAddress = 127.0.0.1
+ServerPort = 8087
+
+[MAIN]
+
+;The value of a variable ThreadStackSize used only if its realy needed, other way stack size will be PTHREAD_STACK_MIN
+;
+ThreadStackSize = 20480
+MixingAudioSupported = true
+HMICapabilities = hmi_capabilities.json
+MaxCmdID = 2000000000
+; Default request timeout in milliseconds
+DefaultTimeout = 10000
+
+SystemFilesPath = /tmp/fs/mp/images/ivsu_cache
+
+
+[Remote Control]
+InteriorVDCapabilitiesFile = ./plugins/InteriorVehicleDataCapabilities.json
diff --git a/src/components/hmi_message_handler/include/hmi_message_handler/hmi_message_adapter_impl.h b/src/components/hmi_message_handler/include/hmi_message_handler/hmi_message_adapter_impl.h
index bd118032d6..1a28c89bda 100644
--- a/src/components/hmi_message_handler/include/hmi_message_handler/hmi_message_adapter_impl.h
+++ b/src/components/hmi_message_handler/include/hmi_message_handler/hmi_message_adapter_impl.h
@@ -51,8 +51,15 @@ class HMIMessageAdapterImpl : public HMIMessageAdapter {
/**
* \brief Destructor
*/
- virtual ~HMIMessageAdapterImpl();
+ ~HMIMessageAdapterImpl();
+#ifdef SDL_REMOTE_CONTROL
+ /**
+ * @brief Subscribes to notification from HMI
+ * @param hmi_notification string with notification name
+ */
+ void SubscribeToHMINotification(const std::string& hmi_notification) OVERRIDE;
+#endif // SDL_REMOTE_CONTROL
protected:
virtual HMIMessageHandler* handler() const {
return handler_;
diff --git a/src/components/hmi_message_handler/include/hmi_message_handler/hmi_message_handler_impl.h b/src/components/hmi_message_handler/include/hmi_message_handler/hmi_message_handler_impl.h
index 8b238b4aa8..daba87e738 100644
--- a/src/components/hmi_message_handler/include/hmi_message_handler/hmi_message_handler_impl.h
+++ b/src/components/hmi_message_handler/include/hmi_message_handler/hmi_message_handler_impl.h
@@ -89,14 +89,21 @@ class HMIMessageHandlerImpl : public HMIMessageHandler,
explicit HMIMessageHandlerImpl(const HMIMessageHandlerSettings& settings);
~HMIMessageHandlerImpl();
- void OnMessageReceived(MessageSharedPointer message);
- void SendMessageToHMI(MessageSharedPointer message);
+ void OnMessageReceived(MessageSharedPointer message) OVERRIDE;
+ void SendMessageToHMI(MessageSharedPointer message) OVERRIDE;
void set_message_observer(HMIMessageObserver* observer);
- void OnErrorSending(MessageSharedPointer message);
- void AddHMIMessageAdapter(HMIMessageAdapter* adapter);
- void RemoveHMIMessageAdapter(HMIMessageAdapter* adapter);
-
- virtual const HMIMessageHandlerSettings& get_settings() const OVERRIDE;
+ void OnErrorSending(MessageSharedPointer message) OVERRIDE;
+ void AddHMIMessageAdapter(HMIMessageAdapter* adapter) OVERRIDE;
+ void RemoveHMIMessageAdapter(HMIMessageAdapter* adapter) OVERRIDE;
+
+#ifdef SDL_REMOTE_CONTROL
+ /**
+ * @brief Subscribes to notification from HMI
+ * @param hmi_notification string with notification name
+ */
+ void SubscribeToHMINotification(const std::string& hmi_notification) OVERRIDE;
+#endif // SDL_REMOTE_CONTROL
+ const HMIMessageHandlerSettings& get_settings() const OVERRIDE;
#ifdef BUILD_TESTS
std::set<HMIMessageAdapter*> message_adapters() const {
@@ -120,15 +127,16 @@ class HMIMessageHandlerImpl : public HMIMessageHandler,
// threads::MessageLoopThread<*>::Handler implementations
// CALLED ON messages_from_hmi_ THREAD!
- virtual void Handle(const impl::MessageFromHmi message) OVERRIDE;
+ void Handle(const impl::MessageFromHmi message) OVERRIDE;
// CALLED ON messages_to_hmi_ THREAD!
- virtual void Handle(const impl::MessageToHmi message) OVERRIDE;
+ void Handle(const impl::MessageToHmi message) OVERRIDE;
private:
const HMIMessageHandlerSettings& settings_;
HMIMessageObserver* observer_;
- mutable sync_primitives::Lock observer_locker_;
std::set<HMIMessageAdapter*> message_adapters_;
+ mutable sync_primitives::Lock observer_locker_;
+ mutable sync_primitives::Lock message_adapters_locker_;
// Construct message threads when everything is already created
diff --git a/src/components/hmi_message_handler/include/hmi_message_handler/messagebroker_adapter.h b/src/components/hmi_message_handler/include/hmi_message_handler/messagebroker_adapter.h
index f582cb2b81..8acc8fb207 100644
--- a/src/components/hmi_message_handler/include/hmi_message_handler/messagebroker_adapter.h
+++ b/src/components/hmi_message_handler/include/hmi_message_handler/messagebroker_adapter.h
@@ -76,6 +76,13 @@ class MessageBrokerAdapter : public HMIMessageAdapterImpl,
void* SubscribeAndBeginReceiverThread(void* param);
+#ifdef SDL_REMOTE_CONTROL
+ /**
+ * @brief Subscribes to notification from HMI
+ * @param hmi_notification string with notification name
+ */
+ void SubscribeToHMINotification(const std::string& hmi_notification) FINAL;
+#endif // SDL_REMOTE_CONTROL
protected:
void ProcessRecievedFromMB(Json::Value& root);
diff --git a/src/components/hmi_message_handler/src/hmi_message_adapter_impl.cc b/src/components/hmi_message_handler/src/hmi_message_adapter_impl.cc
index 48874618a0..e58c5a8fb6 100644
--- a/src/components/hmi_message_handler/src/hmi_message_adapter_impl.cc
+++ b/src/components/hmi_message_handler/src/hmi_message_adapter_impl.cc
@@ -40,4 +40,10 @@ HMIMessageAdapterImpl::~HMIMessageAdapterImpl() {
handler_ = 0;
}
+#ifdef SDL_REMOTE_CONTROL
+void HMIMessageAdapterImpl::SubscribeToHMINotification(
+ const std::string& hmi_notification) {
+ // TODO(SL): Find an immplementation
+}
+#endif // SDL_REMOTE_CONTROL
} // namespace hmi_message_handler
diff --git a/src/components/hmi_message_handler/src/hmi_message_handler_impl.cc b/src/components/hmi_message_handler/src/hmi_message_handler_impl.cc
index 1c774b9efe..654b67de7f 100644
--- a/src/components/hmi_message_handler/src/hmi_message_handler_impl.cc
+++ b/src/components/hmi_message_handler/src/hmi_message_handler_impl.cc
@@ -94,6 +94,7 @@ void HMIMessageHandlerImpl::AddHMIMessageAdapter(HMIMessageAdapter* adapter) {
LOG4CXX_WARN(logger_, "HMIMessageAdapter is not valid!");
return;
}
+ sync_primitives::AutoLock lock(message_adapters_locker_);
message_adapters_.insert(adapter);
}
@@ -104,6 +105,7 @@ void HMIMessageHandlerImpl::RemoveHMIMessageAdapter(
LOG4CXX_WARN(logger_, "HMIMessageAdapter is not valid!");
return;
}
+ sync_primitives::AutoLock lock(message_adapters_locker_);
message_adapters_.erase(adapter);
}
@@ -123,11 +125,23 @@ void HMIMessageHandlerImpl::Handle(const impl::MessageFromHmi message) {
LOG4CXX_INFO(logger_, "Message from hmi given away.");
}
void HMIMessageHandlerImpl::Handle(const impl::MessageToHmi message) {
+ sync_primitives::AutoLock lock(message_adapters_locker_);
for (std::set<HMIMessageAdapter*>::iterator it = message_adapters_.begin();
it != message_adapters_.end();
++it) {
(*it)->SendMessageToHMI(message);
}
}
+#ifdef SDL_REMOTE_CONTROL
+void HMIMessageHandlerImpl::SubscribeToHMINotification(
+ const std::string& hmi_notification) {
+ sync_primitives::AutoLock lock(message_adapters_locker_);
+ for (std::set<HMIMessageAdapter*>::iterator it = message_adapters_.begin();
+ it != message_adapters_.end();
+ ++it) {
+ (*it)->SubscribeToHMINotification(hmi_notification);
+ }
+}
+#endif // SDL_REMOTE_CONTROL
} // namespace hmi_message_handler
diff --git a/src/components/include/test/application_manager/mock_application_manager.h b/src/components/include/test/application_manager/mock_application_manager.h
index 8d1bb756c2..e4500fb602 100644
--- a/src/components/include/test/application_manager/mock_application_manager.h
+++ b/src/components/include/test/application_manager/mock_application_manager.h
@@ -45,6 +45,7 @@
#include "application_manager/hmi_capabilities.h"
#include "application_manager/vehicle_info_data.h"
#include "application_manager/state_controller.h"
+#include "application_manager/message.h"
#include "resumption/last_state.h"
#include "interfaces/MOBILE_API.h"
#include "application_manager/app_launch/app_launch_ctrl.h"
@@ -74,6 +75,28 @@ class MockApplicationManager : public application_manager::ApplicationManager {
application, application_manager::ApplicationSharedPtr(uint32_t app_id));
MOCK_CONST_METHOD0(active_application,
application_manager::ApplicationSharedPtr());
+
+#ifdef SDL_REMOTE_CONTROL
+ MOCK_CONST_METHOD2(application,
+ application_manager::ApplicationSharedPtr(
+ const std::string& device_id,
+ const std::string& policy_app_id));
+ MOCK_METHOD1(SubscribeToHMINotification,
+ void(const std::string& hmi_notification));
+ MOCK_METHOD1(GetDeviceHandle, uint32_t(uint32_t connection_key));
+ MOCK_CONST_METHOD1(IsAudioStreamingAllowed, bool(uint32_t connection_key));
+ MOCK_CONST_METHOD1(IsVideoStreamingAllowed, bool(uint32_t connection_key));
+ MOCK_METHOD2(ChangeAppsHMILevel,
+ void(uint32_t app_id, mobile_apis::HMILevel::eType level));
+ MOCK_METHOD0(GetPluginManager, functional_modules::PluginManager&());
+ MOCK_CONST_METHOD1(
+ devices, std::vector<std::string>(const std::string& policy_app_id));
+ MOCK_METHOD1(SendPostMessageToMobile,
+ void(const application_manager::MessagePtr& message));
+ MOCK_METHOD1(SendPostMessageToHMI,
+ void(const application_manager::MessagePtr& message));
+#endif // SDL_REMOTE_CONTROL
+
MOCK_CONST_METHOD1(
application_by_hmi_app,
application_manager::ApplicationSharedPtr(uint32_t hmi_app_id));
@@ -110,6 +133,8 @@ class MockApplicationManager : public application_manager::ApplicationManager {
MOCK_METHOD1(
SendMessageToHMI,
void(const application_manager::commands::MessageSharedPtr message));
+ MOCK_METHOD1(RemoveHMIFakeParameters,
+ void(application_manager::MessagePtr& message));
MOCK_METHOD1(
ManageHMICommand,
bool(const application_manager::commands::MessageSharedPtr message));
diff --git a/src/components/include/test/application_manager/mock_application_manager_settings.h b/src/components/include/test/application_manager/mock_application_manager_settings.h
index fd9e2aa8a3..c09e79a52f 100644
--- a/src/components/include/test/application_manager/mock_application_manager_settings.h
+++ b/src/components/include/test/application_manager/mock_application_manager_settings.h
@@ -101,6 +101,7 @@ class MockApplicationManagerSettings
MOCK_CONST_METHOD0(start_stream_retry_amount,
const std::pair<uint32_t, int32_t>&());
MOCK_CONST_METHOD0(app_icons_folder, const std::string&());
+ MOCK_CONST_METHOD0(plugins_folder, const std::string&());
MOCK_CONST_METHOD0(app_icons_folder_max_size, const uint32_t&());
MOCK_CONST_METHOD0(app_icons_amount_to_remove, const uint32_t&());
MOCK_CONST_METHOD0(list_files_response_size, const uint32_t&());
diff --git a/src/components/include/utils/macro.h b/src/components/include/utils/macro.h
index 0e029e4b06..4cf76fe022 100644
--- a/src/components/include/utils/macro.h
+++ b/src/components/include/utils/macro.h
@@ -113,6 +113,13 @@
return; \
}
+#define EXPORT_FUNCTION(TypeName) extern "C" TypeName* Create();
+
+#define EXPORT_FUNCTION_IMPL(TypeName) \
+ extern "C" TypeName* Create() { \
+ return new TypeName(); \
+ }
+
#define NOTREACHED() DCHECK(!"Unreachable code")
// Allows to perform static check that virtual function from base class is
@@ -134,6 +141,8 @@
#ifdef BUILD_TESTS
#define FRIEND_TEST(test_case_name, test_name) \
friend class test_case_name##_##test_name##_Test
-#endif
+#else // BUILD_TESTS
+#define FRIEND_TEST(test_case_name, test_name)
+#endif // BUILD_TESTS
#endif // SRC_COMPONENTS_INCLUDE_UTILS_MACRO_H_