diff options
83 files changed, 5999 insertions, 933 deletions
diff --git a/src/appMain/life_cycle.cc b/src/appMain/life_cycle.cc index 1d8e92210e..3c3895d02f 100644 --- a/src/appMain/life_cycle.cc +++ b/src/appMain/life_cycle.cc @@ -128,6 +128,7 @@ bool LifeCycle::StartComponents() { hmi_handler_ = new hmi_message_handler::HMIMessageHandlerImpl(profile_); media_manager_ = new media_manager::MediaManagerImpl(*app_manager_, profile_); + app_manager_->set_connection_handler(connection_handler_); if (!app_manager_->Init(*last_state_, media_manager_)) { LOG4CXX_ERROR(logger_, "Application manager init failed."); return false; @@ -177,7 +178,6 @@ bool LifeCycle::StartComponents() { // It's important to initialise TM after setting up listener chain // [TM -> CH -> AM], otherwise some events from TM could arrive at nowhere app_manager_->set_protocol_handler(protocol_handler_); - app_manager_->set_connection_handler(connection_handler_); app_manager_->set_hmi_message_handler(hmi_handler_); transport_manager_->Init(*last_state_); diff --git a/src/appMain/smartDeviceLink.ini b/src/appMain/smartDeviceLink.ini index a9baf8c45a..c5cd4dab8e 100644 --- a/src/appMain/smartDeviceLink.ini +++ b/src/appMain/smartDeviceLink.ini @@ -238,3 +238,20 @@ UseDBForResumption = false AttemptsToOpenResumptionDB = 5 ; Timeout between attempts during opening DB in milliseconds OpenAttemptTimeoutMsResumptionDB = 500 + +[AppLaunch] +; time in milliseconds started from device connection - after expiring SDL remotely launches all known not-yet-registered apps from this device +AppLaunchWaitTime = 5000 +; the number of times SDL attempts to launch an application after device connection - applied separately to each application from the given device +AppLaunchMaxRetryAttempt = 3 +; time in milliseconds started by SDL after app launch request. if expired and app did not register, SDL sends new launch request. applied separately to each app +AppLaunchRetryWaitTime = 15000 +; the number of the given device connections that the requested application failed to register after SDL's launch attempts - SDL removes app's bundleID on "value + 1" device connection +RemoveBundleIDattempts = 3 +; the maximum number of iOS devices for which entries can be remembered by SDL +MaxNumberOfiOSDevice = 10 +; time in milliseconds started after request to launch the first app. after either expires or the first app registers SDL requests to launch the second app. +WaitTimeBetweenApps = 4000 +; App Launch on iOS devices SDL feature enabler/disabler +EnableAppLaunchIOS = true + diff --git a/src/components/application_manager/CMakeLists.txt b/src/components/application_manager/CMakeLists.txt index d44cf6c69e..4137a67891 100644 --- a/src/components/application_manager/CMakeLists.txt +++ b/src/components/application_manager/CMakeLists.txt @@ -46,6 +46,7 @@ include_directories ( ${COMPONENTS_DIR}/config_profile/include/ ${COMPONENTS_DIR}/request_watchdog/include/ ${COMPONENTS_DIR}/resumption/include/ + ${COMPONENTS_DIR}/app_launch/include/ ${COMPONENTS_DIR}/rpc_base/include/ ${COMPONENTS_DIR}/interfaces ${CMAKE_BINARY_DIR}/src/components/ @@ -95,6 +96,12 @@ file (GLOB RESUMPTION ${AM_SOURCE_DIR}/src/resumption/* ) + +file (GLOB APP_LAUNCH + ${AM_SOURCE_DIR}/src/app_launch/* +) + + file (GLOB MOBILE_COMMANDS_SOURCES ${AM_SOURCE_DIR}/src/commands/* ${AM_SOURCE_DIR}/src/commands/mobile/* @@ -382,7 +389,8 @@ add_library("MessageHelper" ${MESSAGE_HELPER_SOURCES}) add_library("AMMobileCommandsLibrary" ${MOBILE_COMMANDS_SOURCES} ) target_link_libraries("AMMobileCommandsLibrary" ${LIBRARIES} AMEventEngine) -add_library("ApplicationManager" ${SOURCES} ${RESUMPTION}) +add_library("ApplicationManager" ${SOURCES} ${RESUMPTION} ${APP_LAUNCH}) + target_link_libraries("ApplicationManager" ${LIBRARIES} AMHMICommandsLibrary AMMobileCommandsLibrary AMEventEngine diff --git a/src/components/application_manager/include/application_manager/app_launch/app_launch_ctrl.h b/src/components/application_manager/include/application_manager/app_launch/app_launch_ctrl.h new file mode 100644 index 0000000000..9fc85db38c --- /dev/null +++ b/src/components/application_manager/include/application_manager/app_launch/app_launch_ctrl.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_CTRL_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_CTRL_H_ +#include <string> +#include "utils/shared_ptr.h" + +namespace application_manager { +class Application; +typedef utils::SharedPtr<const Application> ApplicationConstSharedPtr; +} // namespace application_manager + +namespace app_launch { + +/** + * @brief The AppLaunchCtrl class manage logic of AppLaunch feature + * It launches all known applications on newly connected device + */ +class AppLaunchCtrl { + public: + /** + * @brief OnAppRegistered should be called when application registered + * Save application parameters to database + * @param app application to save + */ + virtual void OnAppRegistered(const application_manager::Application& app) = 0; + + /** + * @brief OnDeviceConnected shoudl be called on device connected event + * Start launching saaved applications on ios device + * @param device_mac + */ + virtual void OnDeviceConnected(const std::string& device_mac) = 0; + + /** + * @brief OnMasterReset clear database of saved applications + */ + virtual void OnMasterReset() = 0; + virtual ~AppLaunchCtrl() {} +}; + +} // namespace app_launch + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_CTRL_H_ diff --git a/src/components/application_manager/include/application_manager/app_launch/app_launch_ctrl_impl.h b/src/components/application_manager/include/application_manager/app_launch/app_launch_ctrl_impl.h new file mode 100644 index 0000000000..1f508eebe5 --- /dev/null +++ b/src/components/application_manager/include/application_manager/app_launch/app_launch_ctrl_impl.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_CTRL_IMPL_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_CTRL_IMPL_H_ + +#include "application_manager/app_launch/app_launch_ctrl.h" +#include "application_manager/app_launch/app_launch_data.h" +#include "application_manager/app_launch/apps_launcher.h" +#include "application_manager/app_launch/device_apps_launcher.h" +#include "application_manager/app_launch_settings.h" + +namespace connection_handler { +class ConnectionHandler; +} // connection_handler + +namespace resumption { +class ResumeCtrl; +} // resumption + +namespace app_launch { +// TODO(AK) Use unique pointer +typedef utils::SharedPtr<timer::Timer> TimerPtr; +class MultipleAppsLauncherFactoryImpl; + +class AppLaunchCtrlImpl : public AppLaunchCtrl { + public: + /** + * @brief allows to create AppLaunchCtrlImpl object + */ + AppLaunchCtrlImpl(AppLaunchData& data, + application_manager::ApplicationManager& app_mngr, + const AppLaunchSettings& settings); + + /** + * @brief allows to destroy AppLaunchCtrlImpl object + */ + ~AppLaunchCtrlImpl() {} + + void OnAppRegistered(const application_manager::Application& app) OVERRIDE; + void OnDeviceConnected(const std::string& device_mac) OVERRIDE; + void OnMasterReset() OVERRIDE; + + private: + const AppLaunchSettings& settings_; + AppLaunchData& app_launch_data_; + resumption::ResumeCtrl& resume_ctrl_; + + AppsLauncher apps_launcher_; + DeviceAppsLauncher device_apps_launcher_; + + DISALLOW_COPY_AND_ASSIGN(AppLaunchCtrlImpl); +}; + +} // namespace app_launch + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_CTRL_IMPL_H_ diff --git a/src/components/application_manager/include/application_manager/app_launch/app_launch_data.h b/src/components/application_manager/include/application_manager/app_launch/app_launch_data.h new file mode 100644 index 0000000000..0d52384018 --- /dev/null +++ b/src/components/application_manager/include/application_manager/app_launch/app_launch_data.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_DATA_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_DATA_H_ + +#include <stdint.h> +#include <vector> +#include <string> +#include "utils/shared_ptr.h" + +namespace app_launch { + +/** + * @brief struct holds AppLaunch data + */ +struct ApplicationData { + ApplicationData(const std::string& mobile_app_id, + const std::string& bundle_id, + const std::string& device_id) + : mobile_app_id_(mobile_app_id) + , bundle_id_(bundle_id) + , device_mac_(device_id) {} + + std::string mobile_app_id_; + std::string bundle_id_; + std::string device_mac_; + bool operator==(const ApplicationData& app_data) const { + return mobile_app_id_ == app_data.mobile_app_id_ && + bundle_id_ == app_data.bundle_id_ && device_mac_ == device_mac_; + } +}; +typedef utils::SharedPtr<ApplicationData> ApplicationDataPtr; + +/** + * @brief class contains interfaces to AppLaunchDataDB and AppLaunchDataJson + */ +class AppLaunchData { + public: + /** + * @brief allows correct delete heir object + */ + virtual ~AppLaunchData() {} + + /** + * @brief insert new data to DB + * @param app_data - data to inserting + * @return true in success cases and false othrewise + */ + virtual bool AddApplicationData(const ApplicationData& app_data) = 0; + + /** + * @brief select from DB all records with this dev_mac + * @param app_data - data to inserting + * @param dev_apps - + * @return vector of pointers on results of select + */ + virtual std::vector<ApplicationDataPtr> GetApplicationDataByDevice( + const std::string& dev_mac) = 0; + /** + * @brief delete App_launch table in DB, after calling this + * one, it should again call init + * @return true in success cases and false othrewise + */ + virtual bool Clear() = 0; + + /** + * @brief Persist saves resumption data on file system + */ + virtual bool Persist() = 0; +}; +} // namespace app_launch + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_DATA_H_ diff --git a/src/components/application_manager/include/application_manager/app_launch/app_launch_data_db.h b/src/components/application_manager/include/application_manager/app_launch/app_launch_data_db.h new file mode 100644 index 0000000000..92d6bbd9ef --- /dev/null +++ b/src/components/application_manager/include/application_manager/app_launch/app_launch_data_db.h @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_DATA_DB_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_DATA_DB_H_ +#include <memory> +#include "application_manager/app_launch/app_launch_data_impl.h" +#include "application_manager/app_launch_settings.h" +#include "utils/macro.h" +#ifdef __QNX__ +#include "utils/qdb_wrapper/sql_database.h" +#include "utils/qdb_wrapper/sql_query.h" +#else // linux +#include "utils/sqlite_wrapper/sql_database.h" +#include "utils/sqlite_wrapper/sql_query.h" +#endif + +namespace app_launch { + +const std::string kDatabaseName = "resumption"; + +/** + * @brief Show should database be saved in a disk file or in memory + */ +enum DbStorage { In_Memory_Storage = 0, In_File_Storage }; + +/** + * @brief class contains logic for representation application + * launch_app data in data base + */ +class AppLaunchDataDB : public AppLaunchDataImpl { + public: + /** + * @brief Constructor of AppLaunchDataDB + * @param settings - setting of AppLaunch + */ + AppLaunchDataDB(const AppLaunchSettings& settings, + DbStorage db_storage = In_File_Storage); + + /** + * @brief allows to destroy AppLaunchDataDB object + */ + ~AppLaunchDataDB(); + + /** + * @brief Creates or opens DB and initialize it + * @return false if DB doesn't initialize + * otherwise returns true + */ + bool Init(); + + /** + * @brief delete App_launch table in DB, after calling this + * one, it should again call init + * @return true in success cases and false othrewise + */ + bool Clear() OVERRIDE; + + /** + * @brief Write database to file system + */ + bool Persist() OVERRIDE; + + /** + * @return current count of records + * AppLaunch in DB + */ + uint32_t GetCurentNumberOfAppData() const; + + /** + * @param app_data - searching fields in object + * @return true in case application data already existed + * and false othrewise + */ + bool IsAppDataAlreadyExisted(const ApplicationData& app_data) const OVERRIDE; + + /** + * @brief returns pointer to data base + */ + utils::dbms::SQLDatabase* db() const; + + enum ApplicationDataDBIndexes { + result_query = 0, + device_mac_index = 0, + application_id_index, + bundle_id_index, + timestamp_index + }; + + private: + /** + * @brief update time stamp + * @param app_data - data to update + * @return true in success cases and false othrewise + */ + bool RefreshAppSessionTime(const ApplicationData& app_data) OVERRIDE; + + /** + * @brief insert new data to DB + * @param app_data - data to inserting + * @return true in success cases and false othrewise + */ + bool AddNewAppData(const ApplicationData& app_data) OVERRIDE; + + /** + * @brief select from DB all records with this dev_mac + * @param app_data - data to inserting + * @return vector of ponter on founded records + */ + std::vector<ApplicationDataPtr> GetAppDataByDevMac( + const std::string& dev_mac) const OVERRIDE; + /** + * @brief delete record with oldest timestamp + * @return true in success cases and false othrewise + */ + bool DeleteOldestAppData() OVERRIDE; + + /** + * @brief write DB to file + * @return true in success cases and false othrewise + */ + bool WriteDb(); + + /** + * @brief returns pointer to data base + */ + std::auto_ptr<utils::dbms::SQLDatabase> db_; + + /** + * @brief indicate initializing status of DB + */ + bool init_successeful_; + + DISALLOW_COPY_AND_ASSIGN(AppLaunchDataDB); +}; + +} // namespace app_launch + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_DATA_DB_H_ diff --git a/src/components/application_manager/include/application_manager/app_launch/app_launch_data_impl.h b/src/components/application_manager/include/application_manager/app_launch/app_launch_data_impl.h new file mode 100644 index 0000000000..111ff25ab2 --- /dev/null +++ b/src/components/application_manager/include/application_manager/app_launch/app_launch_data_impl.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_DATA_IMPL_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_DATA_IMPL_H_ + +#include "application_manager/app_launch/app_launch_data.h" +#include "application_manager/app_launch_settings.h" + +namespace app_launch { + +class AppLaunchDataImpl : public AppLaunchData { + public: + /** + * @brief Constructor of AppLaunchDataImpl + * @param settings - setting of AppLaunch + */ + AppLaunchDataImpl(const AppLaunchSettings& settings); + + /** + * @brief allows to destroy AppLaunchDataImpl object + */ + virtual ~AppLaunchDataImpl(); + + /** + * @brief insert new data to DB + * @param app_data - data to inserting + * @return true in success cases and false othrewise + */ + virtual bool AddApplicationData(const ApplicationData& app_data); + + /** + * @brief select from DB all records with this dev_mac + * @param app_data - data to inserting + * @return return vector of pointers on founded records + */ + std::vector<ApplicationDataPtr> GetApplicationDataByDevice( + const std::string& dev_mac) OVERRIDE; + + /** + * @brief Persist saves resumption data on file system + */ + virtual bool Persist() = 0; + + /** + * @return max count of iOS device that can be connected + */ + virtual uint32_t get_max_number_iOS_devs() const { + return kMaxNumberOfiOSdevice; + } + + /** + * @brief all AppLaunch settings + */ + const AppLaunchSettings& settings_; + + private: + /** + * @param app_data - searching filled in object + * @return true in case application data already existed + * and false othrewise + */ + virtual bool IsAppDataAlreadyExisted( + const ApplicationData& app_data) const = 0; + + /** + * @brief update time stamp + * @param app_data - data to update + * @return true in success cases and false othrewise + */ + virtual bool RefreshAppSessionTime(const ApplicationData& app_data) = 0; + + /** + * @brief insert new data to DB + * @param app_data - data to inserting + * @return true in success cases and false othrewise + */ + virtual bool AddNewAppData(const ApplicationData& app_data) = 0; + + /** + * @brief select from DB all records with this dev_mac + * @param app_data - data to inserting + * @return vector of ponter on founded records + */ + virtual std::vector<ApplicationDataPtr> GetAppDataByDevMac( + const std::string& dev_mac) const = 0; + + /** + * @brief delete record with oldest timestamp + * @return true in success cases and false othrewise + */ + virtual bool DeleteOldestAppData() = 0; + + /** + * @return current count of records + * AppLaunch in DB + */ + virtual uint32_t GetCurentNumberOfAppData() const = 0; + + /** + * @brief max count of iOS device that can be connected + */ + const uint32_t kMaxNumberOfiOSdevice; +}; +} // namespace app_launch + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_DATA_IMPL_H_ diff --git a/src/components/application_manager/include/application_manager/app_launch/app_launch_data_json.h b/src/components/application_manager/include/application_manager/app_launch/app_launch_data_json.h new file mode 100644 index 0000000000..61117e552b --- /dev/null +++ b/src/components/application_manager/include/application_manager/app_launch/app_launch_data_json.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_DATA_JSON_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_DATA_JSON_H_ + +#include "application_manager/app_launch/app_launch_data_impl.h" +#include "smart_objects/smart_object.h" +#include "resumption/last_state.h" +#include "utils/lock.h" +#include "utils/macro.h" + +namespace app_launch { + +enum { NotFound = -1 }; +/** + * @brief class contains logic for representation application launch_app data in + * json file + */ +class AppLaunchDataJson : public AppLaunchDataImpl { + public: + /** + * @brief Constructor of AppLaunchDataJson object + */ + AppLaunchDataJson(const AppLaunchSettings& settings, + resumption::LastState& last_state); + /** + * @brief allows to destroy AppLaunchDataJson object + */ + ~AppLaunchDataJson(); + + /** + * @brief Write Json to file system + */ + bool Persist() OVERRIDE; + + /** + * @brief delete App_launch table in DB, after calling this + * one, it should again call init + * @return true in success cases and false othrewise + */ + virtual bool Clear(); + + /** + * @return current count of records + * AppLaunch in DB + */ + uint32_t GetCurentNumberOfAppData() const; + + /** + * @param app_data - searching filled in object + * @return true in case application data already existed + * and false othrewise + */ + virtual bool IsAppDataAlreadyExisted(const ApplicationData& app_data) const; + + /** + * @param app_data - searching filled in object + * @param founded_index - referenceto index of founded record + * in case it wasn't found it'll be -1 + * @return pointer to json list object + */ + Json::Value& GetApplicationListAndIndex(const ApplicationData& app_data, + int32_t& founded_index) const; + + private: + /** + * @brief update time stamp + * @param app_data - data to update + * @return true in success cases and false othrewise + */ + virtual bool RefreshAppSessionTime(const ApplicationData& app_data); + + /** + * @brief insert new data to DB + * @param app_data - data to inserting + * @return true in success cases and false othrewise + */ + virtual bool AddNewAppData(const ApplicationData& app_data); + + /** + * @brief select from DB all records with this dev_mac + * @param app_data - data to inserting + * @return vector of pointer on founded records + */ + std::vector<ApplicationDataPtr> GetAppDataByDevMac( + const std::string& dev_mac) const OVERRIDE; + + /** + * @return pointer to LastState functionality + */ + resumption::LastState& last_state() const { + return last_state_; + } + + /** + * @brief delete record with oldest timestamp + * @return true in success cases and false othrewise + */ + bool DeleteOldestAppData(); + + /** + * @return pointer to AppLaunch data block in Json file + */ + Json::Value& GetSavedApplicationDataList() const; + + /** + * @return pointer to AppLaunch records block in Json file + */ + Json::Value& GetApplicationData() const; + + /** + * @brief lock to protected common data + */ + mutable sync_primitives::Lock app_launch_json_lock_; + + /** + * @brief ponter to Last State object + */ + resumption::LastState& last_state_; + + DISALLOW_COPY_AND_ASSIGN(AppLaunchDataJson); +}; + +} // namespace app_launch + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_DATA_JSON_H_ diff --git a/src/components/application_manager/include/application_manager/app_launch/app_launch_sql_queries.h b/src/components/application_manager/include/application_manager/app_launch/app_launch_sql_queries.h new file mode 100644 index 0000000000..4539b49002 --- /dev/null +++ b/src/components/application_manager/include/application_manager/app_launch/app_launch_sql_queries.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_SQL_QUERIES_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_SQL_QUERIES_H_ + +#include <string> + +namespace app_launch { + +extern const std::string kCreateSchema; +extern const std::string kDropSchema; +extern const std::string kFindApplicationData; +extern const std::string kDeleteOldestAppData; +extern const std::string kGetNumberOfApplicationData; +extern const std::string kGetApplicationDataByDevID; +extern const std::string kAddApplicationData; +extern const std::string kRefreshApplicationDataSessionTime; + +} // namespace app_launch + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_SQL_QUERIES_H_ diff --git a/src/components/application_manager/include/application_manager/app_launch/apps_launcher.h b/src/components/application_manager/include/application_manager/app_launch/apps_launcher.h new file mode 100644 index 0000000000..751e04bada --- /dev/null +++ b/src/components/application_manager/include/application_manager/app_launch/apps_launcher.h @@ -0,0 +1,86 @@ +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APPS_LAUNCHER_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APPS_LAUNCHER_H_ +#include "application_manager/app_launch/app_launch_data.h" +#include "connection_handler/connection_handler.h" +#include "utils/timer.h" + +namespace app_launch { +class AppLaunchCtrlImpl; +/** + * @brief The AppLauncher struct will manage Launching app and relaunching app + * in case application wasn't Registered. + * When application registered instance of this structure should be deleted to + * stop relaunch timer + */ +class AppsLauncher { + public: + AppsLauncher(connection_handler::ConnectionHandler& connection_handler, + const uint16_t max_number_of_ios_device, + const uint16_t app_launch_max_retry_attempt, + const uint16_t app_launch_retry_wait_time); + + /** + * @brief StartLaunching start launching process of applicaiton + * @param app_data applicaiton to launch + */ + void StartLaunching(ApplicationDataPtr app_data); + + /** + * @brief OnLaunched callback for application registration + * @param app_data registered application + */ + void OnLaunched(ApplicationDataPtr app_data); + + /** + * @brief OnRetryAttemptsExhausted callback for retry attempt exhausting + * @param app_data applicaiton that was exhausted launch attempts + */ + void OnRetryAttemptsExhausted(ApplicationDataPtr app_data); + + struct Launcher { + public: + Launcher(AppsLauncher& parent, + connection_handler::ConnectionHandler& connection_handler, + const uint16_t app_launch_max_retry_attempt, + const uint16_t app_launch_retry_wait_time); + + /** + * @brief PosponedLaunch launch application after cpecial timeout + * Will manage launch retrying in case of application wasn't registered + * @param app_data applicaiton to launch + */ + void PosponedLaunch(const ApplicationDataPtr& app_data); + + /** + * @brief Stops launching timers and remove information about launching + * application + */ + void Clear(); + + /** + * @brief LaunchNow send Launch to device request now + */ + void LaunchNow(); + ApplicationDataPtr app_data_; + size_t retry_index_; + timer::Timer retry_timer_; + const uint16_t app_launch_max_retry_attempt_; + const uint16_t app_launch_retry_wait_time_; + connection_handler::ConnectionHandler& connection_handler_; + AppsLauncher& parent_; + }; + typedef utils::SharedPtr<Launcher> LauncherPtr; + typedef std::vector<LauncherPtr> AppLaunchers; + + private: + sync_primitives::Lock launchers_lock_; + AppLaunchers free_launchers_; + AppLaunchers works_launchers_; + friend class Launcher; + void StopLaunching(ApplicationDataPtr app_data); + DISALLOW_COPY_AND_ASSIGN(AppsLauncher); +}; + +} // namespace app_launch + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APPS_LAUNCHER_H_ diff --git a/src/components/application_manager/include/application_manager/app_launch/device_apps_launcher.h b/src/components/application_manager/include/application_manager/app_launch/device_apps_launcher.h new file mode 100644 index 0000000000..f1f29471e6 --- /dev/null +++ b/src/components/application_manager/include/application_manager/app_launch/device_apps_launcher.h @@ -0,0 +1,46 @@ +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_DEVICE_APPS_LAUNCHER_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_DEVICE_APPS_LAUNCHER_H_ +#include <stdint.h> +#include <vector> +#include <string> +#include <memory> +#include "application_manager/app_launch/app_launch_data.h" +#include "application_manager/application_manager.h" +#include "application_manager/app_launch_settings.h" + +namespace app_launch { +class AppLaunchCtrlImpl; +class DeviceAppsLauncherImpl; +class AppsLauncher; +class AppLaunchSettings; +/** + * @brief The MultipleAppsLauncher struct + * should manage launching applications and gaps between launching application + * on one device + * When all apps launched it will notify AppLaunchCtrlImpl that all apps + * launched + */ +class DeviceAppsLauncher { + public: + DeviceAppsLauncher(application_manager::ApplicationManager& app_mngr, + app_launch::AppsLauncher& apps_launcher, + const AppLaunchSettings& settings); + + bool LaunchAppsOnDevice( + const std::string& device_mac, + const std::vector<ApplicationDataPtr>& applications_to_launch); + bool StopLaunchingAppsOnDevice(const std::string& device_mac); + + const AppLaunchSettings& settings() const; + + private: + application_manager::ApplicationManager& app_mngr_; + const AppLaunchSettings& settings_; + std::auto_ptr<DeviceAppsLauncherImpl> impl_; + friend class DeviceAppsLauncherImpl; + DISALLOW_COPY_AND_ASSIGN(DeviceAppsLauncher); +}; + +} // namespace app_launch + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_DEVICE_APPS_LAUNCHER_H_ diff --git a/src/components/application_manager/include/application_manager/application.h b/src/components/application_manager/include/application_manager/application.h index 612db6be03..c1b68c2eff 100644 --- a/src/components/application_manager/include/application_manager/application.h +++ b/src/components/application_manager/include/application_manager/application.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -109,6 +109,8 @@ class InitialApplicationData { virtual const smart_objects::SmartObject* app_types() const = 0; virtual const smart_objects::SmartObject* vr_synonyms() const = 0; virtual const std::string& mac_address() const = 0; + virtual const std::string& bundle_id() const = 0; + virtual void set_bundle_id(const std::string& bundle_id) = 0; virtual std::string policy_app_id() const = 0; virtual const smart_objects::SmartObject* tts_name() const = 0; virtual const smart_objects::SmartObject* ngn_media_screen_name() const = 0; diff --git a/src/components/application_manager/include/application_manager/application_impl.h b/src/components/application_manager/include/application_manager/application_impl.h index 75496b2761..972cf4b10f 100644 --- a/src/components/application_manager/include/application_manager/application_impl.h +++ b/src/components/application_manager/include/application_manager/application_impl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -139,6 +139,8 @@ class ApplicationImpl : public virtual InitialApplicationDataImpl, const std::string& app_icon_path() const; connection_handler::DeviceHandle device() const; const std::string& mac_address() const OVERRIDE; + const std::string& bundle_id() const OVERRIDE; + void set_bundle_id(const std::string& bundle_id) OVERRIDE; void set_tts_properties_in_none(bool active); bool tts_properties_in_none(); void set_tts_properties_in_full(bool active); @@ -357,7 +359,7 @@ class ApplicationImpl : public virtual InitialApplicationDataImpl, std::string app_icon_path_; connection_handler::DeviceHandle device_; const std::string mac_address_; - + std::string bundle_id_; AppFilesMap app_files_; std::set<mobile_apis::ButtonName::eType> subscribed_buttons_; VehicleInfoSubscriptions subscribed_vehicle_info_; diff --git a/src/components/application_manager/include/application_manager/application_manager.h b/src/components/application_manager/include/application_manager/application_manager.h index 97c38cd134..214f101b40 100644 --- a/src/components/application_manager/include/application_manager/application_manager.h +++ b/src/components/application_manager/include/application_manager/application_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,6 +52,9 @@ namespace resumption { class LastState; } +namespace app_launch { +class AppLaunchCtrl; +} // namespace app_launch namespace media_manager { class MediaManager; } @@ -490,6 +493,8 @@ class ApplicationManager { uint32_t connection_key, const std::string& policy_app_id) const = 0; virtual resumption::ResumeCtrl& resume_controller() = 0; + + virtual app_launch::AppLaunchCtrl& app_launch_ctrl() = 0; /* * @brief Converts connection string transport type representation * to HMI Common_TransportType diff --git a/src/components/application_manager/include/application_manager/application_manager_impl.h b/src/components/application_manager/include/application_manager/application_manager_impl.h index dda192f8b0..2775c6ad5d 100644 --- a/src/components/application_manager/include/application_manager/application_manager_impl.h +++ b/src/components/application_manager/include/application_manager/application_manager_impl.h @@ -30,8 +30,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_H_ -#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_H_ +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APPLICATION_MANAGER_IMPL_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APPLICATION_MANAGER_IMPL_H_ #include <stdint.h> #include <vector> @@ -39,6 +39,7 @@ #include <set> #include <deque> #include <algorithm> +#include <memory> #include "application_manager/hmi_command_factory.h" #include "application_manager/application_manager.h" @@ -49,6 +50,7 @@ #include "application_manager/resumption/resume_ctrl.h" #include "application_manager/vehicle_info_data.h" #include "application_manager/state_controller_impl.h" +#include "application_manager/app_launch/app_launch_data.h" #include "application_manager/application_manager_settings.h" #include "application_manager/event_engine/event_dispatcher_impl.h" @@ -317,8 +319,8 @@ class ApplicationManagerImpl void OnApplicationRegistered(ApplicationSharedPtr app) OVERRIDE; - HMICapabilities& hmi_capabilities(); - const HMICapabilities& hmi_capabilities() const; + HMICapabilities& hmi_capabilities() OVERRIDE; + const HMICapabilities& hmi_capabilities() const OVERRIDE; /** * @brief ProcessQueryApp executes logic related to QUERY_APP system request. @@ -839,7 +841,7 @@ class ApplicationManagerImpl * @return Resume Controller */ resumption::ResumeCtrl& resume_controller() OVERRIDE { - return resume_ctrl_; + return *resume_ctrl_.get(); } /** @@ -1102,6 +1104,8 @@ class ApplicationManagerImpl const ApplicationManagerSettings& get_settings() const OVERRIDE; virtual event_engine::EventDispatcher& event_dispatcher() OVERRIDE; + app_launch::AppLaunchCtrl& app_launch_ctrl() OVERRIDE; + private: /** * @brief PullLanguagesInfo allows to pull information about languages. @@ -1409,7 +1413,7 @@ class ApplicationManagerImpl // Thread that pumps messages audio pass thru to mobile. impl::AudioPassThruQueue audio_pass_thru_messages_; - HMICapabilities hmi_capabilities_; + std::auto_ptr<HMICapabilities> hmi_capabilities_; // The reason of HU shutdown mobile_api::AppInterfaceUnregisteredReason::eType unregister_reason_; @@ -1418,7 +1422,7 @@ class ApplicationManagerImpl * about persistent application data on disk, and save session ID for resuming * application in case INGITION_OFF or MASTER_RESSET */ - resumption::ResumeCtrl resume_ctrl_; + std::auto_ptr<resumption::ResumeCtrl> resume_ctrl_; NaviServiceStatusMap navi_service_status_; std::deque<uint32_t> navi_app_to_stop_; @@ -1430,6 +1434,8 @@ class ApplicationManagerImpl sync_primitives::Lock timer_pool_lock_; sync_primitives::Lock stopping_application_mng_lock_; StateControllerImpl state_ctrl_; + std::auto_ptr<app_launch::AppLaunchData> app_launch_dto_; + std::auto_ptr<app_launch::AppLaunchCtrl> app_launch_ctrl_; #ifdef TELEMETRY_MONITOR AMTelemetryObserver* metric_observer_; @@ -1460,4 +1466,4 @@ inline bool ApplicationManagerImpl::all_apps_allowed() const { } // namespace application_manager -#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_H_ +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APPLICATION_MANAGER_IMPL_H_ diff --git a/src/components/application_manager/include/application_manager/hmi_capabilities.h b/src/components/application_manager/include/application_manager/hmi_capabilities_impl.h index f94c8125c8..6724f4fdd5 100644 --- a/src/components/application_manager/include/application_manager/hmi_capabilities.h +++ b/src/components/application_manager/include/application_manager/hmi_capabilities_impl.h @@ -30,9 +30,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_HMI_CAPABILITIES_H_ -#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_HMI_CAPABILITIES_H_ +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_HMI_CAPABILITIES_IMPL_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_HMI_CAPABILITIES_IMPL_H_ +#include "application_manager/hmi_capabilities.h" #include "interfaces/HMI_API.h" #include "interfaces/MOBILE_API.h" #include "json/json.h" @@ -42,38 +43,39 @@ namespace NsSmartDeviceLink { namespace NsSmartObjects { class SmartObject; -} -} +} // namespace NsSmartObjects +} // namespace NsSmartDeviceLink + namespace resumption { class LastState; -} +} // namespace resumption namespace smart_objects = NsSmartDeviceLink::NsSmartObjects; namespace application_manager { class ApplicationManager; -class HMICapabilities { +class HMICapabilitiesImpl : public HMICapabilities { public: /* * @ Class constructor * * @param app_mngr Application manager pointer */ - explicit HMICapabilities(ApplicationManager& app_mngr); + explicit HMICapabilitiesImpl(ApplicationManager& app_mngr); /* * @brief Class destructor * */ - virtual ~HMICapabilities(); + virtual ~HMICapabilitiesImpl(); /** * @brief Checks if all HMI capabilities received * * @return TRUE if all information received, otherwise FALSE */ - bool is_hmi_capabilities_initialized() const; + bool is_hmi_capabilities_initialized() const OVERRIDE; /* * @brief Checks is image type(Static/Dynamic) requested by @@ -81,27 +83,42 @@ class HMICapabilities { * @param image_type recieved type of image from Enum. * @return Bool true if supported */ - bool VerifyImageType(int32_t image_type) const; + bool VerifyImageType(const int32_t image_type) const OVERRIDE; /** * @brief Checks if all HMI capabilities received * * @return TRUE if all information received, otherwise FALSE */ - inline bool is_vr_cooperating() const; - void set_is_vr_cooperating(bool value); + bool is_vr_cooperating() const OVERRIDE; + void set_is_vr_cooperating(const bool value) OVERRIDE; + + bool is_tts_cooperating() const OVERRIDE; + void set_is_tts_cooperating(const bool value) OVERRIDE; - inline bool is_tts_cooperating() const; - void set_is_tts_cooperating(bool value); + bool is_ui_cooperating() const OVERRIDE; + void set_is_ui_cooperating(const bool value) OVERRIDE; - inline bool is_ui_cooperating() const; - void set_is_ui_cooperating(bool value); + bool is_navi_cooperating() const OVERRIDE; + void set_is_navi_cooperating(const bool value) OVERRIDE; - inline bool is_navi_cooperating() const; - void set_is_navi_cooperating(bool value); + bool is_ivi_cooperating() const OVERRIDE; + void set_is_ivi_cooperating(const bool value) OVERRIDE; - inline bool is_ivi_cooperating() const; - void set_is_ivi_cooperating(bool value); + /* + * @brief Interface used to store information about software version of the + *target + * + * @param ccpu_version Received system/hmi software version + */ + void set_ccpu_version(const std::string& ccpu_version) OVERRIDE; + + /* + * @brief Returns software version of the target + * + * @return TRUE if it supported, otherwise FALSE + */ + const std::string& ccpu_version() const OVERRIDE; /* * @brief Retrieves if mixing audio is supported by HMI @@ -109,35 +126,36 @@ class HMICapabilities { * * @return Current state of the mixing audio flag */ - inline bool attenuated_supported() const; + bool attenuated_supported() const OVERRIDE; /* * @brief Sets state for mixing audio * * @param state New state to be set */ - void set_attenuated_supported(bool state); + void set_attenuated_supported(const bool state) OVERRIDE; /* * @brief Retrieves currently active UI language * * @return Currently active UI language */ - const hmi_apis::Common_Language::eType active_ui_language() const; + const hmi_apis::Common_Language::eType active_ui_language() const OVERRIDE; /* * @brief Sets currently active UI language * * @param language Currently active UI language */ - void set_active_ui_language(const hmi_apis::Common_Language::eType& language); + void set_active_ui_language( + const hmi_apis::Common_Language::eType language) OVERRIDE; /* * @brief Retrieves UI supported languages * * @return Currently supported UI languages */ - inline const smart_objects::SmartObject* ui_supported_languages() const; + const smart_objects::SmartObject* ui_supported_languages() const OVERRIDE; /* * @brief Sets supported UI languages @@ -145,28 +163,29 @@ class HMICapabilities { * @param supported_languages Supported UI languages */ void set_ui_supported_languages( - const smart_objects::SmartObject& supported_languages); + const smart_objects::SmartObject& supported_languages) OVERRIDE; /* * @brief Retrieves currently active VR language * * @return Currently active VR language */ - const hmi_apis::Common_Language::eType active_vr_language() const; + const hmi_apis::Common_Language::eType active_vr_language() const OVERRIDE; /* * @brief Sets currently active VR language * * @param language Currently active VR language */ - void set_active_vr_language(const hmi_apis::Common_Language::eType& language); + void set_active_vr_language( + const hmi_apis::Common_Language::eType language) OVERRIDE; /* * @brief Retrieves VR supported languages * * @return Currently supported VR languages */ - inline const smart_objects::SmartObject* vr_supported_languages() const; + const smart_objects::SmartObject* vr_supported_languages() const OVERRIDE; /* * @brief Sets supported VR languages @@ -174,14 +193,14 @@ class HMICapabilities { * @param supported_languages Supported VR languages */ void set_vr_supported_languages( - const smart_objects::SmartObject& supported_languages); + const smart_objects::SmartObject& supported_languages) OVERRIDE; /* * @brief Retrieves currently active TTS language * * @return Currently active TTS language */ - const hmi_apis::Common_Language::eType active_tts_language() const; + const hmi_apis::Common_Language::eType active_tts_language() const OVERRIDE; /* * @brief Sets currently active TTS language @@ -189,14 +208,14 @@ class HMICapabilities { * @param language Currently active TTS language */ void set_active_tts_language( - const hmi_apis::Common_Language::eType& language); + const hmi_apis::Common_Language::eType language) OVERRIDE; /* * @brief Retrieves TTS supported languages * * @return Currently supported TTS languages */ - inline const smart_objects::SmartObject* tts_supported_languages() const; + const smart_objects::SmartObject* tts_supported_languages() const OVERRIDE; /* * @brief Sets supported TTS languages @@ -204,14 +223,14 @@ class HMICapabilities { * @param supported_languages Supported TTS languages */ void set_tts_supported_languages( - const smart_objects::SmartObject& supported_languages); + const smart_objects::SmartObject& supported_languages) OVERRIDE; /* * @brief Retrieves information about the display capabilities * * @return Currently supported display capabilities */ - inline const smart_objects::SmartObject* display_capabilities() const; + const smart_objects::SmartObject* display_capabilities() const OVERRIDE; /* * @brief Sets supported display capabilities @@ -219,14 +238,14 @@ class HMICapabilities { * @param display_capabilities supported display capabilities */ void set_display_capabilities( - const smart_objects::SmartObject& display_capabilities); + const smart_objects::SmartObject& display_capabilities) OVERRIDE; /* * @brief Retrieves information about the HMI zone capabilities * * @return Currently supported HMI zone capabilities */ - inline const smart_objects::SmartObject* hmi_zone_capabilities() const; + const smart_objects::SmartObject* hmi_zone_capabilities() const OVERRIDE; /* * @brief Sets supported HMI zone capabilities @@ -234,14 +253,14 @@ class HMICapabilities { * @param hmi_zone_capabilities supported HMI zone capabilities */ void set_hmi_zone_capabilities( - const smart_objects::SmartObject& hmi_zone_capabilities); + const smart_objects::SmartObject& hmi_zone_capabilities) OVERRIDE; /* * @brief Retrieves information about the SoftButton's capabilities * * @return Currently supported SoftButton's capabilities */ - inline const smart_objects::SmartObject* soft_button_capabilities() const; + const smart_objects::SmartObject* soft_button_capabilities() const OVERRIDE; /* * @brief Sets supported SoftButton's capabilities @@ -249,14 +268,14 @@ class HMICapabilities { * @param soft_button_capabilities supported SoftButton's capabilities */ void set_soft_button_capabilities( - const smart_objects::SmartObject& soft_button_capabilities); + const smart_objects::SmartObject& soft_button_capabilities) OVERRIDE; /* * @brief Retrieves information about the Button's capabilities * * @return Currently supported Button's capabilities */ - inline const smart_objects::SmartObject* button_capabilities() const; + const smart_objects::SmartObject* button_capabilities() const OVERRIDE; /* * @brief Sets supported Button's capabilities @@ -264,7 +283,7 @@ class HMICapabilities { * @param soft_button_capabilities supported Button's capabilities */ void set_button_capabilities( - const smart_objects::SmartObject& button_capabilities); + const smart_objects::SmartObject& button_capabilities) OVERRIDE; /* * @brief Sets supported speech capabilities @@ -272,28 +291,29 @@ class HMICapabilities { * @param speech_capabilities supported speech capabilities */ void set_speech_capabilities( - const smart_objects::SmartObject& speech_capabilities); + const smart_objects::SmartObject& speech_capabilities) OVERRIDE; /* * @brief Retrieves information about the speech capabilities * * @return Currently supported speech capabilities */ - inline const smart_objects::SmartObject* speech_capabilities() const; + const smart_objects::SmartObject* speech_capabilities() const OVERRIDE; /* * @brief Sets supported VR capabilities * * @param vr_capabilities supported VR capabilities */ - void set_vr_capabilities(const smart_objects::SmartObject& vr_capabilities); + void set_vr_capabilities( + const smart_objects::SmartObject& vr_capabilities) OVERRIDE; /* * @brief Retrieves information about the VR capabilities * * @return Currently supported VR capabilities */ - inline const smart_objects::SmartObject* vr_capabilities() const; + const smart_objects::SmartObject* vr_capabilities() const OVERRIDE; /* * @brief Sets supported audio_pass_thru capabilities @@ -301,36 +321,37 @@ class HMICapabilities { * @param vr_capabilities supported audio_pass_thru capabilities */ void set_audio_pass_thru_capabilities( - const smart_objects::SmartObject& audio_pass_thru_capabilities); + const smart_objects::SmartObject& audio_pass_thru_capabilities) OVERRIDE; /* - * @brief Sets supported pcm_stream capabilities + * @brief Retrieves information about the audio_pass_thru capabilities * - * @param supported pcm stream capabilities + * @return Currently supported audio_pass_thru capabilities */ - void set_pcm_stream_capabilities( - const smart_objects::SmartObject& pcm_stream_capabilities); + const smart_objects::SmartObject* audio_pass_thru_capabilities() + const OVERRIDE; /* - * @brief Retrieves information about the audio_pass_thru capabilities + * @brief Sets supported pcm_stream capabilities * - * @return Currently supported audio_pass_thru capabilities + * @param supported pcm_stream capabilities */ - inline const smart_objects::SmartObject* audio_pass_thru_capabilities() const; + void set_pcm_stream_capabilities( + const smart_objects::SmartObject& pcm_stream_capabilities) OVERRIDE; /* * @brief Retrieves information about the pcm_stream capabilities * * @return Currently supported pcm_streaming capabilities */ - inline const smart_objects::SmartObject* pcm_stream_capabilities() const; + const smart_objects::SmartObject* pcm_stream_capabilities() const OVERRIDE; /* * @brief Retrieves information about the preset bank capabilities * * @return Currently supported preset bank capabilities */ - inline const smart_objects::SmartObject* preset_bank_capabilities() const; + const smart_objects::SmartObject* preset_bank_capabilities() const OVERRIDE; /* * @brief Sets supported preset bank capabilities @@ -338,28 +359,29 @@ class HMICapabilities { * @param soft_button_capabilities supported preset bank capabilities */ void set_preset_bank_capabilities( - const smart_objects::SmartObject& preset_bank_capabilities); + const smart_objects::SmartObject& preset_bank_capabilities) OVERRIDE; /* * @brief Sets vehicle information(make, model, modelYear) * * @param vehicle_type Cuurent vehicle information */ - void set_vehicle_type(const smart_objects::SmartObject& vehicle_type); + void set_vehicle_type( + const smart_objects::SmartObject& vehicle_type) OVERRIDE; /* * @brief Retrieves vehicle information(make, model, modelYear) * * @param vehicle_type Cuurent vehicle information */ - inline const smart_objects::SmartObject* vehicle_type() const; + const smart_objects::SmartObject* vehicle_type() const OVERRIDE; /* * @brief Retrieves information about the prerecorded speech * * @return Currently supported prerecorded speech */ - inline const smart_objects::SmartObject* prerecorded_speech() const; + const smart_objects::SmartObject* prerecorded_speech() const OVERRIDE; /* * @brief Sets supported prerecorded speech @@ -367,7 +389,7 @@ class HMICapabilities { * @param prerecorded_speech supported prerecorded speech */ void set_prerecorded_speech( - const smart_objects::SmartObject& prerecorded_speech); + const smart_objects::SmartObject& prerecorded_speech) OVERRIDE; /* * @brief Interface used to store information if navigation @@ -375,14 +397,14 @@ class HMICapabilities { * * @param supported Indicates if navigation supported by the system */ - void set_navigation_supported(bool supported); + void set_navigation_supported(const bool supported) OVERRIDE; /* * @brief Retrieves information if navi supported by the system * * @return TRUE if it supported, otherwise FALSE */ - inline bool navigation_supported() const; + bool navigation_supported() const OVERRIDE; /* * @brief Interface used to store information if phone call @@ -390,40 +412,23 @@ class HMICapabilities { * * @param supported Indicates if navigation supported by the sustem */ - void set_phone_call_supported(bool supported); + void set_phone_call_supported(const bool supported) OVERRIDE; /* * @brief Retrieves information if phone call supported by the system * * @return TRUE if it supported, otherwise FALSE */ - inline bool phone_call_supported() const; + bool phone_call_supported() const OVERRIDE; - /* - * @brief Interface used to store information about software version of the - *target - * - * @param ccpu_version Received system/hmi software version - */ - void set_ccpu_version(const std::string& ccpu_version); + void Init(resumption::LastState* last_state) OVERRIDE; /* - * @brief Returns software version of the target - * - * @return TRUE if it supported, otherwise FALSE - */ - inline const std::string& ccpu_version() const; - - void Init(resumption::LastState* last_state); - - /** * @brief return component which follows for correctness of * languages * @return HMI language handler */ - HMILanguageHandler& get_hmi_language_handler() { - return hmi_language_handler_; - } + HMILanguageHandler& get_hmi_language_handler() OVERRIDE; protected: /* @@ -445,7 +450,7 @@ class HMICapabilities { * member does not exist. */ bool check_existing_json_member(const Json::Value& json_member, - const char* name_of_member); + const char* name_of_member) const OVERRIDE; /* * @brief function converts json object "languages" to smart object @@ -454,8 +459,9 @@ class HMICapabilities { * @param languages - the converted object * */ - void convert_json_languages_to_obj(Json::Value& json_languages, - smart_objects::SmartObject& languages); + void convert_json_languages_to_obj( + const Json::Value& json_languages, + smart_objects::SmartObject& languages) const OVERRIDE; private: bool is_vr_cooperating_; @@ -489,117 +495,16 @@ class HMICapabilities { smart_objects::SmartObject* audio_pass_thru_capabilities_; smart_objects::SmartObject* pcm_stream_capabilities_; smart_objects::SmartObject* prerecorded_speech_; - std::string ccpu_version_; bool is_navigation_supported_; bool is_phone_call_supported_; + std::string ccpu_version_; ApplicationManager& app_mngr_; HMILanguageHandler hmi_language_handler_; - DISALLOW_COPY_AND_ASSIGN(HMICapabilities); + DISALLOW_COPY_AND_ASSIGN(HMICapabilitiesImpl); }; -bool HMICapabilities::is_ui_cooperating() const { - return is_ui_cooperating_; -} - -bool HMICapabilities::is_vr_cooperating() const { - return is_vr_cooperating_; -} - -bool HMICapabilities::is_tts_cooperating() const { - return is_tts_cooperating_; -} - -bool HMICapabilities::is_navi_cooperating() const { - return is_navi_cooperating_; -} - -bool HMICapabilities::is_ivi_cooperating() const { - return is_ivi_cooperating_; -} - -const smart_objects::SmartObject* HMICapabilities::ui_supported_languages() - const { - return ui_supported_languages_; -} - -const smart_objects::SmartObject* HMICapabilities::vr_supported_languages() - const { - return vr_supported_languages_; -} - -const smart_objects::SmartObject* HMICapabilities::tts_supported_languages() - const { - return tts_supported_languages_; -} - -const smart_objects::SmartObject* HMICapabilities::display_capabilities() - const { - return display_capabilities_; -} - -const smart_objects::SmartObject* HMICapabilities::hmi_zone_capabilities() - const { - return hmi_zone_capabilities_; -} - -const smart_objects::SmartObject* HMICapabilities::soft_button_capabilities() - const { - return soft_buttons_capabilities_; -} - -const smart_objects::SmartObject* HMICapabilities::button_capabilities() const { - return button_capabilities_; -} - -const smart_objects::SmartObject* HMICapabilities::speech_capabilities() const { - return speech_capabilities_; -} - -const smart_objects::SmartObject* HMICapabilities::vr_capabilities() const { - return vr_capabilities_; -} - -const smart_objects::SmartObject* -HMICapabilities::audio_pass_thru_capabilities() const { - return audio_pass_thru_capabilities_; -} - -const smart_objects::SmartObject* HMICapabilities::pcm_stream_capabilities() - const { - return pcm_stream_capabilities_; -} - -const smart_objects::SmartObject* HMICapabilities::preset_bank_capabilities() - const { - return preset_bank_capabilities_; -} - -bool HMICapabilities::attenuated_supported() const { - return attenuated_supported_; -} - -const smart_objects::SmartObject* HMICapabilities::vehicle_type() const { - return vehicle_type_; -} - -const smart_objects::SmartObject* HMICapabilities::prerecorded_speech() const { - return prerecorded_speech_; -} - -const std::string& HMICapabilities::ccpu_version() const { - return ccpu_version_; -} - -bool HMICapabilities::navigation_supported() const { - return is_navigation_supported_; -} - -bool HMICapabilities::phone_call_supported() const { - return is_phone_call_supported_; -} - } // namespace application_manager -#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_HMI_CAPABILITIES_H_ +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_HMI_CAPABILITIES_IMPL_H_ diff --git a/src/components/application_manager/include/application_manager/resumption/resume_ctrl.h b/src/components/application_manager/include/application_manager/resumption/resume_ctrl.h index 853f91ff23..26b1739a38 100644 --- a/src/components/application_manager/include/application_manager/resumption/resume_ctrl.h +++ b/src/components/application_manager/include/application_manager/resumption/resume_ctrl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,28 +30,20 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_RESUME_CTRL_H -#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_RESUME_CTRL_H +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUME_CTRL_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUME_CTRL_H_ #include <stdint.h> -#include <vector> -#include <map> -#include <set> -#include <list> - -#include "interfaces/HMI_API.h" -#include "interfaces/HMI_API_schema.h" -#include "interfaces/MOBILE_API_schema.h" -#include "application_manager/event_engine/event_observer.h" -#include "smart_objects/smart_object.h" -#include "application_manager/application.h" +#include "utils/shared_ptr.h" #include "application_manager/resumption/resumption_data.h" -#include "utils/timer.h" namespace application_manager { class ApplicationManager; class Application; +typedef utils::SharedPtr<Application> ApplicationSharedPtr; +typedef utils::SharedPtr<const Application> ApplicationConstSharedPtr; } +namespace app_mngr = application_manager; namespace resumption { @@ -61,50 +53,40 @@ class LastState; * @brief Contains logic for storage/restore data of applications. */ -class ResumeCtrl : public application_manager::event_engine::EventObserver { +class ResumeCtrl { public: /** - * @brief allows to create ResumeCtrl object - */ - ResumeCtrl(application_manager::ApplicationManager& application_manager); - - /** * @brief allows to destroy ResumeCtrl object */ - ~ResumeCtrl(); - - /** - * @brief Event, that raised if application get resumption response from HMI - * @param event : event object, that contains smart_object with HMI message - */ - virtual void on_event(const application_manager::event_engine::Event& event); + virtual ~ResumeCtrl() {} /** * @brief Save all applications info to the file system */ - void SaveAllApplications(); + virtual void SaveAllApplications() = 0; /** * @brief Save application persistent info for future resuming * @param application is application witch need to be saved */ - void SaveApplication(application_manager::ApplicationSharedPtr application); + virtual void SaveApplication( + application_manager::ApplicationSharedPtr application) = 0; /** * @brief Set application HMI Level and ausio_state as saved * @param application is application witch HMI Level is need to restore * @return true if success, otherwise return false */ - bool RestoreAppHMIState( - application_manager::ApplicationSharedPtr application); + virtual bool RestoreAppHMIState( + application_manager::ApplicationSharedPtr application) = 0; /** * @brief Set application HMI Level as stored in policy * @param application is application witch HMI Level is need to setup * @return true if success, otherwise return false */ - bool SetupDefaultHMILevel( - application_manager::ApplicationSharedPtr application); + virtual bool SetupDefaultHMILevel( + application_manager::ApplicationSharedPtr application) = 0; /** * @brief Setup HmiLevel for application @@ -115,55 +97,34 @@ class ResumeCtrl : public application_manager::event_engine::EventObserver { * @param check_policy indicate if policy data consent must be verified * @return true if success, otherwise return false */ - bool SetAppHMIState(application_manager::ApplicationSharedPtr application, - const mobile_apis::HMILevel::eType hmi_level, - bool check_policy = true); - - /** - * @brief Check if Resume controller have saved instance of application - * @param application is application witch need to be checked - * @return true if exist, false otherwise - */ - bool ApplicationIsSaved( - application_manager::ApplicationConstSharedPtr application); + virtual bool SetAppHMIState( + application_manager::ApplicationSharedPtr application, + const mobile_apis::HMILevel::eType hmi_level, + bool check_policy = true) = 0; /** * @brief Remove application from list of saved applications * @param application is application which need to be removed * @return return true, if success, otherwise return false */ - bool RemoveApplicationFromSaved( - application_manager::ApplicationConstSharedPtr application); - - /** - * @brief Increments ignition counter for all registered applications - * and remember ign_off time stamp - */ - void OnSuspend(); - + virtual bool RemoveApplicationFromSaved( + app_mngr::ApplicationConstSharedPtr application) = 0; /** - * @brief Increments ignition counter for all registered applications - * and remember ign_off time stamp + * @brief Processes resumption data after receiving signal "Suspend" */ - void OnAwake(); + virtual void OnSuspend() = 0; /** - * @brief Method starts timer "RsmCtrlPercist" when - * SDL receives onAwakeSDL notification + * @brief Processes resumption data after receiving signal "Awake" */ - void StartSavePersistentDataTimer(); + virtual void OnAwake() = 0; /** * @brief Method stops timer "RsmCtrlPercist" when SDL * receives OnExitAllApplication notification * with reason "SUSPEND" */ - void StopSavePersistentDataTimer(); - - /** - * @brief Method stops restore_hmi_level_timer_ "RsmCtrlRstore" in OnSuspend() - */ - void StopRestoreHmiLevelTimer(); + virtual void StopSavePersistentDataTimer() = 0; /** * @brief Start timer for resumption applications @@ -171,41 +132,39 @@ class ResumeCtrl : public application_manager::event_engine::EventObserver { * @param application that is need to be restored * @return true if it was saved, otherwise return false */ - bool StartResumption(application_manager::ApplicationSharedPtr application, - const std::string& hash); - + virtual bool StartResumption(app_mngr::ApplicationSharedPtr application, + const std::string& hash) = 0; /** * @brief Start timer for resumption applications * Does not restore D1-D5 data * @param application that is need to be restored * @return true if it was saved, otherwise return false */ - bool StartResumptionOnlyHMILevel( - application_manager::ApplicationSharedPtr application); + virtual bool StartResumptionOnlyHMILevel( + app_mngr::ApplicationSharedPtr application) = 0; /** * @brief Check if there are all files need for resumption * @param application that is need to be restored * @return true if it all files exist, otherwise return false */ - bool CheckPersistenceFilesForResumption( - application_manager::ApplicationSharedPtr application); + virtual bool CheckPersistenceFilesForResumption( + app_mngr::ApplicationSharedPtr application) = 0; /** * @brief Check application hash * @param application that is need to be restored * @return true if it was saved, otherwise return false */ - bool CheckApplicationHash( - application_manager::ApplicationSharedPtr application, - const std::string& hash); + virtual bool CheckApplicationHash(app_mngr::ApplicationSharedPtr application, + const std::string& hash) = 0; /** * @brief Checks if Resume controller have saved application with hmi app id * @param hmi_app_id - hmi application id * @return true if exist, false otherwise */ - bool IsHMIApplicationIdExist(uint32_t hmi_app_id); + virtual bool IsHMIApplicationIdExist(uint32_t hmi_app_id) = 0; /** * @brief Check if Resume controller have saved instance of application @@ -213,8 +172,8 @@ class ResumeCtrl : public application_manager::event_engine::EventObserver { * @param device_id - id of device where application is run * @return true if exist, false otherwise */ - bool IsApplicationSaved(const std::string& policy_app_id, - const std::string& device_id); + virtual bool IsApplicationSaved(const std::string& policy_app_id, + const std::string& device_id) = 0; /** * @brief Function is used for application resume. HMI app ID must be @@ -224,283 +183,75 @@ class ResumeCtrl : public application_manager::event_engine::EventObserver { * @param device_id - id of device where application is run * @return HMI app ID */ - uint32_t GetHMIApplicationID(const std::string& policy_app_id, - const std::string& device_id) const; - /** - * @brief SaveDataOnTimer : - * Timer callback for persisting ResumptionData each N seconds - * N gets from property - */ - void SaveDataOnTimer(); + virtual uint32_t GetHMIApplicationID(const std::string& policy_app_id, + const std::string& device_id) const = 0; /** * @brief Updates flag for saving application data */ - void ApplicationsDataUpdated() { - is_data_saved_ = false; - } + virtual void ApplicationsDataUpdated() = 0; /** * @brief Resume HMI Level and audio streaming state if needed * @param application - application to restore hmi level * and audio streaming state */ - void StartAppHmiStateResumption( - application_manager::ApplicationSharedPtr application); + virtual void StartAppHmiStateResumption( + application_manager::ApplicationSharedPtr application) = 0; /** * @brief Update launch_time_ to current */ - void ResetLaunchTime(); - - /** - * @brief Timer callback for restoring HMI Level - * - */ - void ApplicationResumptiOnTimer(); + virtual void ResetLaunchTime() = 0; /** * @brief Removes activated application from resumption list * * @param application application witch need to be removed from resumption */ - void OnAppActivated(application_manager::ApplicationSharedPtr application); + virtual void OnAppActivated(app_mngr::ApplicationSharedPtr application) = 0; /** * @brief Removes app from resumption list * * app_id Application to remove */ - void RemoveFromResumption(uint32_t app_id); + virtual void RemoveFromResumption(uint32_t app_id) = 0; /** * @brief Initialization data for Resume controller * @return true if initialization is success otherwise * returns false */ - bool Init(LastState& last_state); + virtual bool Init(LastState& last_state) = 0; /** * @brief Notify resume controller about new application * @param policy_app_id - mobile application id * @param device_id - id of device where application is run */ - void OnAppRegistrationStart(const std::string& policy_app_id, - const std::string& device_id); + virtual void OnAppRegistrationStart(const std::string& policy_app_id, + const std::string& device_id) = 0; /** * @brief Notify resume controller about delete new application */ - void OnAppRegistrationEnd(); - -#ifdef BUILD_TESTS - void set_resumption_storage(utils::SharedPtr<ResumptionData> mock_storage); -#endif // BUILD_TESTS - private: - /** - * @brief restores saved data of application - * @param application contains application for which restores data - * @return true if success, otherwise return false - */ - bool RestoreApplicationData( - application_manager::ApplicationSharedPtr application); - - /** - * @brief AddFiles allows to add files for the application - * which should be resumed - * @param application application which will be resumed - * @param saved_app application specific section from backup file - */ - void AddFiles(application_manager::ApplicationSharedPtr application, - const smart_objects::SmartObject& saved_app); - - /** - * @brief AddSubmenues allows to add sub menues for the application - * which should be resumed - * @param application application which will be resumed - * @param saved_app application specific section from backup file - */ - void AddSubmenues(application_manager::ApplicationSharedPtr application, - const smart_objects::SmartObject& saved_app); - - /** - * @brief AddCommands allows to add commands for the application - * which should be resumed - * @param application application which will be resumed - * @param saved_app application specific section from backup file - */ - void AddCommands(application_manager::ApplicationSharedPtr application, - const smart_objects::SmartObject& saved_app); - - /** - * @brief AddChoicesets allows to add choice sets for the application - * which should be resumed - * @param application application which will be resumed - * @param saved_app application specific section from backup file - */ - void AddChoicesets(application_manager::ApplicationSharedPtr application, - const smart_objects::SmartObject& saved_app); - - /** - * @brief SetGlobalProperties allows to restore global properties. - * @param application application which will be resumed - * @param saved_app application specific section from backup file - */ - void SetGlobalProperties( - application_manager::ApplicationSharedPtr application, - const smart_objects::SmartObject& saved_app); - - /** - * @brief AddSubscriptions allows to restore subscriptions - * @param application application which will be resumed - * @param saved_app application specific section from backup file - */ - void AddSubscriptions(application_manager::ApplicationSharedPtr application, - const smart_objects::SmartObject& saved_app); - - /** - * @brief AddWayPointsSubscription allows to restore subscription - * for WayPoints - * @param application application which will be resumed - * @param saved_app application specific section from backup file - */ - void AddWayPointsSubscription( - application_manager::ApplicationSharedPtr application, - const smart_objects::SmartObject& saved_app); - - bool CheckIgnCycleRestrictions(const smart_objects::SmartObject& saved_app); - - bool DisconnectedJustBeforeIgnOff( - const smart_objects::SmartObject& saved_app); - - bool CheckAppRestrictions( - application_manager::ApplicationConstSharedPtr application, - const smart_objects::SmartObject& saved_app); - - /** - * @brief CheckIcons allows to check application icons - * @param application application under resumtion application - * @param json_object - * @return true in case icons exists, false otherwise - */ - bool CheckIcons(application_manager::ApplicationSharedPtr application, - smart_objects::SmartObject& obj); - - /** - * @brief CheckDelayAfterIgnOn should check if SDL was started less - * then N secconds ago. N will be readed from profile. - * @return true if SDL started N secconds ago, otherwise return false - */ - bool CheckDelayAfterIgnOn(); - - typedef std::pair<uint32_t, uint32_t> ApplicationTimestamp; - - std::set<application_manager::ApplicationSharedPtr> retrieve_application(); + virtual void OnAppRegistrationEnd() = 0; /** - * @brief This struct need to map - * timestamp and application from correlationID + * @brief GetSavedHMILevels get saved apps hmi levels + * @return mapping of mobile application id and saved hmi_level */ - struct ResumingApp { - uint32_t old_session_key; // session key is the same as app_id - application_manager::ApplicationSharedPtr app; - }; - - struct TimeStampComparator { - bool operator()(const ApplicationTimestamp& lhs, - const ApplicationTimestamp& rhs) const { - return lhs.second < rhs.second; - } - }; + virtual int32_t GetSavedAppHmiLevel(const std::string& app_id, + const std::string& device_id) const = 0; - /** - * @brief geter for launch_time_ - * @return value of launch_time_ - */ - time_t launch_time() const; - - /** - * @brief Check device MAC address - * @param application that is need to be restored - * @param saved_device_mac Saved device MAC address - * @return TRUE on success, otherwise FALSE - */ - bool IsDeviceMacAddressEqual( - application_manager::ApplicationSharedPtr application, - const std::string& saved_device_mac); - - /** - * @brief Get the last ignition off time from LastState - * @return the last ignition off time from LastState - */ - time_t GetIgnOffTime(); + virtual time_t LaunchTime() const = 0; - /** - * @brief Setup IgnOff time to LastState - * @param ign_off_time - igition off time - */ - void SetLastIgnOffTime(time_t ign_off_time); - - /** - * @brief Process specified HMI request - * @param request Request to process - * @param use_events Process request events or not flag - * @return TRUE on success, otherwise FALSE - */ - bool ProcessHMIRequest(smart_objects::SmartObjectSPtr request = NULL, - bool use_events = false); - - /** - * @brief Process list of HMI requests using ProcessHMIRequest method - * @param requests List of requests to process - */ - void ProcessHMIRequests(const smart_objects::SmartObjectList& requests); - - void InsertToTimerQueue(uint32_t app_id, uint32_t time_stamp); - - void AddToResumptionTimerQueue(const uint32_t app_id); - - void LoadResumeData(); - - /** - * @brief Checks, if application data needs to be resumed - * @param application Application data from storage - * @return true, if data resumption must be skipped, otherwise - false - */ - bool IsAppDataResumptionExpired( - const smart_objects::SmartObject& application) const; - /** - * @brief Checks from resume data, if application has been disconnected - * unexpectedly - * @param app Application section from resume data - * @return true, if it has been unexpectedly disconnected, otherwise - false - */ - bool IsUnexpectedlyDisconnected(const smart_objects::SmartObject& app) const; - - /** - * @brief Checks, if application can be resumed - * @param application Application - * @return true, if no restrictions currently, otherwise - false - */ - bool IsResumeAllowed( - const application_manager::ApplicationSharedPtr application) const; - - /** - *@brief Mapping applications to time_stamps - * wait for timer to resume HMI Level - * - */ - mutable sync_primitives::Lock queue_lock_; - timer::Timer restore_hmi_level_timer_; - timer::Timer save_persistent_data_timer_; - typedef std::list<uint32_t> WaitingForTimerList; - WaitingForTimerList waiting_for_timer_; - bool is_resumption_active_; - bool is_data_saved_; - time_t launch_time_; - utils::SharedPtr<ResumptionData> resumption_storage_; - application_manager::ApplicationManager& application_manager_; +#ifdef BUILD_TESTS + virtual void set_resumption_storage( + utils::SharedPtr<ResumptionData> mock_storage) = 0; +#endif // BUILD_TESTS }; } // namespace resumption -#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_RESUME_CTRL_H +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUME_CTRL_H_ diff --git a/src/components/application_manager/include/application_manager/resumption/resume_ctrl_impl.h b/src/components/application_manager/include/application_manager/resumption/resume_ctrl_impl.h new file mode 100644 index 0000000000..b7512df28b --- /dev/null +++ b/src/components/application_manager/include/application_manager/resumption/resume_ctrl_impl.h @@ -0,0 +1,500 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUME_CTRL_IMPL_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUME_CTRL_IMPL_H_ + +#include <stdint.h> +#include <vector> +#include <map> +#include <set> +#include <list> + +#include "interfaces/HMI_API.h" +#include "interfaces/HMI_API_schema.h" +#include "interfaces/MOBILE_API_schema.h" +#include "application_manager/event_engine/event_observer.h" +#include "smart_objects/smart_object.h" +#include "application_manager/application.h" +#include "application_manager/resumption/resumption_data.h" +#include "application_manager/resumption/resume_ctrl.h" +#include "utils/timer.h" + +namespace resumption { + +class LastState; + +/** + * @brief Contains logic for storage/restore data of applications. + */ + +class ResumeCtrlImpl : public ResumeCtrl, + public app_mngr::event_engine::EventObserver { + public: + /** + * @brief allows to create ResumeCtrlImpl object + */ + ResumeCtrlImpl(application_manager::ApplicationManager& application_manager); + + /** + * @brief allows to destroy ResumeCtrlImpl object + */ + ~ResumeCtrlImpl(); + + /** + * @brief Event, that raised if application get resumption response from HMI + * @param event : event object, that contains smart_object with HMI message + */ + void on_event(const app_mngr::event_engine::Event& event) OVERRIDE; + + /** + * @brief Save all applications info to the file system + */ + void SaveAllApplications() OVERRIDE; + + /** + * @brief Save application persistent info for future resuming + * @param application is application witch need to be saved + */ + void SaveApplication(app_mngr::ApplicationSharedPtr application) OVERRIDE; + + /** + * @brief Set application HMI Level and ausio_state as saved + * @param application is application witch HMI Level is need to restore + * @return true if success, otherwise return false + */ + bool RestoreAppHMIState(app_mngr::ApplicationSharedPtr application) OVERRIDE; + + /** + * @brief Set application HMI Level as stored in policy + * @param application is application witch HMI Level is need to setup + * @return true if success, otherwise return false + */ + bool SetupDefaultHMILevel( + app_mngr::ApplicationSharedPtr application) OVERRIDE; + + /** + * @brief Setup HmiLevel for application + * Do routine of setting up hmi_level + * @param application is application witch HMI Level is need to setup + * @param hmi_level HMI Level is needed to setup + * @param hmi_level AudioStreamingState is needed to setup + * @param check_policy indicate if policy data consent must be verified + * @return true if success, otherwise return false + */ + bool SetAppHMIState(app_mngr::ApplicationSharedPtr application, + const mobile_apis::HMILevel::eType hmi_level, + bool check_policy = true) OVERRIDE; + + /** + * @brief Remove application from list of saved applications + * @param application is application which need to be removed + * @return return true, if success, otherwise return false + */ + bool RemoveApplicationFromSaved( + app_mngr::ApplicationConstSharedPtr application) OVERRIDE; + + /** + * @brief Processes resumption data after receiving signal "Suspend" + */ + void OnSuspend() OVERRIDE; + + /** + * @brief Processes resumption data after receiving signal "Awake" + */ + void OnAwake() OVERRIDE; + + /** + * @brief Method stops timer "RsmCtrlPercist" when SDL + * receives OnExitAllApplication notification + * with reason "SUSPEND" + */ + void StopSavePersistentDataTimer() OVERRIDE; + + /** + * @brief Method stops restore_hmi_level_timer_ "RsmCtrlRstore" in OnSuspend() + */ + void StopRestoreHmiLevelTimer(); + + /** + * @brief Start timer for resumption applications + * Restore D1-D5 data + * @param application that is need to be restored + * @return true if it was saved, otherwise return false + */ + bool StartResumption(app_mngr::ApplicationSharedPtr application, + const std::string& hash) OVERRIDE; + + /** + * @brief Start timer for resumption applications + * Does not restore D1-D5 data + * @param application that is need to be restored + * @return true if it was saved, otherwise return false + */ + bool StartResumptionOnlyHMILevel( + app_mngr::ApplicationSharedPtr application) OVERRIDE; + + /** + * @brief Check if there are all files need for resumption + * @param application that is need to be restored + * @return true if it all files exist, otherwise return false + */ + bool CheckPersistenceFilesForResumption( + app_mngr::ApplicationSharedPtr application) OVERRIDE; + + /** + * @brief Check application hash + * @param application that is need to be restored + * @return true if it was saved, otherwise return false + */ + bool CheckApplicationHash(app_mngr::ApplicationSharedPtr application, + const std::string& hash) OVERRIDE; + + /** + * @brief Checks if Resume controller have saved application with hmi app id + * @param hmi_app_id - hmi application id + * @return true if exist, false otherwise + */ + bool IsHMIApplicationIdExist(uint32_t hmi_app_id) OVERRIDE; + + /** + * @brief Check if Resume controller have saved instance of application + * @param policy_app_id - mobile application id + * @param device_id - id of device where application is run + * @return true if exist, false otherwise + */ + bool IsApplicationSaved(const std::string& policy_app_id, + const std::string& device_id) OVERRIDE; + + /** + * @brief Function is used for application resume. HMI app ID must be + * the same(PASA VCA module use it for stored app info). + * Retrieves HMI app ID for the given policy app ID from stored information. + * @param policy_app_id - mobile application id + * @param device_id - id of device where application is run + * @return HMI app ID + */ + uint32_t GetHMIApplicationID(const std::string& policy_app_id, + const std::string& device_id) const OVERRIDE; + + /** + * @brief Updates flag for saving application data + */ + void ApplicationsDataUpdated() OVERRIDE { + is_data_saved_ = false; + } + + /** + * @brief Resume HMI Level and audio streaming state if needed + * @param application - application to restore hmi level + * and audio streaming state + */ + void StartAppHmiStateResumption( + app_mngr::ApplicationSharedPtr application) OVERRIDE; + + /** + * @brief Update launch_time_ to current + */ + void ResetLaunchTime() OVERRIDE; + + /** + * @brief Removes activated application from resumption list + * + * @param application application witch need to be removed from resumption + */ + void OnAppActivated(app_mngr::ApplicationSharedPtr application) OVERRIDE; + + /** + * @brief Removes app from resumption list + * + * app_id Application to remove + */ + void RemoveFromResumption(uint32_t app_id) OVERRIDE; + + /** + * @brief Initialization data for Resume controller + * @return true if initialization is success otherwise + * returns false + */ + bool Init(LastState& last_state) OVERRIDE; + + /** + * @brief Notify resume controller about new application + * @param policy_app_id - mobile application id + * @param device_id - id of device where application is run + */ + void OnAppRegistrationStart(const std::string& policy_app_id, + const std::string& device_id) OVERRIDE; + + /** + * @brief Notify resume controller about delete new application + */ + void OnAppRegistrationEnd() OVERRIDE; + + int32_t GetSavedAppHmiLevel(const std::string& app_id, + const std::string& device_id) const OVERRIDE; + + /** + * @brief geter for launch_time_ + * @return value of launch_time_ + */ + time_t LaunchTime() const OVERRIDE; + + /** + * @brief Timer callback for restoring HMI Level + * + */ + void ApplicationResumptiOnTimer(); + + /** + * @brief Method starts timer "RsmCtrlPercist" when + * SDL receives onAwakeSDL notification + */ + void StartSavePersistentDataTimer(); + +#ifdef BUILD_TESTS + void set_resumption_storage( + utils::SharedPtr<ResumptionData> mock_storage) OVERRIDE; +#endif // BUILD_TESTS + private: + /** + * @brief restores saved data of application + * @param application contains application for which restores data + * @return true if success, otherwise return false + */ + bool RestoreApplicationData(app_mngr::ApplicationSharedPtr application); + + /** + * @brief SaveDataOnTimer : + * Timer callback for persisting ResumptionData each N seconds + * N gets from property + */ + void SaveDataOnTimer(); + + /** + * @brief AddFiles allows to add files for the application + * which should be resumed + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void AddFiles(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app); + + /** + * @brief AddSubmenues allows to add sub menues for the application + * which should be resumed + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void AddSubmenues(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app); + + /** + * @brief AddCommands allows to add commands for the application + * which should be resumed + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void AddCommands(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app); + + /** + * @brief AddChoicesets allows to add choice sets for the application + * which should be resumed + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void AddChoicesets(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app); + + /** + * @brief SetGlobalProperties allows to restore global properties. + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void SetGlobalProperties(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app); + + /** + * @brief AddSubscriptions allows to restore subscriptions + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void AddSubscriptions(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app); + + /** + * @brief AddWayPointsSubscription allows to restore subscription + * for WayPoints + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void AddWayPointsSubscription(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app); + + bool CheckIgnCycleRestrictions(const smart_objects::SmartObject& saved_app); + + bool DisconnectedJustBeforeIgnOff( + const smart_objects::SmartObject& saved_app); + + bool CheckAppRestrictions(app_mngr::ApplicationConstSharedPtr application, + const smart_objects::SmartObject& saved_app); + + /** + * @brief CheckIcons allows to check application icons + * @param application application under resumtion application + * @param json_object + * @return true in case icons exists, false otherwise + */ + bool CheckIcons(app_mngr::ApplicationSharedPtr application, + smart_objects::SmartObject& obj); + + /** + * @brief CheckDelayAfterIgnOn should check if SDL was started less + * then N secconds ago. N will be readed from profile. + * @return true if SDL started N secconds ago, otherwise return false + */ + bool CheckDelayAfterIgnOn(); + + typedef std::pair<uint32_t, uint32_t> application_timestamp; + + std::set<app_mngr::ApplicationSharedPtr> retrieve_application(); + + /** + * @brief This struct need to map + * timestamp and application from correlationID + */ + struct ResumingApp { + uint32_t old_session_key; // session key is the same as app_id + app_mngr::ApplicationSharedPtr app; + }; + + struct TimeStampComparator { + bool operator()(const application_timestamp& lhs, + const application_timestamp& rhs) const { + return lhs.second < rhs.second; + } + }; + + /** + * @brief Check device MAC address + * @param application that is need to be restored + * @param saved_device_mac Saved device MAC address + * @return TRUE on success, otherwise FALSE + */ + bool IsDeviceMacAddressEqual(app_mngr::ApplicationSharedPtr application, + const std::string& saved_device_mac); + + /** + * @brief Get the last ignition off time from LastState + * @return the last ignition off time from LastState + */ + time_t GetIgnOffTime(); + + /** + * @brief Setup IgnOff time to LastState + * @param ign_off_time - igition off time + */ + void SetLastIgnOffTime(time_t ign_off_time); + + /** + * @brief Process specified HMI request + * @param request Request to process + * @param use_events Process request events or not flag + * @return TRUE on success, otherwise FALSE + */ + bool ProcessHMIRequest(smart_objects::SmartObjectSPtr request = NULL, + bool use_events = false); + + /** + * @brief Process list of HMI requests using ProcessHMIRequest method + * @param requests List of requests to process + */ + void ProcessHMIRequests(const smart_objects::SmartObjectList& requests); + + void InsertToTimerQueue(uint32_t app_id, uint32_t time_stamp); + + /** + * @brief Add application to queue to restore HMI level + * @param time_stamp contains time when application was stored to resumption + * data + * @param app_id contains id of application + */ + void AddToResumptionTimerQueue(const uint32_t app_id); + + void LoadResumeData(); + + /** + * @brief Checks, if application data needs to be resumed + * @param application Application data from storage + * @return true, if data resumption must be skipped, otherwise - false + */ + bool IsAppDataResumptionExpired( + const smart_objects::SmartObject& application) const; + + /** + * @brief Checks from resume data, if application has been disconnected + * unexpectedly + * @param app Application section from resume data + * @return true, if it has been unexpectedly disconnected, otherwise - false + */ + bool IsUnexpectedlyDisconnected(const smart_objects::SmartObject& app) const; + + /** + * @brief Checks, if application can be resumed + * @param application Application + * @param time_stamp contain time when application was stored to resumption + * data + * @return true, if no restrictions currently, otherwise - false + */ + bool IsResumeAllowed( + const application_manager::ApplicationSharedPtr application) const; + + /** + *@brief Mapping applications to time_stamps + * wait for timer to resume HMI Level + * + */ + mutable sync_primitives::Lock queue_lock_; + timer::Timer restore_hmi_level_timer_; + timer::Timer save_persistent_data_timer_; + typedef std::list<uint32_t> WaitingForTimerList; + WaitingForTimerList waiting_for_timer_; + bool is_resumption_active_; + bool is_data_saved_; + time_t launch_time_; + utils::SharedPtr<ResumptionData> resumption_storage_; + application_manager::ApplicationManager& application_manager_; +}; + +} // namespace resumption +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUME_CTRL_IMPL_H_ diff --git a/src/components/application_manager/include/application_manager/smart_object_keys.h b/src/components/application_manager/include/application_manager/smart_object_keys.h index 1fda170c34..a1639eebd8 100644 --- a/src/components/application_manager/include/application_manager/smart_object_keys.h +++ b/src/components/application_manager/include/application_manager/smart_object_keys.h @@ -51,6 +51,12 @@ extern const char* msg_params; extern const char* method_name; extern const char* info; extern const char* app_id; +extern const char* bundle_id; +extern const char* app_info; +extern const char* app_launch; +extern const char* app_launch_list; +extern const char* app_launch_last_session; +extern const char* policy_app_id; extern const char* hmi_app_id; extern const char* device_id; extern const char* subscribed_for_way_points; diff --git a/src/components/application_manager/src/app_launch/app_launch_ctrl_impl.cc b/src/components/application_manager/src/app_launch/app_launch_ctrl_impl.cc new file mode 100644 index 0000000000..481635d8e6 --- /dev/null +++ b/src/components/application_manager/src/app_launch/app_launch_ctrl_impl.cc @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <iterator> +#include <algorithm> +#include <utility> +#include <vector> +#include "application_manager/app_launch/app_launch_ctrl_impl.h" +#include "application_manager/resumption/resume_ctrl.h" +#include "connection_handler/connection_handler.h" +#include "application_manager/application.h" +#include "utils/timer_task_impl.h" +#include "utils/make_shared.h" + +namespace app_launch { +CREATE_LOGGERPTR_GLOBAL(logger_, "AppLaunch") + +AppLaunchCtrlImpl::AppLaunchCtrlImpl( + AppLaunchData& data, + application_manager::ApplicationManager& app_mngr, + const AppLaunchSettings& settings) + : settings_(settings) + , app_launch_data_(data) + , resume_ctrl_(app_mngr.resume_controller()) + , apps_launcher_(app_mngr.connection_handler(), + settings.max_number_of_ios_device(), + settings.app_launch_max_retry_attempt(), + settings.app_launch_retry_wait_time()) + , device_apps_launcher_(app_mngr, apps_launcher_, settings) {} + +void AppLaunchCtrlImpl::OnAppRegistered( + const application_manager::Application& app) { + LOG4CXX_AUTO_TRACE(logger_); + // TODO (AKutsan) : get device mac + ApplicationDataPtr app_data = utils::MakeShared<ApplicationData>( + app.policy_app_id(), app.bundle_id(), app.mac_address()); + apps_launcher_.OnLaunched(app_data); + app_launch_data_.AddApplicationData(*app_data); +} + +ApplicationDataPtr GetAppFromHmiLevelPair( + const std::pair<int32_t, ApplicationDataPtr>& pair) { + return pair.second; +} + +bool HmiLevelSorter(const std::pair<int32_t, ApplicationDataPtr>& lval, + const std::pair<int32_t, ApplicationDataPtr>& rval) { + if (lval.first == -1) { + return false; + } + if (rval.first == -1) { + return true; + } + return lval.first < rval.first; +} + +void AppLaunchCtrlImpl::OnDeviceConnected(const std::string& device_mac) { + LOG4CXX_AUTO_TRACE(logger_); + std::vector<ApplicationDataPtr> apps_on_device = + app_launch_data_.GetApplicationDataByDevice(device_mac); + std::vector<std::pair<int32_t, ApplicationDataPtr> > apps_hmi_levels; + std::vector<ApplicationDataPtr>::iterator it = apps_on_device.begin(); + for (; it != apps_on_device.end(); ++it) { + const ApplicationDataPtr& app_data = *it; + const int32_t hmi_level = resume_ctrl_.GetSavedAppHmiLevel( + app_data->mobile_app_id_, app_data->device_mac_); + const std::pair<int32_t, ApplicationDataPtr> hmi_level_app(hmi_level, + app_data); + apps_hmi_levels.push_back(hmi_level_app); + } + std::sort(apps_hmi_levels.begin(), apps_hmi_levels.end(), HmiLevelSorter); + apps_on_device.clear(); + std::transform(apps_hmi_levels.begin(), + apps_hmi_levels.end(), + std::back_inserter(apps_on_device), + GetAppFromHmiLevelPair); + if (apps_on_device.size() > 0) { + device_apps_launcher_.LaunchAppsOnDevice(device_mac, apps_on_device); + } else { + LOG4CXX_DEBUG(logger_, "No apps in saved for device " << device_mac); + } +} + +void AppLaunchCtrlImpl::OnMasterReset() { + LOG4CXX_AUTO_TRACE(logger_); + app_launch_data_.Clear(); +} +} // namespace app_launch diff --git a/src/components/application_manager/src/app_launch/app_launch_data_db.cc b/src/components/application_manager/src/app_launch/app_launch_data_db.cc new file mode 100644 index 0000000000..f3adfc749b --- /dev/null +++ b/src/components/application_manager/src/app_launch/app_launch_data_db.cc @@ -0,0 +1,396 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <string> +#include <unistd.h> + +#include "application_manager/app_launch/app_launch_data_db.h" +#include "application_manager/application_manager_impl.h" +#include "application_manager/app_launch/app_launch_sql_queries.h" +#include "application_manager/smart_object_keys.h" +#include "application_manager/message_helper.h" +#include "utils/make_shared.h" + +namespace app_launch { +CREATE_LOGGERPTR_GLOBAL(logger_, "AppLaunch") + +AppLaunchDataDB::AppLaunchDataDB(const AppLaunchSettings& settings, + DbStorage db_storage) + : AppLaunchDataImpl(settings) { + if (db_storage == In_File_Storage) { + db_.reset(new utils::dbms::SQLDatabase(kDatabaseName)); +#ifndef __QNX__ + std::string path = settings_.app_storage_folder(); + if (!path.empty()) { + db()->set_path(path + "/"); + } + } else if (db_storage == In_Memory_Storage) { + db_.reset(new utils::dbms::SQLDatabase()); +#endif // __QNX__ + DCHECK(db_.get()); + } else { + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_ERROR(logger_, "Get not existed type of database storage"); + } + + // Connect to resumption DB + init_successeful_ = Init(); +} + +AppLaunchDataDB::~AppLaunchDataDB() { + db()->Close(); +} + +bool AppLaunchDataDB::Init() { + LOG4CXX_AUTO_TRACE(logger_); + + if (!db()->Open()) { + LOG4CXX_ERROR(logger_, "Failed opening database."); + LOG4CXX_INFO(logger_, "Starting opening retries."); + const uint16_t attempts = settings_.app_launch_max_retry_attempt(); + LOG4CXX_DEBUG(logger_, "Total attempts number is: " << attempts); + bool is_opened = false; + const uint16_t open_attempt_timeout_ms = + settings_.app_launch_retry_wait_time(); + const useconds_t sleep_interval_mcsec = open_attempt_timeout_ms * 1000u; + LOG4CXX_DEBUG(logger_, + "Open attempt timeout(ms) is: " << open_attempt_timeout_ms); + for (size_t i = 0u; i < attempts; ++i) { + usleep(sleep_interval_mcsec); + LOG4CXX_INFO(logger_, "Attempt: " << i + 1); + if (db()->Open()) { + LOG4CXX_INFO(logger_, "Database opened."); + is_opened = true; + break; + } + } + if (!is_opened) { + LOG4CXX_ERROR(logger_, + "Open retry sequence failed. Tried " + << attempts << " attempts with " + << open_attempt_timeout_ms + << " open timeout(ms) for each."); + return false; + } + } +#ifndef __QNX__ + if (!db()->IsReadWrite()) { + LOG4CXX_ERROR(logger_, "There are no read/write permissions for database"); + return false; + } +#endif // __QNX__ + + utils::dbms::SQLQuery query(db()); + if (!query.Exec(kCreateSchema)) { + LOG4CXX_ERROR( + logger_, + "Failed creating schema of database: " << query.LastError().text()); + return false; + } + + return true; +} + +bool AppLaunchDataDB::Persist() { + LOG4CXX_AUTO_TRACE(logger_); + bool retVal = false; + + if (!init_successeful_) { + LOG4CXX_ERROR(logger_, + "AppLaunch data base was not successfully " + "initialize, AppLaunch won't work!"); + return retVal; + } + + if ((retVal = WriteDb())) { + LOG4CXX_DEBUG(logger_, "App_lauch had been successfully saved."); + } else { + LOG4CXX_WARN(logger_, "Fail to save app_launch data."); + } + + return retVal; +} + +bool AppLaunchDataDB::IsAppDataAlreadyExisted( + const ApplicationData& app_data) const { + LOG4CXX_AUTO_TRACE(logger_); + bool retVal = false; + + if (!init_successeful_) { + LOG4CXX_ERROR(logger_, + "AppLaunch data base was not successfully " + "initialize, AppLaunch won't work!"); + return retVal; + } + + utils::dbms::SQLQuery query(db()); + + if (!query.Prepare(kFindApplicationData)) { + LOG4CXX_WARN(logger_, + "Problem with verification queries 'kFindApplicationData'"); + return retVal; + } + + query.Bind(device_mac_index, app_data.device_mac_); + query.Bind(application_id_index, app_data.mobile_app_id_); + query.Bind(bundle_id_index, app_data.bundle_id_); + + if (query.Exec()) { + retVal = query.GetBoolean(result_query); + } else { + LOG4CXX_WARN(logger_, + "Failed execute query 'kGetNumberOfApplicationData'. Reson: " + << query.LastError().text()); + } + + return retVal; +} + +bool AppLaunchDataDB::RefreshAppSessionTime(const ApplicationData& app_data) { + LOG4CXX_AUTO_TRACE(logger_); + bool retVal = false; + + if (!init_successeful_) { + LOG4CXX_ERROR(logger_, + "AppLaunch data base was not successfully " + "initialize, AppLaunch won't work!"); + return retVal; + } + + utils::dbms::SQLQuery query(db()); + + if (!query.Prepare(kRefreshApplicationDataSessionTime)) { + LOG4CXX_WARN(logger_, + "Problem with verification queries " + "'kRefreshApplicationDataSessionTime'"); + return retVal; + } + + query.Bind(device_mac_index, app_data.device_mac_); + query.Bind(application_id_index, app_data.mobile_app_id_); + query.Bind(bundle_id_index, app_data.bundle_id_); + + if (query.Exec()) { + LOG4CXX_DEBUG(logger_, "Dare&time last session were updated successfully"); + retVal = WriteDb(); + } else { + LOG4CXX_WARN(logger_, + "Failed execute query 'kGetNumberOfApplicationData'. Reson: " + << query.LastError().text()); + } + + return retVal; +} + +bool AppLaunchDataDB::AddNewAppData(const ApplicationData& app_data) { + LOG4CXX_AUTO_TRACE(logger_); + bool retVal = false; + + if (!init_successeful_) { + LOG4CXX_ERROR(logger_, + "AppLaunch data base was not successfully " + "initialize, AppLaunch won't work!"); + return retVal; + } + + utils::dbms::SQLQuery query(db()); + + if (!query.Prepare(kAddApplicationData)) { + LOG4CXX_WARN(logger_, + "Problem with verification queries 'kAddApplicationData'"); + return retVal; + } + + query.Bind(device_mac_index, app_data.device_mac_); + query.Bind(application_id_index, app_data.mobile_app_id_); + query.Bind(bundle_id_index, app_data.bundle_id_); + + retVal = query.Exec(); + if (retVal) { + LOG4CXX_DEBUG(logger_, "New application data was added successfully"); + retVal = WriteDb(); + } else { + LOG4CXX_WARN(logger_, + "Failed execute query 'kGetNumberOfApplicationData'. Reson: " + << query.LastError().text()); + } + + return retVal; +} + +std::vector<ApplicationDataPtr> AppLaunchDataDB::GetAppDataByDevMac( + const std::string& dev_mac) const { + LOG4CXX_AUTO_TRACE(logger_); + std::vector<ApplicationDataPtr> dev_apps; + + if (!init_successeful_) { + LOG4CXX_ERROR(logger_, + "AppLaunch data base was not successfully " + "initialize, AppLaunch won't work!"); + return dev_apps; + } + + utils::dbms::SQLQuery query(db()); + + if (!query.Prepare(kGetApplicationDataByDevID)) { + LOG4CXX_WARN( + logger_, + "Problem with verification queries 'kGetApplicationDataByDevID'"); + return dev_apps; + } + + query.Bind(device_mac_index, dev_mac); + const bool retVal = query.Exec(); + if (retVal) { + LOG4CXX_INFO(logger_, + "Values of ignition off counts were updated successfully"); + do { + const std::string device_mac = query.GetString(device_mac_index); + const std::string mobile_app_id = query.GetString(application_id_index); + const std::string bundle_id = query.GetString(bundle_id_index); + dev_apps.push_back(utils::MakeShared<ApplicationData>( + mobile_app_id, bundle_id, device_mac)); + } while (query.Next()); + LOG4CXX_DEBUG(logger_, "All application data has been successfully loaded"); + } else { + LOG4CXX_WARN(logger_, + "Failed execute query 'kGetNumberOfApplicationData'. Reson: " + << query.LastError().text()); + } + + return dev_apps; +} + +bool AppLaunchDataDB::Clear() { + LOG4CXX_AUTO_TRACE(logger_); + bool retVal = false; + + utils::dbms::SQLQuery query(db()); + retVal = query.Exec(kDropSchema); + + if (retVal) { + LOG4CXX_INFO(logger_, "App_Launch table had been cleared successfully"); + retVal = WriteDb(); + init_successeful_ = false; + } else { + LOG4CXX_WARN(logger_, + "Failed dropping database: " << query.LastError().text()); + } + + return retVal; +} + +uint32_t AppLaunchDataDB::GetCurentNumberOfAppData() const { + LOG4CXX_AUTO_TRACE(logger_); + uint32_t number_of_app_data = 0u; + + if (!init_successeful_) { + LOG4CXX_ERROR(logger_, + "AppLaunch data base was not successfully " + "initialize, AppLaunch won't work!"); + return number_of_app_data; + } + + utils::dbms::SQLQuery query(db()); + + if (!query.Prepare(kGetNumberOfApplicationData)) { + LOG4CXX_WARN( + logger_, + "Problem with verification queries 'kGetNumberOfApplicationData'"); + return number_of_app_data; + } + + if (query.Exec()) { + LOG4CXX_INFO(logger_, + "Values of ignition off counts were updated successfully"); + + number_of_app_data = query.GetInteger(result_query); + LOG4CXX_DEBUG(logger_, + "Total cout saved mobile applications is " + << number_of_app_data); + } else { + LOG4CXX_WARN(logger_, + "Failed execute query 'kGetNumberOfApplicationData'. Reson: " + << query.LastError().text()); + } + + return number_of_app_data; +} + +bool AppLaunchDataDB::DeleteOldestAppData() { + LOG4CXX_AUTO_TRACE(logger_); + bool retVal = false; + + if (!init_successeful_) { + LOG4CXX_ERROR(logger_, + "AppLaunch data base was not successfully " + "initialize, AppLaunch won't work!"); + return retVal; + } + + utils::dbms::SQLQuery query(db()); + + if (!query.Prepare(kDeleteOldestAppData)) { + LOG4CXX_WARN(logger_, + "Problem with verification queries 'kDeleteOldestAppData'"); + return retVal; + } + + if ((retVal = query.Exec())) { + LOG4CXX_INFO(logger_, + "Values of ignition off counts were updated successfully"); + retVal = WriteDb(); + } else { + LOG4CXX_WARN(logger_, + "Failed execute query 'kGetNumberOfApplicationData'. Reson: " + << query.LastError().text()); + } + + return retVal; +} + +bool AppLaunchDataDB::WriteDb() { + LOG4CXX_AUTO_TRACE(logger_); + return db_->Backup(); +} + +utils::dbms::SQLDatabase* AppLaunchDataDB::db() const { +#ifdef __QNX__ + std::auto_ptr<utils::dbms::SQLDatabase> db_qnx( + new utils::dbms::SQLDatabase(kDatabaseName)); + db_qnx.get()->Open(); + return db_qnx.get(); +#else + return db_.get(); +#endif // __QNX__ +} + +} // namespace resumption diff --git a/src/components/application_manager/src/app_launch/app_launch_data_impl.cc b/src/components/application_manager/src/app_launch/app_launch_data_impl.cc new file mode 100644 index 0000000000..c095cc9d94 --- /dev/null +++ b/src/components/application_manager/src/app_launch/app_launch_data_impl.cc @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include "application_manager/app_launch/app_launch_data_impl.h" +#include "utils/logger.h" + +namespace app_launch { + +CREATE_LOGGERPTR_GLOBAL(logger_, "AppLaunch") + +AppLaunchDataImpl::AppLaunchDataImpl(const AppLaunchSettings& settings) + : settings_(settings) + , kMaxNumberOfiOSdevice(settings.max_number_of_ios_device()) {} + +AppLaunchDataImpl::~AppLaunchDataImpl() {} + +bool AppLaunchDataImpl::AddApplicationData(const ApplicationData& app_data) { + LOG4CXX_AUTO_TRACE(logger_); + bool retVal = true; + + if (app_data.device_mac_.empty() == false && + app_data.mobile_app_id_.empty() == false && + app_data.bundle_id_.empty() == false) { + if (IsAppDataAlreadyExisted(app_data)) { + LOG4CXX_INFO(logger_, "This application data already existed"); + retVal &= RefreshAppSessionTime(app_data); + } else { + if (GetCurentNumberOfAppData() >= get_max_number_iOS_devs()) { + LOG4CXX_INFO(logger_, + "Max number of application data have. It will be deleted " + "the oldest one"); + retVal &= DeleteOldestAppData(); + } + retVal &= AddNewAppData(app_data); + LOG4CXX_INFO(logger_, "Added new application data to DB"); + } + } else { + retVal = false; + } + return retVal; +} + +std::vector<ApplicationDataPtr> AppLaunchDataImpl::GetApplicationDataByDevice( + const std::string& dev_mac) { + LOG4CXX_AUTO_TRACE(logger_); + std::vector<ApplicationDataPtr> apps = GetAppDataByDevMac(dev_mac); + + if (apps.empty()) { + LOG4CXX_DEBUG(logger_, "No application founded by mac" << dev_mac); + } + + return apps; +} + +} // namespace app_launch diff --git a/src/components/application_manager/src/app_launch/app_launch_data_json.cc b/src/components/application_manager/src/app_launch/app_launch_data_json.cc new file mode 100644 index 0000000000..260dde7205 --- /dev/null +++ b/src/components/application_manager/src/app_launch/app_launch_data_json.cc @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <algorithm> +#include "application_manager/app_launch/app_launch_data_json.h" +#include "application_manager/smart_object_keys.h" +#include "smart_objects/smart_object.h" +#include "utils/make_shared.h" +#include "utils/date_time.h" +#include "json/json.h" + +namespace app_launch { + +CREATE_LOGGERPTR_GLOBAL(logger_, "AppLaunch") + +AppLaunchDataJson::AppLaunchDataJson(const AppLaunchSettings& settings, + resumption::LastState& last_state) + : AppLaunchDataImpl(settings) + , app_launch_json_lock_(true) + , last_state_(last_state) {} + +AppLaunchDataJson::~AppLaunchDataJson() {} + +Json::Value& AppLaunchDataJson::GetSavedApplicationDataList() const { + using namespace application_manager; + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock autolock(app_launch_json_lock_); + Json::Value& app_launch = GetApplicationData(); + if (!app_launch.isMember(strings::app_launch_list)) { + app_launch[strings::app_launch_list] = Json::Value(Json::arrayValue); + LOG4CXX_WARN(logger_, "app_list section is missed"); + } + Json::Value& app_launch_list = app_launch[strings::app_launch_list]; + if (!app_launch_list.isArray()) { + LOG4CXX_ERROR(logger_, "app_launch_list type INVALID rewrite"); + app_launch_list = Json::Value(Json::arrayValue); + } + return app_launch_list; +} + +Json::Value& AppLaunchDataJson::GetApplicationData() const { + using namespace application_manager; + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock autolock(app_launch_json_lock_); + Json::Value& dictionary = last_state().dictionary; + if (!dictionary.isMember(strings::app_launch)) { + last_state().dictionary[strings::app_launch] = + Json::Value(Json::objectValue); + LOG4CXX_WARN(logger_, "app_launch section is missed"); + } + Json::Value& app_launch = dictionary[strings::app_launch]; + if (!app_launch.isObject()) { + LOG4CXX_ERROR(logger_, "resumption type INVALID rewrite"); + app_launch = Json::Value(Json::objectValue); + } + return app_launch; +} + +Json::Value& AppLaunchDataJson::GetApplicationListAndIndex( + const ApplicationData& app_data, int32_t& founded_index) const { + using namespace application_manager; + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock autolock(app_launch_json_lock_); + + Json::Value& apps_list = GetSavedApplicationDataList(); + const Json::ArrayIndex size = apps_list.size(); + + for (Json::ArrayIndex idx = 0; idx != size; ++idx) { + if (apps_list[idx].isMember(strings::device_id) && + apps_list[idx].isMember(strings::bundle_id) && + apps_list[idx].isMember(strings::app_id) && + apps_list[idx].isMember(strings::app_launch_last_session)) { + const std::string deviceID = + apps_list[idx][strings::device_id].asString(); + const std::string bundleID = + apps_list[idx][strings::bundle_id].asString(); + const std::string appID = apps_list[idx][strings::app_id].asString(); + + if (deviceID == app_data.device_mac_ && bundleID == app_data.bundle_id_ && + appID == app_data.mobile_app_id_) { + founded_index = idx; + } + } + } + + return apps_list; +} + +bool AppLaunchDataJson::IsAppDataAlreadyExisted( + const ApplicationData& app_data) const { + LOG4CXX_AUTO_TRACE(logger_); + + int32_t index = NotFound; + GetApplicationListAndIndex(app_data, index); + return index == NotFound ? false : true; +} + +bool AppLaunchDataJson::RefreshAppSessionTime(const ApplicationData& app_data) { + using namespace application_manager; + using namespace date_time; + LOG4CXX_AUTO_TRACE(logger_); + bool retVal = false; + + int32_t index = NotFound; + Json::Value& json_data_list = GetApplicationListAndIndex(app_data, index); + if (index != NotFound) { + if (json_data_list.empty() == false) { + json_data_list[index][strings::app_launch_last_session] = + static_cast<Json::Value::UInt64>(DateTime::getCurrentTime().tv_sec); + retVal = true; + } + } + return retVal; +} + +bool AppLaunchDataJson::AddNewAppData(const ApplicationData& app_data) { + using namespace application_manager; + using namespace date_time; + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock autolock(app_launch_json_lock_); + + Json::Value& json_app_data = + GetSavedApplicationDataList().append(Json::Value()); + json_app_data[strings::device_id] = app_data.device_mac_; + json_app_data[strings::app_id] = app_data.mobile_app_id_; + json_app_data[strings::bundle_id] = app_data.bundle_id_; + json_app_data[strings::app_launch_last_session] = + static_cast<Json::Value::UInt64>(DateTime::getCurrentTime().tv_sec); + + LOG4CXX_DEBUG(logger_, + "New application data saved. Detatils device_id: " + << app_data.device_mac_ + << ", app_id: " << app_data.mobile_app_id_ + << ", bundle_id: " << app_data.bundle_id_ << "."); + + return true; +} + +std::vector<ApplicationDataPtr> AppLaunchDataJson::GetAppDataByDevMac( + const std::string& dev_mac) const { + using namespace application_manager; + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock autolock(app_launch_json_lock_); + std::vector<ApplicationDataPtr> dev_apps; + const Json::Value& apps_list = GetSavedApplicationDataList(); + const Json::ArrayIndex size = apps_list.size(); + + for (Json::ArrayIndex idx = 0; idx != size; ++idx) { + if (apps_list[idx].isMember(strings::device_id) && + apps_list[idx].isMember(strings::bundle_id) && + apps_list[idx].isMember(strings::app_id) && + apps_list[idx].isMember(strings::app_launch_last_session)) { + const std::string deviceMac = + apps_list[idx][strings::device_id].asString(); + const std::string bundleID = + apps_list[idx][strings::bundle_id].asString(); + const std::string appID = apps_list[idx][strings::app_id].asString(); + + if (deviceMac == dev_mac) { + dev_apps.push_back( + utils::MakeShared<ApplicationData>(appID, bundleID, deviceMac)); + } + } + } + + return dev_apps; +} + +bool AppLaunchDataJson::Clear() { + LOG4CXX_AUTO_TRACE(logger_); + + GetSavedApplicationDataList().clear(); + + LOG4CXX_DEBUG(logger_, + "Application launch JSON section successfully cleared."); + + return true; +} + +uint32_t AppLaunchDataJson::GetCurentNumberOfAppData() const { + LOG4CXX_AUTO_TRACE(logger_); + + uint32_t list_size = GetSavedApplicationDataList().size(); + + LOG4CXX_DEBUG(logger_, + "Successfully was gotten app_launch list. Size: " << list_size); + + return list_size; +} + +bool AppLaunchDataJson::DeleteOldestAppData() { + using namespace application_manager; + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock autolock(app_launch_json_lock_); + std::vector<uint64_t> temp_array; + std::vector<Json::Value> temp_json_list; + Json::Value& apps_list = GetSavedApplicationDataList(); + const Json::ArrayIndex size = apps_list.size(); + + // Search oldest record in Json + // for it collect all timestaps in vector + for (Json::ArrayIndex idx = 0; idx != size; ++idx) { + if (apps_list[idx].isMember(strings::device_id) && + apps_list[idx].isMember(strings::bundle_id) && + apps_list[idx].isMember(strings::app_id) && + apps_list[idx].isMember(strings::app_launch_last_session)) { + temp_array.push_back( + apps_list[idx][strings::app_launch_last_session].asUInt64()); + } + } + + // Calc oldest one and found index of it in Json + const int32_t oldest_index = + (std::min_element(temp_array.begin(), temp_array.end()) - + temp_array.begin()); + + // Copy in temporary vector Json list without oldest record + int32_t i = 0; + for (Json::Value::iterator it = GetSavedApplicationDataList().begin(); + it != GetSavedApplicationDataList().end(); + ++it, i++) { + if ((*it).isMember(strings::device_id) && + (*it).isMember(strings::bundle_id) && (*it).isMember(strings::app_id) && + (*it).isMember(strings::app_launch_last_session)) { + if (i == oldest_index) { + continue; + } + temp_json_list.push_back((*it)); + } + } + + // Clear Json list + GetSavedApplicationDataList().clear(); + + // Copy to Json new list without oldest one + for (std::vector<Json::Value>::iterator it = temp_json_list.begin(); + it != temp_json_list.end(); + ++it) { + GetSavedApplicationDataList().append((*it)); + } + + LOG4CXX_DEBUG( + logger_, "Oldest application launch data had been successfully deleted."); + + return true; +} + +bool AppLaunchDataJson::Persist() { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock autolock(app_launch_json_lock_); + last_state().SaveToFileSystem(); + return true; +} + +} // app_launch diff --git a/src/components/application_manager/src/app_launch/app_launch_sql_queries.cc b/src/components/application_manager/src/app_launch/app_launch_sql_queries.cc new file mode 100644 index 0000000000..950bcd44fa --- /dev/null +++ b/src/components/application_manager/src/app_launch/app_launch_sql_queries.cc @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include "application_manager/app_launch/app_launch_sql_queries.h" + +namespace app_launch { + +const std::string kCreateSchema = + "CREATE TABLE IF NOT EXISTS `app_launch`( " + " `deviceMac` TEXT, " + " `appID` TEXT," + " `bundleID` TEXT," + " `last_session` DATETIME, " + " PRIMARY KEY(`deviceMac`, `appID`, `bundleID`)" + " ); "; + +const std::string kDropSchema = "DROP TABLE IF EXISTS `app_launch`; "; + +const std::string kAddApplicationData = + "INSERT INTO `app_launch`" + "(`deviceMac`, `appID`, `bundleID`, `last_session`)" + "VALUES " + "(?, ?, ?, STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW'));"; + +const std::string kFindApplicationData = + " SELECT COUNT(*)" + "FROM `app_launch`" + "WHERE `deviceMac` = ? AND `appID` = ? AND `bundleID` = ?;"; + +const std::string kDeleteOldestAppData = + "DELETE FROM `app_launch`" + "WHERE `last_session` IN (" + "SELECT MIN(`last_session`)" + "FROM `app_launch`);"; + +const std::string kGetNumberOfApplicationData = + "SELECT COUNT (*)" + "FROM `app_launch` ;"; + +const std::string kGetApplicationDataByDevID = + "SELECT *" + "FROM `app_launch`" + "WHERE `deviceMac` = ?;"; + +const std::string kRefreshApplicationDataSessionTime = + "UPDATE `app_launch`" + "SET `last_session` = STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')" + "WHERE `deviceMac` = ? AND appID = ? AND bundleID = ?;"; + +} // namespace resumption diff --git a/src/components/application_manager/src/app_launch/apps_launcher.cc b/src/components/application_manager/src/app_launch/apps_launcher.cc new file mode 100644 index 0000000000..41465ae985 --- /dev/null +++ b/src/components/application_manager/src/app_launch/apps_launcher.cc @@ -0,0 +1,139 @@ +#include <algorithm> +#include "application_manager/app_launch/apps_launcher.h" +#include "utils/make_shared.h" +#include "utils/timer_task_impl.h" +#include <iostream> + +namespace app_launch { +struct LauncherGenerator { + LauncherGenerator(AppsLauncher& apps_laucnher, + connection_handler::ConnectionHandler& connection_handler, + const uint16_t app_launch_max_retry_attempt, + const uint16_t app_launch_retry_wait_time) + : apps_laucnher_(apps_laucnher) + , connection_handler_(connection_handler) + , app_launch_max_retry_attempt_(app_launch_max_retry_attempt) + , app_launch_retry_wait_time_(app_launch_retry_wait_time) {} + AppsLauncher::LauncherPtr operator()() { + return utils::MakeShared<AppsLauncher::Launcher>( + apps_laucnher_, + connection_handler_, + app_launch_max_retry_attempt_, + app_launch_retry_wait_time_); + } + + AppsLauncher& apps_laucnher_; + connection_handler::ConnectionHandler& connection_handler_; + const uint16_t app_launch_max_retry_attempt_; + const uint16_t app_launch_retry_wait_time_; +}; + +CREATE_LOGGERPTR_GLOBAL(logger_, "AppLaunch") +AppsLauncher::AppsLauncher( + connection_handler::ConnectionHandler& connection_handler, + const uint16_t max_number_of_ios_device, + const uint16_t app_launch_max_retry_attempt, + const uint16_t app_launch_retry_wait_time) { + sync_primitives::AutoLock lock(launchers_lock_); + free_launchers_.resize(max_number_of_ios_device); + std::generate(free_launchers_.begin(), + free_launchers_.end(), + LauncherGenerator(*this, + connection_handler, + app_launch_max_retry_attempt, + app_launch_retry_wait_time)); +} + +void AppsLauncher::StartLaunching(ApplicationDataPtr app_data) { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(launchers_lock_); + DCHECK_OR_RETURN_VOID(!free_launchers_.empty()) + const AppLaunchers::iterator it = free_launchers_.begin(); + LauncherPtr app_launcher = *it; + works_launchers_.push_back(app_launcher); + free_launchers_.erase(it); + app_launcher->PosponedLaunch(app_data); +} + +struct AppLauncherFinder { + AppLauncherFinder(const ApplicationDataPtr& app_data) : app_data_(app_data) {} + bool operator()(const AppsLauncher::LauncherPtr& launcher) const { + DCHECK_OR_RETURN(launcher->app_data_ && app_data_, false) + return *launcher->app_data_ == *app_data_; + } + const ApplicationDataPtr& app_data_; +}; + +void AppsLauncher::StopLaunching(ApplicationDataPtr app_data) { + sync_primitives::AutoLock lock(launchers_lock_); + const AppLaunchers::iterator it = std::find_if(works_launchers_.begin(), + works_launchers_.end(), + AppLauncherFinder(app_data)); + if (it != works_launchers_.end()) { + LauncherPtr launcher = *it; + launcher->Clear(); + free_launchers_.push_back(launcher); + works_launchers_.erase(it); + } else { + LOG4CXX_DEBUG(logger_, + "Unable to StopLaunching" << app_data->mobile_app_id_); + } +} + +void AppsLauncher::OnLaunched(ApplicationDataPtr app_data) { + LOG4CXX_AUTO_TRACE(logger_); + StopLaunching(app_data); +} + +void AppsLauncher::OnRetryAttemptsExhausted(ApplicationDataPtr app_data) { + LOG4CXX_AUTO_TRACE(logger_); + StopLaunching(app_data); +} + +AppsLauncher::Launcher::Launcher( + AppsLauncher& parent, + connection_handler::ConnectionHandler& connection_handler, + const uint16_t app_launch_max_retry_attempt, + const uint16_t app_launch_retry_wait_time) + : retry_timer_( + "AppsLauncherTimer", + new timer::TimerTaskImpl<Launcher>(this, &Launcher::LaunchNow)) + , app_launch_max_retry_attempt_(app_launch_max_retry_attempt) + , app_launch_retry_wait_time_(app_launch_retry_wait_time) + , connection_handler_(connection_handler) + , parent_(parent) {} + +void AppsLauncher::Launcher::PosponedLaunch( + const app_launch::ApplicationDataPtr& app_data) { + DCHECK(!app_data_); + app_data_ = app_data; + retry_index_ = 0; + retry_timer_.Start(app_launch_retry_wait_time_, timer::kPeriodic); + LOG4CXX_DEBUG(logger_, + "Applicaiton " << app_data->mobile_app_id_ << " on device " + << app_data->device_mac_ + << " will be launched in " + << app_launch_retry_wait_time_ << " ms"); +} + +void AppsLauncher::Launcher::Clear() { + retry_timer_.Stop(); + app_data_.reset(); + retry_index_ = 0; +} + +void AppsLauncher::Launcher::LaunchNow() { + if (retry_index_++ < app_launch_max_retry_attempt_) { + LOG4CXX_DEBUG(logger_, + "Run App " << app_data_->mobile_app_id_ << "with bundle " + << app_data_->bundle_id_ << " On Device " + << app_data_->device_mac_); + + connection_handler_.RunAppOnDevice(app_data_->device_mac_, + app_data_->bundle_id_); + } else { + parent_.OnRetryAttemptsExhausted(app_data_); + } +} + +} // namespace app_launch diff --git a/src/components/application_manager/src/app_launch/device_apps_launcher.cc b/src/components/application_manager/src/app_launch/device_apps_launcher.cc new file mode 100644 index 0000000000..0eb9245cf8 --- /dev/null +++ b/src/components/application_manager/src/app_launch/device_apps_launcher.cc @@ -0,0 +1,208 @@ +#include <string> +#include <vector> +#include <algorithm> + +#include "application_manager/app_launch/device_apps_launcher.h" +#include "application_manager/app_launch/app_launch_data.h" +#include "application_manager/app_launch/apps_launcher.h" +#include "application_manager/resumption/resume_ctrl.h" +#include "utils/shared_ptr.h" +#include "utils/make_shared.h" +#include "utils/timer.h" +#include "utils/timer_task_impl.h" +#include <iostream> + +namespace app_launch { +CREATE_LOGGERPTR_GLOBAL(logger_, "AppLaunch") + +typedef std::pair<std::string, std::vector<ApplicationDataPtr> > AppsOnDevice; +typedef utils::SharedPtr<AppsOnDevice> AppsOnDevicePtr; + +class Launcher { + public: + Launcher(const resumption::ResumeCtrl& resume_ctrl, + DeviceAppsLauncher& device_launcher, + AppsLauncher& apps_launcher) + : device_launcher_(device_launcher) + , apps_launcher_(apps_launcher) + , resume_ctrl_(resume_ctrl) + , gap_between_app_timer_("GapBetweenLaunchTimer", + new timer::TimerTaskImpl<Launcher>( + this, &Launcher::OnGapBetweenLaunchExpired)) + , wait_before_launch_timer_( + "WaitBeforeLainchTimer", + new timer::TimerTaskImpl<Launcher>(this, &Launcher::LaunchNext)) {} + + void Start(const AppsOnDevicePtr& apps_on_device) { + DCHECK(!apps_on_device_); + apps_on_device_ = apps_on_device; + const time_t curr_time = time(NULL); + const time_t sdl_launch_time = resume_ctrl_.LaunchTime(); + const double seconds_from_sdl_start = difftime(curr_time, sdl_launch_time); + const uint32_t wait_time = + device_launcher_.settings().resumption_delay_after_ign(); + const uint32_t wait_before_launch_timeout = + seconds_from_sdl_start < wait_time + ? wait_time - seconds_from_sdl_start + : device_launcher_.settings().app_launch_wait_time(); + wait_before_launch_timer_.Start(wait_before_launch_timeout, + timer::kSingleShot); + } + + void LaunchNext() { + std::vector<ApplicationDataPtr>& apps = apps_on_device_->second; + std::vector<ApplicationDataPtr>::iterator it = apps.begin(); + if (it != apps.end()) { + apps_launcher_.StartLaunching(*it); + apps.erase(it); + gap_between_app_timer_.Start( + device_launcher_.settings().wait_time_between_apps(), + timer::kSingleShot); + } else { + LOG4CXX_DEBUG(logger_, + "All Apps on " << apps_on_device_->first + << " posponed launched"); + device_launcher_.StopLaunchingAppsOnDevice(apps_on_device_->first); + } + } + + void OnGapBetweenLaunchExpired() { + LaunchNext(); + } + + void OnAppRegistered(const ApplicationDataPtr& app_data) { + std::vector<ApplicationDataPtr>& apps = apps_on_device_->second; + std::vector<ApplicationDataPtr>::iterator it = + std::find(apps.begin(), apps.end(), app_data); + if (it != apps.end()) { + apps.erase(it); + } + } + + void Clear() { + gap_between_app_timer_.Stop(); + wait_before_launch_timer_.Stop(); + apps_on_device_.reset(); + } + + DeviceAppsLauncher& device_launcher_; + AppsLauncher& apps_launcher_; + const resumption::ResumeCtrl& resume_ctrl_; + + timer::Timer gap_between_app_timer_; + timer::Timer wait_before_launch_timer_; + + AppsOnDevicePtr apps_on_device_; +}; + +typedef utils::SharedPtr<Launcher> LauncherPtr; +typedef std::vector<LauncherPtr> Launchers; + +struct LauncherGenerator { + LauncherGenerator(resumption::ResumeCtrl& resume_ctrl, + DeviceAppsLauncher& interface, + AppsLauncher& apps_launcher) + : resume_ctrl_(resume_ctrl) + , interface_(interface) + , apps_launcher_(apps_launcher) {} + + LauncherPtr operator()() const { + return utils::MakeShared<Launcher>( + resume_ctrl_, interface_, apps_launcher_); + } + + resumption::ResumeCtrl& resume_ctrl_; + DeviceAppsLauncher& interface_; + AppsLauncher& apps_launcher_; +}; + +class DeviceAppsLauncherImpl { + public: + DeviceAppsLauncherImpl(DeviceAppsLauncher& interface, + AppsLauncher& apps_launcher) + : interface_(interface) { + sync_primitives::AutoLock lock(launchers_lock_); + LauncherGenerator generate( + interface.app_mngr_.resume_controller(), interface, apps_launcher); + free_launchers_.reserve(interface.settings_.max_number_of_ios_device()); + std::generate_n(std::back_inserter(free_launchers_), + interface.settings_.max_number_of_ios_device(), + generate); + } + + bool LaunchAppsOnDevice( + const std::string& device_mac, + const std::vector<ApplicationDataPtr>& applications_to_launch) { + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_DEBUG(logger_, + "On Device " << device_mac << " will be launched " + << applications_to_launch.size() << " apps"); + AppsOnDevicePtr apps_on_device = + utils::MakeShared<AppsOnDevice>(device_mac, applications_to_launch); + sync_primitives::AutoLock lock(launchers_lock_); + DCHECK_OR_RETURN(!free_launchers_.empty(), false) + const Launchers::iterator it = free_launchers_.begin(); + LauncherPtr launcher = *it; + works_launchers_.push_back(launcher); + free_launchers_.erase(it); + launcher->Start(apps_on_device); + return true; + } + + struct LauncherFinder { + LauncherFinder(const std::string& device_mac) : device_mac_(device_mac) {} + + bool operator()(const LauncherPtr& launcher) const { + return device_mac_ == launcher->apps_on_device_->first; + } + + std::string device_mac_; + }; + + bool StopLaunchingAppsOnDevice(const std::string& device_mac) { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(launchers_lock_); + const Launchers::iterator it = std::find_if(works_launchers_.begin(), + works_launchers_.end(), + LauncherFinder(device_mac)); + if (it == works_launchers_.end()) { + return false; + } + LauncherPtr launcher = *it; + launcher->Clear(); + free_launchers_.push_back(launcher); + works_launchers_.erase(it); + return true; + } + + private: + sync_primitives::Lock launchers_lock_; + Launchers free_launchers_; + Launchers works_launchers_; + DeviceAppsLauncher& interface_; +}; + +bool DeviceAppsLauncher::LaunchAppsOnDevice( + const std::string& device_mac, + const std::vector<ApplicationDataPtr>& applications_to_launch) { + return impl_->LaunchAppsOnDevice(device_mac, applications_to_launch); +} + +DeviceAppsLauncher::DeviceAppsLauncher( + application_manager::ApplicationManager& app_mngr, + app_launch::AppsLauncher& apps_launcher, + const AppLaunchSettings& settings) + : app_mngr_(app_mngr) + , settings_(settings) + , impl_(new DeviceAppsLauncherImpl(*this, apps_launcher)) {} + +bool DeviceAppsLauncher::StopLaunchingAppsOnDevice( + const std::string& device_mac) { + return impl_->StopLaunchingAppsOnDevice(device_mac); +} + +const AppLaunchSettings& DeviceAppsLauncher::settings() const { + return settings_; +} + +} // namespace app_launch diff --git a/src/components/application_manager/src/application_impl.cc b/src/components/application_manager/src/application_impl.cc index 61451e3602..a159a7c676 100644 --- a/src/components/application_manager/src/application_impl.cc +++ b/src/components/application_manager/src/application_impl.cc @@ -318,6 +318,10 @@ const std::string& ApplicationImpl::app_icon_path() const { return app_icon_path_; } +const std::string& ApplicationImpl::bundle_id() const { + return bundle_id_; +} + connection_handler::DeviceHandle ApplicationImpl::device() const { return device_; } @@ -489,7 +493,8 @@ void ApplicationImpl::WakeUpStreaming( ServiceType::kMobileNav, true, application_manager_); video_streaming_suspended_ = false; } - video_stream_suspend_timer_.Start(video_stream_suspend_timeout_, false); + video_stream_suspend_timer_.Start(video_stream_suspend_timeout_, + timer::kPeriodic); } else if (ServiceType::kAudio == service_type) { sync_primitives::AutoLock lock(audio_streaming_suspended_lock_); if (audio_streaming_suspended_) { @@ -498,7 +503,8 @@ void ApplicationImpl::WakeUpStreaming( ServiceType::kAudio, true, application_manager_); audio_streaming_suspended_ = false; } - audio_stream_suspend_timer_.Start(audio_stream_suspend_timeout_, false); + audio_stream_suspend_timer_.Start(audio_stream_suspend_timeout_, + timer::kPeriodic); } } @@ -570,6 +576,10 @@ void ApplicationImpl::set_grammar_id(uint32_t value) { grammar_id_ = value; } +void ApplicationImpl::set_bundle_id(const std::string& bundle_id) { + bundle_id_ = bundle_id; +} + void ApplicationImpl::ResetDataInNone() { put_file_in_none_count_ = 0; delete_file_in_none_count_ = 0; diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 249fd04def..7c1efc9d1b 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -44,6 +44,11 @@ #include "application_manager/message_helper.h" #include "application_manager/mobile_message_handler.h" #include "application_manager/policies/policy_handler.h" +#include "application_manager/hmi_capabilities_impl.h" +#include "application_manager/resumption/resume_ctrl_impl.h" +#include "application_manager/app_launch/app_launch_ctrl_impl.h" +#include "application_manager/app_launch/app_launch_data_db.h" +#include "application_manager/app_launch/app_launch_data_json.h" #include "protocol_handler/protocol_handler.h" #include "hmi_message_handler/hmi_message_handler.h" #include "connection_handler/connection_handler_impl.h" @@ -114,10 +119,10 @@ ApplicationManagerImpl::ApplicationManagerImpl( , messages_from_hmi_("AM FromHMI", this) , messages_to_hmi_("AM ToHMI", this) , audio_pass_thru_messages_("AudioPassThru", this) - , hmi_capabilities_(*this) + , hmi_capabilities_(new HMICapabilitiesImpl(*this)) , unregister_reason_( mobile_api::AppInterfaceUnregisteredReason::INVALID_ENUM) - , resume_ctrl_(*this) + , resume_ctrl_(new resumption::ResumeCtrlImpl(*this)) , navi_close_app_timeout_(am_settings.stop_streaming_timeout()) , navi_end_stream_timeout_(am_settings.stop_streaming_timeout()) , stopping_application_mng_lock_(true) @@ -148,7 +153,7 @@ ApplicationManagerImpl::ApplicationManagerImpl( new TimerTaskImpl<ApplicationManagerImpl>( this, &ApplicationManagerImpl::ClearTimerPool))); const uint32_t timeout_ms = 10000u; - clearing_timer->Start(timeout_ms, false); + clearing_timer->Start(timeout_ms, timer::kSingleShot); timer_pool_.push_back(clearing_timer); } @@ -427,7 +432,7 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication( LOG4CXX_DEBUG(logger_, "Restarting application list update timer"); GetPolicyHandler().OnAppsSearchStarted(); uint32_t timeout = get_settings().application_list_update_timeout(); - application_list_update_timer_.Start(timeout, true); + application_list_update_timer_.Start(timeout, timer::kSingleShot); if (!is_all_apps_allowed_) { LOG4CXX_WARN(logger_, @@ -534,16 +539,23 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication( if (!application->hmi_app_id()) { const bool is_saved = - resume_ctrl_.IsApplicationSaved(policy_app_id, device_mac); + resume_controller().IsApplicationSaved(policy_app_id, device_mac); application->set_hmi_application_id( - is_saved ? resume_ctrl_.GetHMIApplicationID(policy_app_id, device_mac) - : GenerateNewHMIAppID()); + is_saved + ? resume_controller().GetHMIApplicationID(policy_app_id, device_mac) + : GenerateNewHMIAppID()); } + if (params.keyExists(strings::app_info)) { + const smart_objects::SmartObject& app_info = params[strings::app_info]; + const std::string& bundle_id = app_info[strings::bundle_id].asString(); + application->set_bundle_id(bundle_id); + } // Stops timer of saving data to resumption in order to // doesn't erase data from resumption storage. // Timer will be started after hmi level resumption. - resume_ctrl_.OnAppRegistrationStart(policy_app_id, device_mac); + resume_controller().OnAppRegistrationStart(policy_app_id, device_mac); + // Add application to registered app list and set appropriate mark. // Lock has to be released before adding app to policy DB to avoid possible // deadlock with simultaneous PTU processing @@ -913,6 +925,7 @@ void ApplicationManagerImpl::OnDeviceListUpdated( GetPolicyHandler().AddDevice(dev_params.device_mac_address, device_info.connection_type); + app_launch_ctrl().OnDeviceConnected(dev_params.device_mac_address); } smart_objects::SmartObjectSPtr msg_params = @@ -939,7 +952,7 @@ void ApplicationManagerImpl::OnFindNewApplicationsRequest() { connection_handler().ConnectToAllDevices(); LOG4CXX_DEBUG(logger_, "Starting application list update timer"); uint32_t timeout = get_settings().application_list_update_timeout(); - application_list_update_timer_.Start(timeout, true); + application_list_update_timer_.Start(timeout, timer::kSingleShot); GetPolicyHandler().OnAppsSearchStarted(); } @@ -1009,7 +1022,7 @@ uint32_t ApplicationManagerImpl::GenerateNewHMIAppID() { uint32_t hmi_app_id = get_rand_from_range(1); LOG4CXX_DEBUG(logger_, "GenerateNewHMIAppID value is: " << hmi_app_id); - while (resume_ctrl_.IsHMIApplicationIdExist(hmi_app_id)) { + while (resume_controller().IsHMIApplicationIdExist(hmi_app_id)) { LOG4CXX_DEBUG(logger_, "HMI appID " << hmi_app_id << " is exists."); hmi_app_id = get_rand_from_range(1); LOG4CXX_DEBUG(logger_, "Trying new value: " << hmi_app_id); @@ -1696,11 +1709,11 @@ bool ApplicationManagerImpl::Init(resumption::LastState& last_state, !IsReadWriteAllowed(app_storage_folder, TYPE_STORAGE)) { return false; } - if (!resume_ctrl_.Init(last_state)) { + if (!resume_controller().Init(last_state)) { LOG4CXX_ERROR(logger_, "Problem with initialization of resume controller"); return false; } - hmi_capabilities_.Init(&last_state); + hmi_capabilities_->Init(&last_state); if (!(file_system::IsWritingAllowed(app_storage_folder) && file_system::IsReadingAllowed(app_storage_folder))) { @@ -1737,6 +1750,16 @@ bool ApplicationManagerImpl::Init(resumption::LastState& last_state, "System is configured to work without policy functionality."); } media_manager_ = media_manager; + + if (settings_.use_db_for_resumption()) { + app_launch_dto_.reset(new app_launch::AppLaunchDataDB(settings_)); + } else { + app_launch_dto_.reset( + new app_launch::AppLaunchDataJson(settings_, last_state)); + } + app_launch_ctrl_.reset(new app_launch::AppLaunchCtrlImpl( + *app_launch_dto_.get(), *this, settings_)); + return true; } @@ -2122,11 +2145,11 @@ mobile_apis::MOBILE_API& ApplicationManagerImpl::mobile_so_factory() { } HMICapabilities& ApplicationManagerImpl::hmi_capabilities() { - return hmi_capabilities_; + return *hmi_capabilities_; } const HMICapabilities& ApplicationManagerImpl::hmi_capabilities() const { - return hmi_capabilities_; + return *hmi_capabilities_; } void ApplicationManagerImpl::PullLanguagesInfo(const SmartObject& app_data, @@ -2257,8 +2280,8 @@ void ApplicationManagerImpl::CreateApplications(SmartArray& obj_array, device_id, NULL, NULL, &device_mac, NULL); const uint32_t hmi_app_id = - resume_ctrl_.IsApplicationSaved(policy_app_id, device_mac) - ? resume_ctrl_.GetHMIApplicationID(policy_app_id, device_mac) + resume_controller().IsApplicationSaved(policy_app_id, device_mac) + ? resume_controller().GetHMIApplicationID(policy_app_id, device_mac) : GenerateNewHMIAppID(); // AppId = 0 because this is query_app(provided by hmi for download, but not @@ -2603,12 +2626,12 @@ void ApplicationManagerImpl::UnregisterApplication( return; } if (is_resuming) { - resume_ctrl_.SaveApplication(app_to_remove); + resume_controller().SaveApplication(app_to_remove); } else { - resume_ctrl_.RemoveApplicationFromSaved(app_to_remove); + resume_controller().RemoveApplicationFromSaved(app_to_remove); } applications_.erase(app_to_remove); - (hmi_capabilities_.get_hmi_language_handler()) + (hmi_capabilities_->get_hmi_language_handler()) .OnUnregisterApplication(app_id); AppV4DevicePredicate finder(handle); ApplicationSharedPtr app = FindApp(accessor, finder); @@ -2971,7 +2994,7 @@ void ApplicationManagerImpl::EndNaviServices(uint32_t app_id) { "CloseNaviAppTimer", new TimerTaskImpl<ApplicationManagerImpl>( this, &ApplicationManagerImpl::CloseNaviApp))); - close_timer->Start(navi_close_app_timeout_, true); + close_timer->Start(navi_close_app_timeout_, timer::kPeriodic); sync_primitives::AutoLock lock(timer_pool_lock_); timer_pool_.push_back(close_timer); @@ -3012,7 +3035,7 @@ void ApplicationManagerImpl::OnHMILevelChanged( "AppShouldFinishStreaming", new TimerTaskImpl<ApplicationManagerImpl>( this, &ApplicationManagerImpl::EndNaviStreaming))); - end_stream_timer->Start(navi_end_stream_timeout_, true); + end_stream_timer->Start(navi_end_stream_timeout_, timer::kPeriodic); sync_primitives::AutoLock lock(timer_pool_lock_); timer_pool_.push_back(end_stream_timer); @@ -3298,7 +3321,7 @@ void ApplicationManagerImpl::AddAppToTTSGlobalPropertiesList( LOG4CXX_INFO(logger_, "Start tts_global_properties_timer_"); tts_global_properties_app_list_lock_.Release(); const uint32_t timeout_ms = 1000; - tts_global_properties_timer_.Start(timeout_ms, false); + tts_global_properties_timer_.Start(timeout_ms, timer::kSingleShot); return; } tts_global_properties_app_list_lock_.Release(); @@ -3459,6 +3482,10 @@ event_engine::EventDispatcher& ApplicationManagerImpl::event_dispatcher() { return event_dispatcher_; } +app_launch::AppLaunchCtrl& ApplicationManagerImpl::app_launch_ctrl() { + return *app_launch_ctrl_; +} + const std::string ApplicationManagerImpl::DirectoryTypeToString( ApplicationManagerImpl::DirectoryType type) const { DirectoryTypeMap::const_iterator it = dir_type_to_string_map_.find(type); diff --git a/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc b/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc index 412827f7c8..2c53fc0db2 100644 --- a/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc +++ b/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc @@ -41,6 +41,7 @@ #include "application_manager/application_manager.h" #include "application_manager/policies/policy_handler_interface.h" #include "application_manager/application_impl.h" +#include "application_manager/app_launch/app_launch_ctrl.h" #include "application_manager/message_helper.h" #include "application_manager/resumption/resume_ctrl.h" #include "interfaces/MOBILE_API.h" @@ -538,6 +539,25 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile() { application->mac_address()); } + hmi_apis::Common_SpeechCapabilities::eType tts_name_type = + hmi_apis::Common_SpeechCapabilities::INVALID_ENUM; + if ((*message_)[strings::msg_params].keyExists(strings::tts_name)) { + tts_name_type = static_cast<hmi_apis::Common_SpeechCapabilities::eType>( + (*message_)[strings::msg_params][strings::tts_name][0][strings::type] + .asInt()); + } + + if (hmi_apis::Common_SpeechCapabilities::SAPI_PHONEMES == tts_name_type || + hmi_apis::Common_SpeechCapabilities::LHPLUS_PHONEMES == tts_name_type || + hmi_apis::Common_SpeechCapabilities::PRE_RECORDED == tts_name_type || + hmi_apis::Common_SpeechCapabilities::SILENCE == tts_name_type) { + result_code = mobile_apis::Result::WARNINGS; + add_info = "ttsChunks is sent but is not supported"; + } + + app_launch::AppLaunchCtrl& app_launch_ctrl = + application_manager_.app_launch_ctrl(); + app_launch_ctrl.OnAppRegistered(*application); SendOnAppRegisteredNotificationToHMI( *(application.get()), resumption, need_restore_vr); SendResponse(true, result_code, add_info.c_str(), &response_params); diff --git a/src/components/application_manager/src/hmi_capabilities.cc b/src/components/application_manager/src/hmi_capabilities_impl.cc index 7535984c16..07b691f889 100644 --- a/src/components/application_manager/src/hmi_capabilities.cc +++ b/src/components/application_manager/src/hmi_capabilities_impl.cc @@ -30,181 +30,295 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "application_manager/hmi_capabilities.h" - #include <map> -#include "json/json.h" -#include "utils/file_system.h" -#include "interfaces/HMI_API.h" +#include "utils/logger.h" +#include "application_manager/hmi_capabilities_impl.h" +#include "application_manager/application_manager_impl.h" #include "smart_objects/smart_object.h" -#include "application_manager/smart_object_keys.h" #include "application_manager/message_helper.h" #include "application_manager/smart_object_keys.h" -#include "application_manager/application_manager.h" -#include "application_manager/message_helper.h" +#include "config_profile/profile.h" #include "formatters/CFormatterJsonBase.h" - -CREATE_LOGGERPTR_GLOBAL(logger_, "ApplicationManager") +#include "interfaces/HMI_API.h" +#include "utils/file_system.h" namespace application_manager { namespace Formatters = NsSmartDeviceLink::NsJSONHandler::Formatters; +namespace { std::map<std::string, hmi_apis::Common_VrCapabilities::eType> - vr_enum_capabilities = {{"TEXT", hmi_apis::Common_VrCapabilities::VR_TEXT}}; - -std::map<std::string, hmi_apis::Common_ButtonName::eType> button_enum_name = { - {"OK", hmi_apis::Common_ButtonName::OK}, - {"SEEKLEFT", hmi_apis::Common_ButtonName::SEEKLEFT}, - {"SEEKRIGHT", hmi_apis::Common_ButtonName::SEEKRIGHT}, - {"TUNEUP", hmi_apis::Common_ButtonName::TUNEUP}, - {"TUNEDOWN", hmi_apis::Common_ButtonName::TUNEDOWN}, - {"PRESET_0", hmi_apis::Common_ButtonName::PRESET_0}, - {"PRESET_1", hmi_apis::Common_ButtonName::PRESET_1}, - {"PRESET_2", hmi_apis::Common_ButtonName::PRESET_2}, - {"PRESET_3", hmi_apis::Common_ButtonName::PRESET_3}, - {"PRESET_4", hmi_apis::Common_ButtonName::PRESET_4}, - {"PRESET_5", hmi_apis::Common_ButtonName::PRESET_5}, - {"PRESET_6", hmi_apis::Common_ButtonName::PRESET_6}, - {"PRESET_7", hmi_apis::Common_ButtonName::PRESET_7}, - {"PRESET_8", hmi_apis::Common_ButtonName::PRESET_8}, - {"PRESET_9", hmi_apis::Common_ButtonName::PRESET_9}, - {"CUSTOM_BUTTON", hmi_apis::Common_ButtonName::CUSTOM_BUTTON}, - {"SEARCH", hmi_apis::Common_ButtonName::SEARCH}, - -}; - -std::map<std::string, - hmi_apis::Common_TextFieldName::eType> text_fields_enum_name = { - {"mainField1", hmi_apis::Common_TextFieldName::mainField1}, - {"mainField2", hmi_apis::Common_TextFieldName::mainField2}, - {"mainField3", hmi_apis::Common_TextFieldName::mainField3}, - {"mainField4", hmi_apis::Common_TextFieldName::mainField4}, - {"statusBar", hmi_apis::Common_TextFieldName::statusBar}, - {"mediaClock", hmi_apis::Common_TextFieldName::mediaClock}, - {"mediaTrack", hmi_apis::Common_TextFieldName::mediaTrack}, - {"alertText1", hmi_apis::Common_TextFieldName::alertText1}, - {"alertText2", hmi_apis::Common_TextFieldName::alertText2}, - {"alertText3", hmi_apis::Common_TextFieldName::alertText3}, - {"scrollableMessageBody", - hmi_apis::Common_TextFieldName::scrollableMessageBody}, - {"initialInteractionText", - hmi_apis::Common_TextFieldName::initialInteractionText}, - {"navigationText1", hmi_apis::Common_TextFieldName::navigationText1}, - {"navigationText2", hmi_apis::Common_TextFieldName::navigationText2}, - {"ETA", hmi_apis::Common_TextFieldName::ETA}, - {"totalDistance", hmi_apis::Common_TextFieldName::totalDistance}, - {"audioPassThruDisplayText1", - hmi_apis::Common_TextFieldName::audioPassThruDisplayText1}, - {"audioPassThruDisplayText2", - hmi_apis::Common_TextFieldName::audioPassThruDisplayText2}, - {"sliderHeader", hmi_apis::Common_TextFieldName::sliderHeader}, - {"sliderFooter", hmi_apis::Common_TextFieldName::sliderFooter}, - {"notificationText", hmi_apis::Common_TextFieldName::notificationText}, - {"menuName", hmi_apis::Common_TextFieldName::menuName}, - {"secondaryText", hmi_apis::Common_TextFieldName::secondaryText}, - {"tertiaryText", hmi_apis::Common_TextFieldName::tertiaryText}, - {"timeToDestination", hmi_apis::Common_TextFieldName::timeToDestination}, - {"locationName", hmi_apis::Common_TextFieldName::locationName}, - {"locationDescription", - hmi_apis::Common_TextFieldName::locationDescription}, - {"addressLines", hmi_apis::Common_TextFieldName::turnText}, - {"turnText", hmi_apis::Common_TextFieldName::addressLines}, - {"phoneNumber", hmi_apis::Common_TextFieldName::phoneNumber}, - {"turnText", hmi_apis::Common_TextFieldName::turnText}, - {"menuTitle", hmi_apis::Common_TextFieldName::menuTitle}, - {"navigationText", hmi_apis::Common_TextFieldName::navigationText}, -}; - + vr_enum_capabilities; +std::map<std::string, hmi_apis::Common_ButtonName::eType> button_enum_name; +std::map<std::string, hmi_apis::Common_TextFieldName::eType> + text_fields_enum_name; std::map<std::string, hmi_apis::Common_MediaClockFormat::eType> - media_clock_enum_name = { - {"CLOCK1", hmi_apis::Common_MediaClockFormat::CLOCK1}, - {"CLOCK2", hmi_apis::Common_MediaClockFormat::CLOCK2}, - {"CLOCK3", hmi_apis::Common_MediaClockFormat::CLOCK3}, - {"CLOCKTEXT1", hmi_apis::Common_MediaClockFormat::CLOCKTEXT1}, - {"CLOCKTEXT2", hmi_apis::Common_MediaClockFormat::CLOCKTEXT2}, - {"CLOCKTEXT3", hmi_apis::Common_MediaClockFormat::CLOCKTEXT3}, - {"CLOCKTEXT4", hmi_apis::Common_MediaClockFormat::CLOCKTEXT4}, -}; - -std::map<std::string, hmi_apis::Common_ImageType::eType> image_type_enum = { - {"STATIC", hmi_apis::Common_ImageType::STATIC}, - {"DYNAMIC", hmi_apis::Common_ImageType::DYNAMIC}}; - -std::map<std::string, hmi_apis::Common_SamplingRate::eType> sampling_rate_enum = - {{"RATE_8KHZ", hmi_apis::Common_SamplingRate::RATE_8KHZ}, - {"8KHZ", hmi_apis::Common_SamplingRate::RATE_8KHZ}, - {"RATE_16KHZ", hmi_apis::Common_SamplingRate::RATE_16KHZ}, - {"16KHZ", hmi_apis::Common_SamplingRate::RATE_16KHZ}, - {"RATE_22KHZ", hmi_apis::Common_SamplingRate::RATE_22KHZ}, - {"22KHZ", hmi_apis::Common_SamplingRate::RATE_22KHZ}, - {"RATE_44KHZ", hmi_apis::Common_SamplingRate::RATE_44KHZ}, - {"44KHZ", hmi_apis::Common_SamplingRate::RATE_44KHZ}}; - + media_clock_enum_name; +std::map<std::string, hmi_apis::Common_ImageType::eType> image_type_enum; +std::map<std::string, hmi_apis::Common_SamplingRate::eType> sampling_rate_enum; std::map<std::string, hmi_apis::Common_BitsPerSample::eType> - bit_per_sample_enum = { - {"RATE_8_BIT", hmi_apis::Common_BitsPerSample::RATE_8_BIT}, - {"8_BIT", hmi_apis::Common_BitsPerSample::RATE_8_BIT}, - {"RATE_16_BIT", hmi_apis::Common_BitsPerSample::RATE_16_BIT}, - {"16_BIT", hmi_apis::Common_BitsPerSample::RATE_16_BIT}}; + bit_per_sample_enum; +std::map<std::string, hmi_apis::Common_AudioType::eType> audio_type_enum; +std::map<std::string, hmi_apis::Common_HmiZoneCapabilities::eType> + hmi_zone_enum; +std::map<std::string, hmi_apis::Common_ImageFieldName::eType> + image_field_name_enum; +std::map<std::string, hmi_apis::Common_FileType::eType> file_type_enum; +std::map<std::string, hmi_apis::Common_DisplayType::eType> display_type_enum; +std::map<std::string, hmi_apis::Common_CharacterSet::eType> character_set_enum; + +void InitCapabilities() { + vr_enum_capabilities.insert(std::make_pair( + std::string("TEXT"), hmi_apis::Common_VrCapabilities::VR_TEXT)); + + button_enum_name.insert( + std::make_pair(std::string("OK"), hmi_apis::Common_ButtonName::OK)); + button_enum_name.insert(std::make_pair( + std::string("SEEKLEFT"), hmi_apis::Common_ButtonName::SEEKLEFT)); + button_enum_name.insert(std::make_pair( + std::string("SEEKRIGHT"), hmi_apis::Common_ButtonName::SEEKRIGHT)); + button_enum_name.insert(std::make_pair(std::string("TUNEUP"), + hmi_apis::Common_ButtonName::TUNEUP)); + button_enum_name.insert(std::make_pair( + std::string("TUNEDOWN"), hmi_apis::Common_ButtonName::TUNEDOWN)); + button_enum_name.insert(std::make_pair( + std::string("PRESET_0"), hmi_apis::Common_ButtonName::PRESET_0)); + button_enum_name.insert(std::make_pair( + std::string("PRESET_1"), hmi_apis::Common_ButtonName::PRESET_1)); + button_enum_name.insert(std::make_pair( + std::string("PRESET_2"), hmi_apis::Common_ButtonName::PRESET_2)); + button_enum_name.insert(std::make_pair( + std::string("PRESET_3"), hmi_apis::Common_ButtonName::PRESET_3)); + button_enum_name.insert(std::make_pair( + std::string("PRESET_4"), hmi_apis::Common_ButtonName::PRESET_4)); + button_enum_name.insert(std::make_pair( + std::string("PRESET_5"), hmi_apis::Common_ButtonName::PRESET_5)); + button_enum_name.insert(std::make_pair( + std::string("PRESET_6"), hmi_apis::Common_ButtonName::PRESET_6)); + button_enum_name.insert(std::make_pair( + std::string("PRESET_7"), hmi_apis::Common_ButtonName::PRESET_7)); + button_enum_name.insert(std::make_pair( + std::string("PRESET_8"), hmi_apis::Common_ButtonName::PRESET_8)); + button_enum_name.insert(std::make_pair( + std::string("PRESET_9"), hmi_apis::Common_ButtonName::PRESET_9)); + button_enum_name.insert( + std::make_pair(std::string("CUSTOM_BUTTON"), + hmi_apis::Common_ButtonName::CUSTOM_BUTTON)); + button_enum_name.insert(std::make_pair(std::string("SEARCH"), + hmi_apis::Common_ButtonName::SEARCH)); + + text_fields_enum_name.insert(std::make_pair( + std::string("mainField1"), hmi_apis::Common_TextFieldName::mainField1)); + text_fields_enum_name.insert(std::make_pair( + std::string("mainField2"), hmi_apis::Common_TextFieldName::mainField2)); + text_fields_enum_name.insert(std::make_pair( + std::string("mainField3"), hmi_apis::Common_TextFieldName::mainField3)); + text_fields_enum_name.insert(std::make_pair( + std::string("mainField4"), hmi_apis::Common_TextFieldName::mainField4)); + text_fields_enum_name.insert(std::make_pair( + std::string("statusBar"), hmi_apis::Common_TextFieldName::statusBar)); + text_fields_enum_name.insert(std::make_pair( + std::string("mediaClock"), hmi_apis::Common_TextFieldName::mediaClock)); + text_fields_enum_name.insert(std::make_pair( + std::string("mediaTrack"), hmi_apis::Common_TextFieldName::mediaTrack)); + text_fields_enum_name.insert(std::make_pair( + std::string("alertText1"), hmi_apis::Common_TextFieldName::alertText1)); + text_fields_enum_name.insert(std::make_pair( + std::string("alertText2"), hmi_apis::Common_TextFieldName::alertText2)); + text_fields_enum_name.insert(std::make_pair( + std::string("alertText3"), hmi_apis::Common_TextFieldName::alertText3)); + text_fields_enum_name.insert( + std::make_pair(std::string("scrollableMessageBody"), + hmi_apis::Common_TextFieldName::scrollableMessageBody)); + text_fields_enum_name.insert( + std::make_pair(std::string("initialInteractionText"), + hmi_apis::Common_TextFieldName::initialInteractionText)); + text_fields_enum_name.insert( + std::make_pair(std::string("navigationText1"), + hmi_apis::Common_TextFieldName::navigationText1)); + text_fields_enum_name.insert( + std::make_pair(std::string("navigationText2"), + hmi_apis::Common_TextFieldName::navigationText2)); + text_fields_enum_name.insert( + std::make_pair(std::string("ETA"), hmi_apis::Common_TextFieldName::ETA)); + text_fields_enum_name.insert( + std::make_pair(std::string("totalDistance"), + hmi_apis::Common_TextFieldName::totalDistance)); + text_fields_enum_name.insert(std::make_pair( + std::string("audioPassThruDisplayText1"), + hmi_apis::Common_TextFieldName::audioPassThruDisplayText1)); + text_fields_enum_name.insert(std::make_pair( + std::string("audioPassThruDisplayText2"), + hmi_apis::Common_TextFieldName::audioPassThruDisplayText2)); + text_fields_enum_name.insert( + std::make_pair(std::string("sliderHeader"), + hmi_apis::Common_TextFieldName::sliderHeader)); + text_fields_enum_name.insert( + std::make_pair(std::string("sliderFooter"), + hmi_apis::Common_TextFieldName::sliderFooter)); + text_fields_enum_name.insert( + std::make_pair(std::string("navigationText"), + hmi_apis::Common_TextFieldName::navigationText)); + text_fields_enum_name.insert( + std::make_pair(std::string("notificationText"), + hmi_apis::Common_TextFieldName::notificationText)); + text_fields_enum_name.insert(std::make_pair( + std::string("menuName"), hmi_apis::Common_TextFieldName::menuName)); + text_fields_enum_name.insert( + std::make_pair(std::string("secondaryText"), + hmi_apis::Common_TextFieldName::secondaryText)); + text_fields_enum_name.insert( + std::make_pair(std::string("tertiaryText"), + hmi_apis::Common_TextFieldName::tertiaryText)); + text_fields_enum_name.insert( + std::make_pair(std::string("timeToDestination"), + hmi_apis::Common_TextFieldName::timeToDestination)); + text_fields_enum_name.insert( + std::make_pair(std::string("locationName"), + hmi_apis::Common_TextFieldName::locationName)); + text_fields_enum_name.insert( + std::make_pair(std::string("locationDescription"), + hmi_apis::Common_TextFieldName::locationDescription)); + text_fields_enum_name.insert(std::make_pair( + std::string("turnText"), hmi_apis::Common_TextFieldName::turnText)); + text_fields_enum_name.insert( + std::make_pair(std::string("addressLines"), + hmi_apis::Common_TextFieldName::addressLines)); + text_fields_enum_name.insert(std::make_pair( + std::string("phoneNumber"), hmi_apis::Common_TextFieldName::phoneNumber)); + text_fields_enum_name.insert(std::make_pair( + std::string("turnText"), hmi_apis::Common_TextFieldName::turnText)); + text_fields_enum_name.insert(std::make_pair( + std::string("menuTitle"), hmi_apis::Common_TextFieldName::menuTitle)); + + media_clock_enum_name.insert(std::make_pair( + std::string("CLOCK1"), hmi_apis::Common_MediaClockFormat::CLOCK1)); + media_clock_enum_name.insert(std::make_pair( + std::string("CLOCK2"), hmi_apis::Common_MediaClockFormat::CLOCK2)); + media_clock_enum_name.insert(std::make_pair( + std::string("CLOCK3"), hmi_apis::Common_MediaClockFormat::CLOCK3)); + media_clock_enum_name.insert( + std::make_pair(std::string("CLOCKTEXT1"), + hmi_apis::Common_MediaClockFormat::CLOCKTEXT1)); + media_clock_enum_name.insert( + std::make_pair(std::string("CLOCKTEXT2"), + hmi_apis::Common_MediaClockFormat::CLOCKTEXT2)); + media_clock_enum_name.insert( + std::make_pair(std::string("CLOCKTEXT3"), + hmi_apis::Common_MediaClockFormat::CLOCKTEXT3)); + media_clock_enum_name.insert( + std::make_pair(std::string("CLOCKTEXT4"), + hmi_apis::Common_MediaClockFormat::CLOCKTEXT4)); + + image_type_enum.insert(std::make_pair(std::string("STATIC"), + hmi_apis::Common_ImageType::STATIC)); + image_type_enum.insert(std::make_pair(std::string("DYNAMIC"), + hmi_apis::Common_ImageType::DYNAMIC)); + + sampling_rate_enum.insert(std::make_pair( + std::string("8KHZ"), hmi_apis::Common_SamplingRate::RATE_8KHZ)); + sampling_rate_enum.insert(std::make_pair( + std::string("16KHZ"), hmi_apis::Common_SamplingRate::RATE_16KHZ)); + sampling_rate_enum.insert(std::make_pair( + std::string("22KHZ"), hmi_apis::Common_SamplingRate::RATE_22KHZ)); + sampling_rate_enum.insert(std::make_pair( + std::string("44KHZ"), hmi_apis::Common_SamplingRate::RATE_44KHZ)); + + bit_per_sample_enum.insert(std::make_pair( + std::string("RATE_8_BIT"), hmi_apis::Common_BitsPerSample::RATE_8_BIT)); + bit_per_sample_enum.insert(std::make_pair( + std::string("RATE_16_BIT"), hmi_apis::Common_BitsPerSample::RATE_16_BIT)); + + audio_type_enum.insert( + std::make_pair(std::string("PCM"), hmi_apis::Common_AudioType::PCM)); + + hmi_zone_enum.insert(std::make_pair( + std::string("FRONT"), hmi_apis::Common_HmiZoneCapabilities::FRONT)); + hmi_zone_enum.insert(std::make_pair( + std::string("BACK"), hmi_apis::Common_HmiZoneCapabilities::BACK)); + + image_field_name_enum.insert( + std::make_pair(std::string("softButtonImage"), + hmi_apis::Common_ImageFieldName::softButtonImage)); + image_field_name_enum.insert( + std::make_pair(std::string("choiceImage"), + hmi_apis::Common_ImageFieldName::choiceImage)); + image_field_name_enum.insert( + std::make_pair(std::string("choiceSecondaryImage"), + hmi_apis::Common_ImageFieldName::choiceSecondaryImage)); + image_field_name_enum.insert(std::make_pair( + std::string("vrHelpItem"), hmi_apis::Common_ImageFieldName::vrHelpItem)); + image_field_name_enum.insert(std::make_pair( + std::string("turnIcon"), hmi_apis::Common_ImageFieldName::turnIcon)); + image_field_name_enum.insert(std::make_pair( + std::string("menuIcon"), hmi_apis::Common_ImageFieldName::menuIcon)); + image_field_name_enum.insert(std::make_pair( + std::string("cmdIcon"), hmi_apis::Common_ImageFieldName::cmdIcon)); + image_field_name_enum.insert(std::make_pair( + std::string("appIcon"), hmi_apis::Common_ImageFieldName::appIcon)); + image_field_name_enum.insert(std::make_pair( + std::string("graphic"), hmi_apis::Common_ImageFieldName::graphic)); + image_field_name_enum.insert( + std::make_pair(std::string("showConstantTBTIcon"), + hmi_apis::Common_ImageFieldName::showConstantTBTIcon)); + image_field_name_enum.insert(std::make_pair( + std::string("showConstantTBTNextTurnIcon"), + hmi_apis::Common_ImageFieldName::showConstantTBTNextTurnIcon)); + image_field_name_enum.insert( + std::make_pair(std::string("locationImage"), + hmi_apis::Common_ImageFieldName::locationImage)); + + file_type_enum.insert(std::make_pair(std::string("GRAPHIC_BMP"), + hmi_apis::Common_FileType::GRAPHIC_BMP)); + file_type_enum.insert(std::make_pair( + std::string("GRAPHIC_JPEG"), hmi_apis::Common_FileType::GRAPHIC_JPEG)); + file_type_enum.insert(std::make_pair(std::string("GRAPHIC_PNG"), + hmi_apis::Common_FileType::GRAPHIC_PNG)); + file_type_enum.insert(std::make_pair(std::string("AUDIO_WAVE"), + hmi_apis::Common_FileType::AUDIO_WAVE)); + file_type_enum.insert(std::make_pair(std::string("AUDIO_MP3"), + hmi_apis::Common_FileType::AUDIO_MP3)); + file_type_enum.insert(std::make_pair(std::string("AUDIO_AAC"), + hmi_apis::Common_FileType::AUDIO_AAC)); + file_type_enum.insert( + std::make_pair(std::string("BINARY"), hmi_apis::Common_FileType::BINARY)); + file_type_enum.insert( + std::make_pair(std::string("JSON"), hmi_apis::Common_FileType::JSON)); + + display_type_enum.insert( + std::make_pair(std::string("CID"), hmi_apis::Common_DisplayType::CID)); + display_type_enum.insert(std::make_pair(std::string("TYPE2"), + hmi_apis::Common_DisplayType::TYPE2)); + display_type_enum.insert(std::make_pair(std::string("TYPE5"), + hmi_apis::Common_DisplayType::TYPE5)); + display_type_enum.insert( + std::make_pair(std::string("NGN"), hmi_apis::Common_DisplayType::NGN)); + display_type_enum.insert(std::make_pair( + std::string("GEN2_8_DMA"), hmi_apis::Common_DisplayType::GEN2_8_DMA)); + display_type_enum.insert(std::make_pair( + std::string("GEN2_6_DMA"), hmi_apis::Common_DisplayType::GEN2_6_DMA)); + display_type_enum.insert( + std::make_pair(std::string("MFD3"), hmi_apis::Common_DisplayType::MFD3)); + display_type_enum.insert( + std::make_pair(std::string("MFD4"), hmi_apis::Common_DisplayType::MFD4)); + display_type_enum.insert( + std::make_pair(std::string("MFD5"), hmi_apis::Common_DisplayType::MFD5)); + display_type_enum.insert(std::make_pair( + std::string("GEN3_8_INCH"), hmi_apis::Common_DisplayType::GEN3_8_INCH)); + + character_set_enum.insert(std::make_pair( + std::string("TYPE2SET"), hmi_apis::Common_CharacterSet::TYPE2SET)); + character_set_enum.insert(std::make_pair( + std::string("TYPE5SET"), hmi_apis::Common_CharacterSet::TYPE5SET)); + character_set_enum.insert(std::make_pair( + std::string("CID1SET"), hmi_apis::Common_CharacterSet::CID1SET)); + character_set_enum.insert(std::make_pair( + std::string("CID2SET"), hmi_apis::Common_CharacterSet::CID2SET)); +} -std::map<std::string, hmi_apis::Common_AudioType::eType> audio_type_enum = { - {"PCM", hmi_apis::Common_AudioType::PCM}}; +} // namespace -std::map<std::string, hmi_apis::Common_HmiZoneCapabilities::eType> - hmi_zone_enum = { - {"FRONT", hmi_apis::Common_HmiZoneCapabilities::FRONT}, - {"BACK", hmi_apis::Common_HmiZoneCapabilities::BACK}, -}; - -const std::map<std::string, hmi_apis::Common_ImageFieldName::eType> - image_field_name_enum = { - {"softButtonImage", hmi_apis::Common_ImageFieldName::softButtonImage}, - {"choiceImage", hmi_apis::Common_ImageFieldName::choiceImage}, - {"choiceSecondaryImage", - hmi_apis::Common_ImageFieldName::choiceSecondaryImage}, - {"vrHelpItem", hmi_apis::Common_ImageFieldName::vrHelpItem}, - {"turnIcon", hmi_apis::Common_ImageFieldName::turnIcon}, - {"menuIcon", hmi_apis::Common_ImageFieldName::menuIcon}, - {"cmdIcon", hmi_apis::Common_ImageFieldName::cmdIcon}, - {"appIcon", hmi_apis::Common_ImageFieldName::appIcon}, - {"graphic", hmi_apis::Common_ImageFieldName::graphic}, - {"showConstantTBTIcon", - hmi_apis::Common_ImageFieldName::showConstantTBTIcon}, - {"showConstantTBTNextTurnIcon", - hmi_apis::Common_ImageFieldName::showConstantTBTNextTurnIcon}, - {"locationImage", hmi_apis::Common_ImageFieldName::locationImage}}; - -const std::map<std::string, hmi_apis::Common_FileType::eType> file_type_enum = { - {"GRAPHIC_BMP", hmi_apis::Common_FileType::GRAPHIC_BMP}, - {"GRAPHIC_JPEG", hmi_apis::Common_FileType::GRAPHIC_JPEG}, - {"GRAPHIC_PNG", hmi_apis::Common_FileType::GRAPHIC_PNG}, - {"AUDIO_WAVE", hmi_apis::Common_FileType::AUDIO_WAVE}, - {"AUDIO_MP3", hmi_apis::Common_FileType::AUDIO_MP3}, - {"AUDIO_AAC", hmi_apis::Common_FileType::AUDIO_AAC}, - {"BINARY", hmi_apis::Common_FileType::BINARY}, - {"JSON", hmi_apis::Common_FileType::JSON}}; - -const std::map<std::string, hmi_apis::Common_DisplayType::eType> - display_type_enum = { - {"CID", hmi_apis::Common_DisplayType::CID}, - {"TYPE2", hmi_apis::Common_DisplayType::TYPE2}, - {"TYPE5", hmi_apis::Common_DisplayType::TYPE5}, - {"NGN", hmi_apis::Common_DisplayType::NGN}, - {"GEN2_8_DMA", hmi_apis::Common_DisplayType::GEN2_8_DMA}, - {"GEN2_6_DMA", hmi_apis::Common_DisplayType::GEN2_6_DMA}, - {"MFD3", hmi_apis::Common_DisplayType::MFD3}, - {"MFD4", hmi_apis::Common_DisplayType::MFD4}, - {"MFD5", hmi_apis::Common_DisplayType::MFD5}, - {"GEN3_8_INCH", hmi_apis::Common_DisplayType::GEN3_8_INCH}}; - -const std::map<std::string, hmi_apis::Common_CharacterSet::eType> - character_set_enum = {{"TYPE2SET", hmi_apis::Common_CharacterSet::TYPE2SET}, - {"TYPE5SET", hmi_apis::Common_CharacterSet::TYPE5SET}, - {"CID1SET", hmi_apis::Common_CharacterSet::CID1SET}, - {"CID2SET", hmi_apis::Common_CharacterSet::CID2SET}}; - -HMICapabilities::HMICapabilities(ApplicationManager& app_mngr) +HMICapabilitiesImpl::HMICapabilitiesImpl(ApplicationManager& app_mngr) : is_vr_cooperating_(false) , is_tts_cooperating_(false) , is_ui_cooperating_(false) @@ -236,7 +350,8 @@ HMICapabilities::HMICapabilities(ApplicationManager& app_mngr) , is_navigation_supported_(false) , is_phone_call_supported_(false) , app_mngr_(app_mngr) - , hmi_language_handler_(app_mngr_) { + , hmi_language_handler_(app_mngr) { + InitCapabilities(); if (false == app_mngr_.get_settings().launch_hmi()) { is_vr_ready_response_recieved_ = true; is_tts_ready_response_recieved_ = true; @@ -252,7 +367,7 @@ HMICapabilities::HMICapabilities(ApplicationManager& app_mngr) } } -HMICapabilities::~HMICapabilities() { +HMICapabilitiesImpl::~HMICapabilitiesImpl() { delete vehicle_type_; delete ui_supported_languages_; delete tts_supported_languages_; @@ -269,7 +384,7 @@ HMICapabilities::~HMICapabilities() { delete prerecorded_speech_; } -bool HMICapabilities::is_hmi_capabilities_initialized() const { +bool HMICapabilitiesImpl::is_hmi_capabilities_initialized() const { bool result = true; if (is_vr_ready_response_recieved_ && is_tts_ready_response_recieved_ && @@ -308,7 +423,7 @@ bool HMICapabilities::is_hmi_capabilities_initialized() const { return result; } -bool HMICapabilities::VerifyImageType(int32_t image_type) const { +bool HMICapabilitiesImpl::VerifyImageType(const int32_t image_type) const { if (!display_capabilities_) { return false; } @@ -326,7 +441,7 @@ bool HMICapabilities::VerifyImageType(int32_t image_type) const { return false; } -void HMICapabilities::set_is_vr_cooperating(bool value) { +void HMICapabilitiesImpl::set_is_vr_cooperating(const bool value) { is_vr_ready_response_recieved_ = true; is_vr_cooperating_ = value; if (is_vr_cooperating_) { @@ -346,7 +461,7 @@ void HMICapabilities::set_is_vr_cooperating(bool value) { } } -void HMICapabilities::set_is_tts_cooperating(bool value) { +void HMICapabilitiesImpl::set_is_tts_cooperating(const bool value) { is_tts_ready_response_recieved_ = true; is_tts_cooperating_ = value; if (is_tts_cooperating_) { @@ -366,7 +481,7 @@ void HMICapabilities::set_is_tts_cooperating(bool value) { } } -void HMICapabilities::set_is_ui_cooperating(bool value) { +void HMICapabilitiesImpl::set_is_ui_cooperating(const bool value) { is_ui_ready_response_recieved_ = true; is_ui_cooperating_ = value; if (is_ui_cooperating_) { @@ -386,12 +501,12 @@ void HMICapabilities::set_is_ui_cooperating(bool value) { } } -void HMICapabilities::set_is_navi_cooperating(bool value) { +void HMICapabilitiesImpl::set_is_navi_cooperating(const bool value) { is_navi_ready_response_recieved_ = true; is_navi_cooperating_ = value; } -void HMICapabilities::set_is_ivi_cooperating(bool value) { +void HMICapabilitiesImpl::set_is_ivi_cooperating(const bool value) { is_ivi_ready_response_recieved_ = true; is_ivi_cooperating_ = value; if (is_ivi_cooperating_) { @@ -402,32 +517,32 @@ void HMICapabilities::set_is_ivi_cooperating(bool value) { } } -void HMICapabilities::set_attenuated_supported(bool state) { +void HMICapabilitiesImpl::set_attenuated_supported(const bool state) { attenuated_supported_ = state; } -void HMICapabilities::set_active_ui_language( - const hmi_apis::Common_Language::eType& language) { +void HMICapabilitiesImpl::set_active_ui_language( + const hmi_apis::Common_Language::eType language) { ui_language_ = language; hmi_language_handler_.set_language_for(HMILanguageHandler::INTERFACE_UI, language); } -void HMICapabilities::set_active_vr_language( - const hmi_apis::Common_Language::eType& language) { +void HMICapabilitiesImpl::set_active_vr_language( + const hmi_apis::Common_Language::eType language) { vr_language_ = language; hmi_language_handler_.set_language_for(HMILanguageHandler::INTERFACE_VR, language); } -void HMICapabilities::set_active_tts_language( - const hmi_apis::Common_Language::eType& language) { +void HMICapabilitiesImpl::set_active_tts_language( + const hmi_apis::Common_Language::eType language) { tts_language_ = language; hmi_language_handler_.set_language_for(HMILanguageHandler::INTERFACE_TTS, language); } -const hmi_apis::Common_Language::eType HMICapabilities::active_ui_language() +const hmi_apis::Common_Language::eType HMICapabilitiesImpl::active_ui_language() const { using namespace hmi_apis; const Common_Language::eType language = @@ -435,7 +550,7 @@ const hmi_apis::Common_Language::eType HMICapabilities::active_ui_language() return Common_Language::INVALID_ENUM != language ? language : ui_language_; } -const hmi_apis::Common_Language::eType HMICapabilities::active_vr_language() +const hmi_apis::Common_Language::eType HMICapabilitiesImpl::active_vr_language() const { using namespace hmi_apis; const Common_Language::eType language = @@ -443,15 +558,15 @@ const hmi_apis::Common_Language::eType HMICapabilities::active_vr_language() return Common_Language::INVALID_ENUM != language ? language : vr_language_; } -const hmi_apis::Common_Language::eType HMICapabilities::active_tts_language() - const { +const hmi_apis::Common_Language::eType +HMICapabilitiesImpl::active_tts_language() const { using namespace hmi_apis; const Common_Language::eType language = hmi_language_handler_.get_language_for(HMILanguageHandler::INTERFACE_TTS); return Common_Language::INVALID_ENUM != language ? language : tts_language_; } -void HMICapabilities::set_ui_supported_languages( +void HMICapabilitiesImpl::set_ui_supported_languages( const smart_objects::SmartObject& supported_languages) { if (ui_supported_languages_) { delete ui_supported_languages_; @@ -459,7 +574,7 @@ void HMICapabilities::set_ui_supported_languages( ui_supported_languages_ = new smart_objects::SmartObject(supported_languages); } -void HMICapabilities::set_tts_supported_languages( +void HMICapabilitiesImpl::set_tts_supported_languages( const smart_objects::SmartObject& supported_languages) { if (tts_supported_languages_) { delete tts_supported_languages_; @@ -468,7 +583,7 @@ void HMICapabilities::set_tts_supported_languages( new smart_objects::SmartObject(supported_languages); } -void HMICapabilities::set_vr_supported_languages( +void HMICapabilitiesImpl::set_vr_supported_languages( const smart_objects::SmartObject& supported_languages) { if (vr_supported_languages_) { delete vr_supported_languages_; @@ -476,7 +591,7 @@ void HMICapabilities::set_vr_supported_languages( vr_supported_languages_ = new smart_objects::SmartObject(supported_languages); } -void HMICapabilities::set_display_capabilities( +void HMICapabilitiesImpl::set_display_capabilities( const smart_objects::SmartObject& display_capabilities) { if (display_capabilities_) { delete display_capabilities_; @@ -484,7 +599,7 @@ void HMICapabilities::set_display_capabilities( display_capabilities_ = new smart_objects::SmartObject(display_capabilities); } -void HMICapabilities::set_hmi_zone_capabilities( +void HMICapabilitiesImpl::set_hmi_zone_capabilities( const smart_objects::SmartObject& hmi_zone_capabilities) { if (hmi_zone_capabilities_) { delete hmi_zone_capabilities_; @@ -493,7 +608,7 @@ void HMICapabilities::set_hmi_zone_capabilities( new smart_objects::SmartObject(hmi_zone_capabilities); } -void HMICapabilities::set_soft_button_capabilities( +void HMICapabilitiesImpl::set_soft_button_capabilities( const smart_objects::SmartObject& soft_button_capabilities) { if (soft_buttons_capabilities_) { delete soft_buttons_capabilities_; @@ -502,7 +617,7 @@ void HMICapabilities::set_soft_button_capabilities( new smart_objects::SmartObject(soft_button_capabilities); } -void HMICapabilities::set_button_capabilities( +void HMICapabilitiesImpl::set_button_capabilities( const smart_objects::SmartObject& button_capabilities) { if (button_capabilities_) { delete button_capabilities_; @@ -510,7 +625,7 @@ void HMICapabilities::set_button_capabilities( button_capabilities_ = new smart_objects::SmartObject(button_capabilities); } -void HMICapabilities::set_vr_capabilities( +void HMICapabilitiesImpl::set_vr_capabilities( const smart_objects::SmartObject& vr_capabilities) { if (vr_capabilities_) { delete vr_capabilities_; @@ -518,7 +633,7 @@ void HMICapabilities::set_vr_capabilities( vr_capabilities_ = new smart_objects::SmartObject(vr_capabilities); } -void HMICapabilities::set_speech_capabilities( +void HMICapabilitiesImpl::set_speech_capabilities( const smart_objects::SmartObject& speech_capabilities) { if (speech_capabilities_) { delete speech_capabilities_; @@ -526,7 +641,7 @@ void HMICapabilities::set_speech_capabilities( speech_capabilities_ = new smart_objects::SmartObject(speech_capabilities); } -void HMICapabilities::set_audio_pass_thru_capabilities( +void HMICapabilitiesImpl::set_audio_pass_thru_capabilities( const smart_objects::SmartObject& audio_pass_thru_capabilities) { if (audio_pass_thru_capabilities_) { delete audio_pass_thru_capabilities_; @@ -535,7 +650,7 @@ void HMICapabilities::set_audio_pass_thru_capabilities( new smart_objects::SmartObject(audio_pass_thru_capabilities); } -void HMICapabilities::set_pcm_stream_capabilities( +void HMICapabilitiesImpl::set_pcm_stream_capabilities( const smart_objects::SmartObject& pcm_stream_capabilities) { if (pcm_stream_capabilities_) { delete pcm_stream_capabilities_; @@ -544,7 +659,7 @@ void HMICapabilities::set_pcm_stream_capabilities( new smart_objects::SmartObject(pcm_stream_capabilities); } -void HMICapabilities::set_preset_bank_capabilities( +void HMICapabilitiesImpl::set_preset_bank_capabilities( const smart_objects::SmartObject& preset_bank_capabilities) { if (preset_bank_capabilities_) { delete preset_bank_capabilities_; @@ -553,7 +668,7 @@ void HMICapabilities::set_preset_bank_capabilities( new smart_objects::SmartObject(preset_bank_capabilities); } -void HMICapabilities::set_vehicle_type( +void HMICapabilitiesImpl::set_vehicle_type( const smart_objects::SmartObject& vehicle_type) { if (vehicle_type_) { delete vehicle_type_; @@ -561,7 +676,7 @@ void HMICapabilities::set_vehicle_type( vehicle_type_ = new smart_objects::SmartObject(vehicle_type); } -void HMICapabilities::set_prerecorded_speech( +void HMICapabilitiesImpl::set_prerecorded_speech( const smart_objects::SmartObject& prerecorded_speech) { if (prerecorded_speech_) { delete prerecorded_speech_; @@ -570,19 +685,14 @@ void HMICapabilities::set_prerecorded_speech( prerecorded_speech_ = new smart_objects::SmartObject(prerecorded_speech); } -void HMICapabilities::set_ccpu_version(const std::string& ccpu_version) { - ccpu_version_ = ccpu_version; -} - -void HMICapabilities::set_navigation_supported(const bool supported) { +void HMICapabilitiesImpl::set_navigation_supported(const bool supported) { is_navigation_supported_ = supported; } - -void HMICapabilities::set_phone_call_supported(const bool supported) { +void HMICapabilitiesImpl::set_phone_call_supported(const bool supported) { is_phone_call_supported_ = supported; } -void HMICapabilities::Init(resumption::LastState* last_state) { +void HMICapabilitiesImpl::Init(resumption::LastState* last_state) { hmi_language_handler_.Init(last_state); if (false == load_capabilities_from_file()) { LOG4CXX_ERROR(logger_, "file hmi_capabilities.json was not loaded"); @@ -593,7 +703,107 @@ void HMICapabilities::Init(resumption::LastState* last_state) { ui_language_, vr_language_, tts_language_); } -bool HMICapabilities::load_capabilities_from_file() { +bool HMICapabilitiesImpl::is_ui_cooperating() const { + return is_ui_cooperating_; +} + +bool HMICapabilitiesImpl::is_vr_cooperating() const { + return is_vr_cooperating_; +} + +bool HMICapabilitiesImpl::is_tts_cooperating() const { + return is_tts_cooperating_; +} + +bool HMICapabilitiesImpl::is_navi_cooperating() const { + return is_navi_cooperating_; +} + +bool HMICapabilitiesImpl::is_ivi_cooperating() const { + return is_ivi_cooperating_; +} + +const smart_objects::SmartObject* HMICapabilitiesImpl::ui_supported_languages() + const { + return ui_supported_languages_; +} + +const smart_objects::SmartObject* HMICapabilitiesImpl::vr_supported_languages() + const { + return vr_supported_languages_; +} + +const smart_objects::SmartObject* HMICapabilitiesImpl::tts_supported_languages() + const { + return tts_supported_languages_; +} + +const smart_objects::SmartObject* HMICapabilitiesImpl::display_capabilities() + const { + return display_capabilities_; +} + +const smart_objects::SmartObject* HMICapabilitiesImpl::hmi_zone_capabilities() + const { + return hmi_zone_capabilities_; +} + +const smart_objects::SmartObject* +HMICapabilitiesImpl::soft_button_capabilities() const { + return soft_buttons_capabilities_; +} + +const smart_objects::SmartObject* HMICapabilitiesImpl::button_capabilities() + const { + return button_capabilities_; +} + +const smart_objects::SmartObject* HMICapabilitiesImpl::speech_capabilities() + const { + return speech_capabilities_; +} + +const smart_objects::SmartObject* HMICapabilitiesImpl::vr_capabilities() const { + return vr_capabilities_; +} + +const smart_objects::SmartObject* +HMICapabilitiesImpl::audio_pass_thru_capabilities() const { + return audio_pass_thru_capabilities_; +} + +const smart_objects::SmartObject* HMICapabilitiesImpl::pcm_stream_capabilities() + const { + return pcm_stream_capabilities_; +} + +const smart_objects::SmartObject* +HMICapabilitiesImpl::preset_bank_capabilities() const { + return preset_bank_capabilities_; +} + +bool HMICapabilitiesImpl::attenuated_supported() const { + return attenuated_supported_; +} + +const smart_objects::SmartObject* HMICapabilitiesImpl::vehicle_type() const { + return vehicle_type_; +} + +const smart_objects::SmartObject* HMICapabilitiesImpl::prerecorded_speech() + const { + return prerecorded_speech_; +} + +bool HMICapabilitiesImpl::navigation_supported() const { + return is_navigation_supported_; +} + +bool HMICapabilitiesImpl::phone_call_supported() const { + return is_phone_call_supported_; +} + +bool HMICapabilitiesImpl::load_capabilities_from_file() { std::string json_string; std::string file_name = app_mngr_.get_settings().hmi_capabilities_file_name(); @@ -620,6 +830,9 @@ bool HMICapabilities::load_capabilities_from_file() { if (check_existing_json_member(ui, "language")) { const std::string lang = ui.get("language", "EN-US").asString(); set_active_ui_language(MessageHelper::CommonLanguageFromString(lang)); + } else { + set_active_ui_language( + MessageHelper::CommonLanguageFromString("EN-US")); } if (check_existing_json_member(ui, "languages")) { @@ -649,10 +862,10 @@ bool HMICapabilities::load_capabilities_from_file() { } if (display_capabilities_so.keyExists(hmi_response::text_fields)) { - uint32_t len = + const uint32_t kLen = display_capabilities_so[hmi_response::text_fields].length(); - for (uint32_t i = 0; i < len; ++i) { + for (uint32_t i = 0; i < kLen; ++i) { if ((display_capabilities_so[hmi_response::text_fields][i]) .keyExists(strings::name)) { std::map<std::string, @@ -842,6 +1055,9 @@ bool HMICapabilities::load_capabilities_from_file() { if (check_existing_json_member(vr, "language")) { const std::string lang = vr.get("language", "EN-US").asString(); set_active_vr_language(MessageHelper::CommonLanguageFromString(lang)); + } else { + set_active_vr_language( + MessageHelper::CommonLanguageFromString("EN-US")); } if (check_existing_json_member(vr, "languages")) { @@ -871,6 +1087,9 @@ bool HMICapabilities::load_capabilities_from_file() { if (check_existing_json_member(tts, "language")) { const std::string lang = tts.get("language", "EN-US").asString(); set_active_tts_language(MessageHelper::CommonLanguageFromString(lang)); + } else { + set_active_tts_language( + MessageHelper::CommonLanguageFromString("EN-US")); } if (check_existing_json_member(tts, "languages")) { @@ -934,17 +1153,30 @@ bool HMICapabilities::load_capabilities_from_file() { return true; } -bool HMICapabilities::check_existing_json_member(const Json::Value& json_member, - const char* name_of_member) { +void HMICapabilitiesImpl::set_ccpu_version(const std::string& ccpu_version) { + ccpu_version_ = ccpu_version; +} + +const std::string& HMICapabilitiesImpl::ccpu_version() const { + return ccpu_version_; +} + +bool HMICapabilitiesImpl::check_existing_json_member( + const Json::Value& json_member, const char* name_of_member) const { return json_member.isMember(name_of_member); } -void HMICapabilities::convert_json_languages_to_obj( - Json::Value& json_languages, smart_objects::SmartObject& languages) { +void HMICapabilitiesImpl::convert_json_languages_to_obj( + const Json::Value& json_languages, + smart_objects::SmartObject& languages) const { for (uint32_t i = 0, j = 0; i < json_languages.size(); ++i) { languages[j++] = MessageHelper::CommonLanguageFromString(json_languages[i].asString()); } } +HMILanguageHandler& HMICapabilitiesImpl::get_hmi_language_handler() { + return hmi_language_handler_; +} + } // namespace application_manager diff --git a/src/components/application_manager/src/request_controller.cc b/src/components/application_manager/src/request_controller.cc index b2ced9b01b..9010232f5c 100644 --- a/src/components/application_manager/src/request_controller.cc +++ b/src/components/application_manager/src/request_controller.cc @@ -495,7 +495,7 @@ void RequestController::UpdateTimer() { date_time::DateTime::getmSecs(end_time - current_time)); LOG4CXX_DEBUG(logger_, "Sleep for " << msecs << " millisecs"); // Timeout for bigger than 5 minutes is a mistake - timer_.Start(msecs, true); + timer_.Start(msecs, timer::kSingleShot); } else { LOG4CXX_WARN( logger_, diff --git a/src/components/application_manager/src/resumption/resume_ctrl.cc b/src/components/application_manager/src/resumption/resume_ctrl_impl.cc index 5e24c5572c..b0debb204d 100644 --- a/src/components/application_manager/src/resumption/resume_ctrl.cc +++ b/src/components/application_manager/src/resumption/resume_ctrl_impl.cc @@ -29,7 +29,7 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "application_manager/resumption/resume_ctrl.h" +#include "application_manager/resumption/resume_ctrl_impl.h" #include <fstream> #include <algorithm> @@ -55,28 +55,28 @@ using namespace application_manager; CREATE_LOGGERPTR_GLOBAL(logger_, "Resumption") -ResumeCtrl::ResumeCtrl(ApplicationManager& application_manager) +ResumeCtrlImpl::ResumeCtrlImpl(ApplicationManager& application_manager) : event_engine::EventObserver(application_manager.event_dispatcher()) , queue_lock_(false) , restore_hmi_level_timer_( "RsmCtrlRstore", - new timer::TimerTaskImpl<ResumeCtrl>( - this, &ResumeCtrl::ApplicationResumptiOnTimer)) + new timer::TimerTaskImpl<ResumeCtrlImpl>( + this, &ResumeCtrlImpl::ApplicationResumptiOnTimer)) , save_persistent_data_timer_("RsmCtrlPercist", - new timer::TimerTaskImpl<ResumeCtrl>( - this, &ResumeCtrl::SaveDataOnTimer)) + new timer::TimerTaskImpl<ResumeCtrlImpl>( + this, &ResumeCtrlImpl::SaveDataOnTimer)) , is_resumption_active_(false) , is_data_saved_(false) , launch_time_(time(NULL)) , application_manager_(application_manager) {} #ifdef BUILD_TESTS -void ResumeCtrl::set_resumption_storage( +void ResumeCtrlImpl::set_resumption_storage( utils::SharedPtr<ResumptionData> mock_storage) { resumption_storage_ = mock_storage; } #endif // BUILD_TESTS -bool ResumeCtrl::Init(resumption::LastState& last_state) { +bool ResumeCtrlImpl::Init(resumption::LastState& last_state) { bool use_db = application_manager_.get_settings().use_db_for_resumption(); if (use_db) { resumption_storage_.reset( @@ -115,20 +115,21 @@ bool ResumeCtrl::Init(resumption::LastState& last_state) { save_persistent_data_timer_.Start( application_manager_.get_settings() .app_resumption_save_persistent_data_timeout(), - false); + timer::kPeriodic); return true; } -ResumeCtrl::~ResumeCtrl() {} +ResumeCtrlImpl::~ResumeCtrlImpl() {} -void ResumeCtrl::SaveAllApplications() { +void ResumeCtrlImpl::SaveAllApplications() { DataAccessor<ApplicationSet> accessor(application_manager_.applications()); - std::for_each(accessor.GetData().begin(), - accessor.GetData().end(), - std::bind1st(std::mem_fun(&ResumeCtrl::SaveApplication), this)); + std::for_each( + accessor.GetData().begin(), + accessor.GetData().end(), + std::bind1st(std::mem_fun(&ResumeCtrlImpl::SaveApplication), this)); } -void ResumeCtrl::SaveApplication(ApplicationSharedPtr application) { +void ResumeCtrlImpl::SaveApplication(ApplicationSharedPtr application) { LOG4CXX_AUTO_TRACE(logger_); DCHECK_OR_RETURN_VOID(application); LOG4CXX_INFO(logger_, @@ -137,11 +138,11 @@ void ResumeCtrl::SaveApplication(ApplicationSharedPtr application) { resumption_storage_->SaveApplication(application); } -void ResumeCtrl::on_event(const event_engine::Event& event) { +void ResumeCtrlImpl::on_event(const event_engine::Event& event) { LOG4CXX_DEBUG(logger_, "Event received" << event.id()); } -bool ResumeCtrl::RestoreAppHMIState(ApplicationSharedPtr application) { +bool ResumeCtrlImpl::RestoreAppHMIState(ApplicationSharedPtr application) { using namespace mobile_apis; LOG4CXX_AUTO_TRACE(logger_); DCHECK_OR_RETURN(application, false); @@ -170,7 +171,7 @@ bool ResumeCtrl::RestoreAppHMIState(ApplicationSharedPtr application) { return result; } -bool ResumeCtrl::SetupDefaultHMILevel(ApplicationSharedPtr application) { +bool ResumeCtrlImpl::SetupDefaultHMILevel(ApplicationSharedPtr application) { LOG4CXX_AUTO_TRACE(logger_); DCHECK_OR_RETURN(application, false); mobile_apis::HMILevel::eType default_hmi = @@ -178,7 +179,7 @@ bool ResumeCtrl::SetupDefaultHMILevel(ApplicationSharedPtr application) { return SetAppHMIState(application, default_hmi, false); } -void ResumeCtrl::ApplicationResumptiOnTimer() { +void ResumeCtrlImpl::ApplicationResumptiOnTimer() { LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock auto_lock(queue_lock_); WaitingForTimerList::iterator it = waiting_for_timer_.begin(); @@ -196,22 +197,23 @@ void ResumeCtrl::ApplicationResumptiOnTimer() { StartSavePersistentDataTimer(); } -void ResumeCtrl::OnAppActivated(ApplicationSharedPtr application) { +void ResumeCtrlImpl::OnAppActivated(ApplicationSharedPtr application) { if (is_resumption_active_) { RemoveFromResumption(application->app_id()); } } -void ResumeCtrl::RemoveFromResumption(uint32_t app_id) { +void ResumeCtrlImpl::RemoveFromResumption(uint32_t app_id) { LOG4CXX_AUTO_TRACE(logger_); queue_lock_.Acquire(); waiting_for_timer_.remove(app_id); queue_lock_.Release(); } -bool ResumeCtrl::SetAppHMIState(ApplicationSharedPtr application, - const mobile_apis::HMILevel::eType hmi_level, - bool check_policy) { +bool ResumeCtrlImpl::SetAppHMIState( + ApplicationSharedPtr application, + const mobile_apis::HMILevel::eType hmi_level, + bool check_policy) { using namespace mobile_apis; LOG4CXX_AUTO_TRACE(logger_); DCHECK_OR_RETURN(application, false); @@ -236,30 +238,30 @@ bool ResumeCtrl::SetAppHMIState(ApplicationSharedPtr application, return true; } -bool ResumeCtrl::IsHMIApplicationIdExist(uint32_t hmi_app_id) { +bool ResumeCtrlImpl::IsHMIApplicationIdExist(uint32_t hmi_app_id) { LOG4CXX_DEBUG(logger_, "hmi_app_id :" << hmi_app_id); return resumption_storage_->IsHMIApplicationIdExist(hmi_app_id); } -bool ResumeCtrl::IsApplicationSaved(const std::string& policy_app_id, - const std::string& device_id) { +bool ResumeCtrlImpl::IsApplicationSaved(const std::string& policy_app_id, + const std::string& device_id) { return -1 != resumption_storage_->IsApplicationSaved(policy_app_id, device_id); } -uint32_t ResumeCtrl::GetHMIApplicationID(const std::string& policy_app_id, - const std::string& device_mac) const { +uint32_t ResumeCtrlImpl::GetHMIApplicationID( + const std::string& policy_app_id, const std::string& device_mac) const { return resumption_storage_->GetHMIApplicationID(policy_app_id, device_mac); } -bool ResumeCtrl::RemoveApplicationFromSaved( +bool ResumeCtrlImpl::RemoveApplicationFromSaved( ApplicationConstSharedPtr application) { const std::string& device_mac = application->mac_address(); return resumption_storage_->RemoveApplicationFromSaved( application->policy_app_id(), device_mac); } -void ResumeCtrl::OnSuspend() { +void ResumeCtrlImpl::OnSuspend() { LOG4CXX_AUTO_TRACE(logger_); StopSavePersistentDataTimer(); SaveAllApplications(); @@ -267,31 +269,31 @@ void ResumeCtrl::OnSuspend() { resumption_storage_->Persist(); } -void ResumeCtrl::OnAwake() { +void ResumeCtrlImpl::OnAwake() { ResetLaunchTime(); StartSavePersistentDataTimer(); return resumption_storage_->OnAwake(); } -void ResumeCtrl::StartSavePersistentDataTimer() { +void ResumeCtrlImpl::StartSavePersistentDataTimer() { LOG4CXX_AUTO_TRACE(logger_); if (!save_persistent_data_timer_.is_running()) { save_persistent_data_timer_.Start( application_manager_.get_settings() .app_resumption_save_persistent_data_timeout(), - false); + timer::kPeriodic); } } -void ResumeCtrl::StopSavePersistentDataTimer() { +void ResumeCtrlImpl::StopSavePersistentDataTimer() { LOG4CXX_AUTO_TRACE(logger_); if (save_persistent_data_timer_.is_running()) { save_persistent_data_timer_.Stop(); } } -bool ResumeCtrl::StartResumption(ApplicationSharedPtr application, - const std::string& hash) { +bool ResumeCtrlImpl::StartResumption(ApplicationSharedPtr application, + const std::string& hash) { LOG4CXX_AUTO_TRACE(logger_); DCHECK_OR_RETURN(application, false); LOG4CXX_DEBUG( @@ -314,7 +316,8 @@ bool ResumeCtrl::StartResumption(ApplicationSharedPtr application, return result; } -bool ResumeCtrl::StartResumptionOnlyHMILevel(ApplicationSharedPtr application) { +bool ResumeCtrlImpl::StartResumptionOnlyHMILevel( + ApplicationSharedPtr application) { // sync_primitives::AutoLock lock(resumtion_lock_); LOG4CXX_AUTO_TRACE(logger_); if (!application) { @@ -339,7 +342,8 @@ bool ResumeCtrl::StartResumptionOnlyHMILevel(ApplicationSharedPtr application) { return result; } -void ResumeCtrl::StartAppHmiStateResumption(ApplicationSharedPtr application) { +void ResumeCtrlImpl::StartAppHmiStateResumption( + ApplicationSharedPtr application) { using namespace date_time; LOG4CXX_AUTO_TRACE(logger_); DCHECK_OR_RETURN_VOID(application); @@ -365,12 +369,12 @@ void ResumeCtrl::StartAppHmiStateResumption(ApplicationSharedPtr application) { } } -void ResumeCtrl::ResetLaunchTime() { +void ResumeCtrlImpl::ResetLaunchTime() { LOG4CXX_AUTO_TRACE(logger_); launch_time_ = time(NULL); } -bool ResumeCtrl::CheckPersistenceFilesForResumption( +bool ResumeCtrlImpl::CheckPersistenceFilesForResumption( ApplicationSharedPtr application) { LOG4CXX_AUTO_TRACE(logger_); DCHECK_OR_RETURN(application, false); @@ -397,8 +401,8 @@ bool ResumeCtrl::CheckPersistenceFilesForResumption( return true; } -bool ResumeCtrl::CheckApplicationHash(ApplicationSharedPtr application, - const std::string& hash) { +bool ResumeCtrlImpl::CheckApplicationHash(ApplicationSharedPtr application, + const std::string& hash) { LOG4CXX_AUTO_TRACE(logger_); DCHECK_OR_RETURN(application, false); LOG4CXX_DEBUG(logger_, @@ -410,7 +414,7 @@ bool ResumeCtrl::CheckApplicationHash(ApplicationSharedPtr application, return result ? saved_app[strings::hash_id].asString() == hash : false; } -void ResumeCtrl::SaveDataOnTimer() { +void ResumeCtrlImpl::SaveDataOnTimer() { LOG4CXX_AUTO_TRACE(logger_); if (is_resumption_active_) { LOG4CXX_WARN(logger_, "Resumption timer is active skip saving"); @@ -426,14 +430,14 @@ void ResumeCtrl::SaveDataOnTimer() { } } -bool ResumeCtrl::IsDeviceMacAddressEqual(ApplicationSharedPtr application, - const std::string& saved_device_mac) { +bool ResumeCtrlImpl::IsDeviceMacAddressEqual( + ApplicationSharedPtr application, const std::string& saved_device_mac) { LOG4CXX_AUTO_TRACE(logger_); const std::string device_mac = application->mac_address(); return device_mac == saved_device_mac; } -bool ResumeCtrl::RestoreApplicationData(ApplicationSharedPtr application) { +bool ResumeCtrlImpl::RestoreApplicationData(ApplicationSharedPtr application) { LOG4CXX_AUTO_TRACE(logger_); DCHECK_OR_RETURN(application, false); LOG4CXX_DEBUG(logger_, "app_id : " << application->app_id()); @@ -465,8 +469,8 @@ bool ResumeCtrl::RestoreApplicationData(ApplicationSharedPtr application) { return result; } -void ResumeCtrl::AddFiles(ApplicationSharedPtr application, - const smart_objects::SmartObject& saved_app) { +void ResumeCtrlImpl::AddFiles(ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app) { LOG4CXX_AUTO_TRACE(logger_); if (saved_app.keyExists(strings::application_files)) { @@ -493,8 +497,8 @@ void ResumeCtrl::AddFiles(ApplicationSharedPtr application, } } -void ResumeCtrl::AddSubmenues(ApplicationSharedPtr application, - const smart_objects::SmartObject& saved_app) { +void ResumeCtrlImpl::AddSubmenues(ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app) { LOG4CXX_AUTO_TRACE(logger_); if (saved_app.keyExists(strings::application_submenus)) { @@ -511,8 +515,8 @@ void ResumeCtrl::AddSubmenues(ApplicationSharedPtr application, } } -void ResumeCtrl::AddCommands(ApplicationSharedPtr application, - const smart_objects::SmartObject& saved_app) { +void ResumeCtrlImpl::AddCommands(ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app) { LOG4CXX_AUTO_TRACE(logger_); if (saved_app.keyExists(strings::application_commands)) { @@ -530,8 +534,9 @@ void ResumeCtrl::AddCommands(ApplicationSharedPtr application, } } -void ResumeCtrl::AddChoicesets(ApplicationSharedPtr application, - const smart_objects::SmartObject& saved_app) { +void ResumeCtrlImpl::AddChoicesets( + ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app) { LOG4CXX_AUTO_TRACE(logger_); if (saved_app.keyExists(strings::application_choice_sets)) { @@ -550,7 +555,7 @@ void ResumeCtrl::AddChoicesets(ApplicationSharedPtr application, } } -void ResumeCtrl::SetGlobalProperties( +void ResumeCtrlImpl::SetGlobalProperties( ApplicationSharedPtr application, const smart_objects::SmartObject& saved_app) { LOG4CXX_AUTO_TRACE(logger_); @@ -563,7 +568,7 @@ void ResumeCtrl::SetGlobalProperties( } } -void ResumeCtrl::AddWayPointsSubscription( +void ResumeCtrlImpl::AddWayPointsSubscription( app_mngr::ApplicationSharedPtr application, const smart_objects::SmartObject& saved_app) { LOG4CXX_AUTO_TRACE(logger_); @@ -577,8 +582,9 @@ void ResumeCtrl::AddWayPointsSubscription( } } -void ResumeCtrl::AddSubscriptions(ApplicationSharedPtr application, - const smart_objects::SmartObject& saved_app) { +void ResumeCtrlImpl::AddSubscriptions( + ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app) { LOG4CXX_AUTO_TRACE(logger_); if (saved_app.keyExists(strings::application_subscribtions)) { const smart_objects::SmartObject& subscribtions = @@ -611,7 +617,7 @@ void ResumeCtrl::AddSubscriptions(ApplicationSharedPtr application, } } -bool ResumeCtrl::CheckIgnCycleRestrictions( +bool ResumeCtrlImpl::CheckIgnCycleRestrictions( const smart_objects::SmartObject& saved_app) { LOG4CXX_AUTO_TRACE(logger_); bool result = true; @@ -628,7 +634,7 @@ bool ResumeCtrl::CheckIgnCycleRestrictions( return result; } -bool ResumeCtrl::DisconnectedJustBeforeIgnOff( +bool ResumeCtrlImpl::DisconnectedJustBeforeIgnOff( const smart_objects::SmartObject& saved_app) { using namespace date_time; LOG4CXX_AUTO_TRACE(logger_); @@ -650,7 +656,7 @@ bool ResumeCtrl::DisconnectedJustBeforeIgnOff( application_manager_.get_settings().resumption_delay_before_ign(); } -bool ResumeCtrl::CheckAppRestrictions( +bool ResumeCtrlImpl::CheckAppRestrictions( ApplicationConstSharedPtr application, const smart_objects::SmartObject& saved_app) { using namespace mobile_apis; @@ -671,8 +677,8 @@ bool ResumeCtrl::CheckAppRestrictions( return result; } -bool ResumeCtrl::CheckIcons(ApplicationSharedPtr application, - smart_objects::SmartObject& obj) { +bool ResumeCtrlImpl::CheckIcons(ApplicationSharedPtr application, + smart_objects::SmartObject& obj) { using namespace smart_objects; LOG4CXX_AUTO_TRACE(logger_); const mobile_apis::Result::eType verify_images = @@ -680,11 +686,11 @@ bool ResumeCtrl::CheckIcons(ApplicationSharedPtr application, return mobile_apis::Result::INVALID_DATA != verify_images; } -bool ResumeCtrl::CheckDelayAfterIgnOn() { +bool ResumeCtrlImpl::CheckDelayAfterIgnOn() { using namespace date_time; LOG4CXX_AUTO_TRACE(logger_); const time_t curr_time = time(NULL); - const time_t sdl_launch_time = launch_time(); + const time_t sdl_launch_time = LaunchTime(); const uint32_t seconds_from_sdl_start = labs(curr_time - sdl_launch_time); const uint32_t wait_time = application_manager_.get_settings().resumption_delay_after_ign(); @@ -696,16 +702,16 @@ bool ResumeCtrl::CheckDelayAfterIgnOn() { return seconds_from_sdl_start <= wait_time; } -time_t ResumeCtrl::launch_time() const { +time_t ResumeCtrlImpl::LaunchTime() const { return launch_time_; } -time_t ResumeCtrl::GetIgnOffTime() { +time_t ResumeCtrlImpl::GetIgnOffTime() { return resumption_storage_->GetIgnOffTime(); } -bool ResumeCtrl::ProcessHMIRequest(smart_objects::SmartObjectSPtr request, - bool use_events) { +bool ResumeCtrlImpl::ProcessHMIRequest(smart_objects::SmartObjectSPtr request, + bool use_events) { LOG4CXX_AUTO_TRACE(logger_); if (use_events) { const hmi_apis::FunctionID::eType function_id = @@ -723,7 +729,7 @@ bool ResumeCtrl::ProcessHMIRequest(smart_objects::SmartObjectSPtr request, return true; } -void ResumeCtrl::ProcessHMIRequests( +void ResumeCtrlImpl::ProcessHMIRequests( const smart_objects::SmartObjectList& requests) { for (smart_objects::SmartObjectList::const_iterator it = requests.begin(), total = requests.end(); @@ -733,7 +739,7 @@ void ResumeCtrl::ProcessHMIRequests( } } -void ResumeCtrl::AddToResumptionTimerQueue(const uint32_t app_id) { +void ResumeCtrlImpl::AddToResumptionTimerQueue(const uint32_t app_id) { LOG4CXX_AUTO_TRACE(logger_); queue_lock_.Acquire(); waiting_for_timer_.push_back(app_id); @@ -744,11 +750,12 @@ void ResumeCtrl::AddToResumptionTimerQueue(const uint32_t app_id) { if (!is_resumption_active_) { is_resumption_active_ = true; restore_hmi_level_timer_.Start( - application_manager_.get_settings().app_resuming_timeout(), true); + application_manager_.get_settings().app_resuming_timeout(), + timer::kSingleShot); } } -void ResumeCtrl::LoadResumeData() { +void ResumeCtrlImpl::LoadResumeData() { LOG4CXX_AUTO_TRACE(logger_); smart_objects::SmartObject so_applications_data; resumption_storage_->GetDataForLoadResumeData(so_applications_data); @@ -769,8 +776,8 @@ void ResumeCtrl::LoadResumeData() { } } -void ResumeCtrl::OnAppRegistrationStart(const std::string& policy_app_id, - const std::string& device_id) { +void ResumeCtrlImpl::OnAppRegistrationStart(const std::string& policy_app_id, + const std::string& device_id) { LOG4CXX_AUTO_TRACE(logger_); if (IsApplicationSaved(policy_app_id, device_id)) { LOG4CXX_INFO( @@ -781,12 +788,22 @@ void ResumeCtrl::OnAppRegistrationStart(const std::string& policy_app_id, } } -void ResumeCtrl::OnAppRegistrationEnd() { +void ResumeCtrlImpl::OnAppRegistrationEnd() { LOG4CXX_AUTO_TRACE(logger_); StartSavePersistentDataTimer(); } -bool ResumeCtrl::IsAppDataResumptionExpired( +int32_t ResumeCtrlImpl::GetSavedAppHmiLevel( + const std::string& app_id, const std::string& device_id) const { + smart_objects::SmartObject saved_app; + if (resumption_storage_->GetSavedApplication(app_id, device_id, saved_app)) { + const int32_t saved_hmi_level = saved_app[strings::hmi_level].asInt(); + return saved_hmi_level; + } + return static_cast<int32_t>(mobile_apis::HMILevel::INVALID_ENUM); +} + +bool ResumeCtrlImpl::IsAppDataResumptionExpired( const smart_objects::SmartObject& application) const { const int32_t max_ign_off_count = 3; return max_ign_off_count <= application[strings::ign_off_count].asInt(); diff --git a/src/components/application_manager/src/smart_object_keys.cc b/src/components/application_manager/src/smart_object_keys.cc index 8b8c17fc5a..68a3a7d424 100644 --- a/src/components/application_manager/src/smart_object_keys.cc +++ b/src/components/application_manager/src/smart_object_keys.cc @@ -18,6 +18,12 @@ const char* msg_params = "msg_params"; const char* method_name = "methodName"; const char* info = "info"; const char* app_id = "appID"; +const char* bundle_id = "appBundleID"; +const char* app_info = "appInfo"; +const char* app_launch = "app_launch"; +const char* app_launch_list = "app_launch_list"; +const char* app_launch_last_session = "app_launch_last_session"; +const char* policy_app_id = "policyAppID"; const char* hmi_app_id = "hmiAppID"; const char* device_id = "deviceID"; const char* subscribed_for_way_points = "subscribed_for_way_points"; @@ -400,6 +406,4 @@ const char* event_name = "eventName"; } // namespace hmi_notification -} // namespace application_manager - -# +} // namespace application_manager
\ No newline at end of file diff --git a/src/components/application_manager/test/CMakeLists.txt b/src/components/application_manager/test/CMakeLists.txt index 118cda4fcb..cd418bd899 100644 --- a/src/components/application_manager/test/CMakeLists.txt +++ b/src/components/application_manager/test/CMakeLists.txt @@ -170,3 +170,5 @@ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/libPolicy.so add_subdirectory(state_controller) endif() + +add_subdirectory(app_launch) diff --git a/src/components/application_manager/test/app_launch/CMakeLists.txt b/src/components/application_manager/test/app_launch/CMakeLists.txt new file mode 100644 index 0000000000..1c038020b9 --- /dev/null +++ b/src/components/application_manager/test/app_launch/CMakeLists.txt @@ -0,0 +1,62 @@ +# Copyright (c) 2016, Ford Motor Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following +# disclaimer in the documentation and/or other materials provided with the +# distribution. +# +# Neither the name of the Ford Motor Company nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +include_directories( + ${GMOCK_INCLUDE_DIRECTORY} + ${COMPONENTS_DIR}/application_manager/include/ + ${COMPONENTS_DIR}/application_manager/test/include/ + ${COMPONENTS_DIR}/connection_handler/include/ + ${COMPONENTS_DIR}/utils/include/ + ${COMPONENTS_DIR}/include/test + ${COMPONENTS_DIR}/include/ +) + +set(LIBRARIES + gmock + Resumption + jsoncpp + SmartObjects + ApplicationManager +) + + if (ENABLE_LOG) + list(APPEND LIBRARIES log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) + list(APPEND LIBRARIES apr-1 -L${APR_LIBS_DIRECTORY}) + list(APPEND LIBRARIES aprutil-1 -L${APR_UTIL_LIBS_DIRECTORY}) + list(APPEND LIBRARIES expat -L${EXPAT_LIBS_DIRECTORY}) + endif() + +set(APP_LAUNCH_DATA_TEST_SOURCES + app_launch_data_db_test.cc + app_launch_data_json_test.cc +) + +create_test("app_launch_ctrl_test" app_launch_ctrl_test.cc "${LIBRARIES}") +create_test("app_launch_data_test" "${APP_LAUNCH_DATA_TEST_SOURCES}" "${LIBRARIES}") diff --git a/src/components/application_manager/test/app_launch/app_launch_ctrl_test.cc b/src/components/application_manager/test/app_launch/app_launch_ctrl_test.cc new file mode 100644 index 0000000000..0f5196a97e --- /dev/null +++ b/src/components/application_manager/test/app_launch/app_launch_ctrl_test.cc @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "gtest/gtest.h" +#include <sstream> +#include "utils/macro.h" +#include "application_manager/app_launch/app_launch_ctrl_impl.h" +#include "application_manager/mock_app_launch_data.h" +#include "application_manager/mock_app_launch_settings.h" +#include "application_manager/mock_resume_ctrl.h" +#include "application_manager/mock_application.h" +#include "application_manager/mock_application_manager.h" +#include "connection_handler/mock_connection_handler.h" +#include "utils/make_shared.h" + +namespace test { +namespace components { +namespace app_launch_test { +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::Truly; +using ::testing::NiceMock; +using ::testing::Invoke; +using ::testing::AtLeast; +using ::testing::InSequence; + +namespace ch_test = test::components::connection_handler_test; +namespace am_test = test::components::application_manager_test; + +const uint32_t MAX_TEST_DURATION = 1000; // 1 second +typedef utils::SharedPtr<am_test::MockApplication> MockAppPtr; +class AppLaunchCtrlTest : public ::testing::Test { + public: + MockAppPtr AppFromAppData(const app_launch::ApplicationData& app_data) { + utils::SharedPtr<NiceMock<am_test::MockApplication>> app = + utils::MakeShared<NiceMock<am_test::MockApplication>>(); + + ON_CALL(*app, mac_address()).WillByDefault(ReturnRef(app_data.device_mac_)); + ON_CALL(*app, bundle_id()).WillByDefault(ReturnRef(app_data.bundle_id_)); + ON_CALL(*app, policy_app_id()) + .WillByDefault(Return(app_data.mobile_app_id_)); + return app; + } + + app_launch::ApplicationDataPtr AppDataFromApp( + const am_test::MockApplication& app) { + app_launch::ApplicationDataPtr app_data = + utils::MakeShared<NiceMock<app_launch::ApplicationData>>( + app.policy_app_id(), app.bundle_id(), app.mac_address()); + return app_data; + } + + void SetUp() OVERRIDE { + ON_CALL(settings_, app_launch_wait_time()).WillByDefault(Return(5)); + ON_CALL(settings_, app_launch_max_retry_attempt()).WillByDefault(Return(3)); + ON_CALL(settings_, app_launch_retry_wait_time()).WillByDefault(Return(15)); + ON_CALL(settings_, remove_bundle_id_attempts()).WillByDefault(Return(3)); + ON_CALL(settings_, max_number_of_ios_device()).WillByDefault(Return(10)); + ON_CALL(settings_, wait_time_between_apps()).WillByDefault(Return(4)); + ON_CALL(settings_, enable_app_launch_ios()).WillByDefault(Return(true)); + ON_CALL(settings_, resumption_delay_after_ign()).WillByDefault(Return(30)); + ON_CALL(resume_ctrl_mock_, LaunchTime()).WillByDefault(Return(0)); + + ON_CALL(app_mngr_mock_, resume_controller()) + .WillByDefault(ReturnRef(resume_ctrl_mock_)); + ON_CALL(app_mngr_mock_, connection_handler()) + .WillByDefault(ReturnRef(connection_handler_mock_)); + app_launch_ctrl_.reset(new app_launch::AppLaunchCtrlImpl( + app_launch_data_mock_, app_mngr_mock_, settings_)); + FillApplications(); + } + + typedef std::pair<MockAppPtr, app_launch::ApplicationDataPtr> AppAndAppData; + std::vector<AppAndAppData> test_app_datas_; + + app_launch::ApplicationDataPtr GetTestAppData(size_t index) { + return test_app_datas_[index].second; + } + + MockAppPtr GetTestApp(size_t index) { + return test_app_datas_[index].first; + } + + const std::string DeviceMac(size_t device_number) { + std::ostringstream ss; + ss << "device_mac_" << device_number; + return ss.str(); + } + + std::vector<AppAndAppData> DeviceApps(std::string device_mac) { + std::vector<AppAndAppData> res; + std::vector<AppAndAppData>::iterator it = test_app_datas_.begin(); + for (; it != test_app_datas_.end(); ++it) { + const AppAndAppData& app_and_data = *it; + if (app_and_data.second->device_mac_ == device_mac) { + res.push_back(app_and_data); + } + } + return res; + } + + AppAndAppData GetAppAndAppData(const std::string& app_id, + const std::string& bundle_id, + const std::string& device_mac) { + using app_launch::ApplicationData; + AppAndAppData app; + app.second = + utils::MakeShared<ApplicationData>(app_id, bundle_id, device_mac); + app.first = AppFromAppData(*app.second); + return app; + } + + void FillApplications() { + test_app_datas_.push_back( + GetAppAndAppData("mob_id1", "bundle_id1", DeviceMac(1))); + test_app_datas_.push_back( + GetAppAndAppData("mob_id2", "bundle_id2", DeviceMac(1))); + test_app_datas_.push_back( + GetAppAndAppData("mob_id3", "bundle_id3", DeviceMac(1))); + test_app_datas_.push_back( + GetAppAndAppData("mob_id4", "bundle_id4", DeviceMac(2))); + test_app_datas_.push_back( + GetAppAndAppData("mob_id5", "bundle_id5", DeviceMac(2))); + test_app_datas_.push_back( + GetAppAndAppData("mob_id6", "bundle_id6", DeviceMac(3))); + } + + void ExpectRegisteration(const AppAndAppData& app_data); + + NiceMock<am_test::MockApplicationManager> app_mngr_mock_; + NiceMock<app_launch_test::AppLaunchDataMock> app_launch_data_mock_; + NiceMock<ch_test::MockConnectionHandler> connection_handler_mock_; + NiceMock<resumprion_test::MockResumeCtrl> resume_ctrl_mock_; + NiceMock<app_launch_test::MockAppLaunchSettings> settings_; + std::auto_ptr<app_launch::AppLaunchCtrlImpl> app_launch_ctrl_; +}; + +app_launch::ApplicationData AppDataFromApp( + application_manager::Application& app) { + // TODO(AK) Use amc op device + return app_launch::ApplicationData( + app.policy_app_id(), app.bundle_id(), "Dummy Deevice Id"); +} + +struct AppDataComparator { + const app_launch::ApplicationData& app_data_; + + AppDataComparator(const app_launch::ApplicationData& app_data) + : app_data_(app_data) {} + + bool operator()(const app_launch::ApplicationData& app_data) const { + return app_data_ == app_data; + } +}; + +TEST_F(AppLaunchCtrlTest, AddRegisteredApplicationToDataStorage) { + MockAppPtr app = GetTestApp(0); + EXPECT_CALL(app_launch_data_mock_, + AddApplicationData(Truly(AppDataComparator(*GetTestAppData(0))))); + app_launch_ctrl_->OnAppRegistered(*app); +} + +ACTION_P2(InvokeOnAppRegistered, app_launch_ctrl, app) { + (app_launch_ctrl->*&app_launch::AppLaunchCtrlImpl::OnAppRegistered)(*app); +} + +TEST_F(AppLaunchCtrlTest, StoredAppIsLaunchedAfterDeviceConnected) { + std::vector<app_launch::ApplicationDataPtr> applications_on_device; + app_launch::ApplicationDataPtr app_to_launch = GetTestAppData(0); + MockAppPtr app = GetTestApp(0); + + applications_on_device.push_back(app_to_launch); + EXPECT_CALL(app_launch_data_mock_, + GetApplicationDataByDevice(app_to_launch->device_mac_)) + .WillOnce(Return(applications_on_device)); + EXPECT_CALL( + connection_handler_mock_, + RunAppOnDevice(app_to_launch->device_mac_, app_to_launch->bundle_id_)) + .Times(AtLeast(1)) + .WillOnce(InvokeOnAppRegistered(app_launch_ctrl_.get(), app.get())); + app_launch_ctrl_->OnDeviceConnected(app_to_launch->device_mac_); + const uint32_t wait_time = + MAX_TEST_DURATION + settings_.app_launch_wait_time(); + testing::Mock::AsyncVerifyAndClearExpectations(wait_time); +} + +TEST_F(AppLaunchCtrlTest, RelaunchAppIfNotRegisteredMultipleTimes) { + std::vector<app_launch::ApplicationDataPtr> applications_on_device; + app_launch::ApplicationDataPtr app_to_launch = GetTestAppData(0); + applications_on_device.push_back(app_to_launch); + EXPECT_CALL(app_launch_data_mock_, + GetApplicationDataByDevice(app_to_launch->device_mac_)) + .WillOnce(Return(applications_on_device)); + + EXPECT_CALL( + connection_handler_mock_, + RunAppOnDevice(app_to_launch->device_mac_, app_to_launch->bundle_id_)) + .Times(settings_.app_launch_max_retry_attempt()); + + app_launch_ctrl_->OnDeviceConnected(app_to_launch->device_mac_); + const uint32_t wait_time = MAX_TEST_DURATION + + settings_.app_launch_wait_time() + + settings_.app_launch_max_retry_attempt() * + settings_.app_launch_retry_wait_time(); + testing::Mock::AsyncVerifyAndClearExpectations(wait_time); +} + +TEST_F(AppLaunchCtrlTest, LaunchMultipleApps) { + std::vector<AppAndAppData> apps_and_data = DeviceApps(DeviceMac(1)); + std::vector<app_launch::ApplicationDataPtr> apps; + for (std::vector<AppAndAppData>::iterator it = apps_and_data.begin(); + it != apps_and_data.end(); + ++it) { + apps.push_back(it->second); + } + + EXPECT_CALL(app_launch_data_mock_, GetApplicationDataByDevice(DeviceMac(1))) + .WillOnce(Return(apps)); + + // Expect multiple call + for (std::vector<AppAndAppData>::iterator it = apps_and_data.begin(); + it != apps_and_data.end(); + ++it) { + ExpectRegisteration(*it); + } + app_launch_ctrl_->OnDeviceConnected(DeviceMac(1)); + const uint32_t wait_time = MAX_TEST_DURATION + + settings_.app_launch_wait_time() + + apps.size() * settings_.wait_time_between_apps(); + testing::Mock::AsyncVerifyAndClearExpectations(wait_time); +} + +TEST_F(AppLaunchCtrlTest, LaunchMultipleAppsNoRegister) { + std::vector<AppAndAppData> apps_and_data = DeviceApps(DeviceMac(1)); + std::vector<app_launch::ApplicationDataPtr> apps; + for (std::vector<AppAndAppData>::iterator it = apps_and_data.begin(); + it != apps_and_data.end(); + ++it) { + apps.push_back(it->second); + } + + EXPECT_CALL(app_launch_data_mock_, GetApplicationDataByDevice(DeviceMac(1))) + .WillOnce(Return(apps)); + + // Expect multiple call + for (std::vector<AppAndAppData>::iterator it = apps_and_data.begin(); + it != apps_and_data.end(); + ++it) { + const AppAndAppData& app_data = *it; + EXPECT_CALL(connection_handler_mock_, + RunAppOnDevice(app_data.second->device_mac_, + app_data.second->bundle_id_)) + .Times(settings_.app_launch_max_retry_attempt()); + } + app_launch_ctrl_->OnDeviceConnected(DeviceMac(1)); + const uint32_t wait_time = MAX_TEST_DURATION + + settings_.app_launch_wait_time() + + apps.size() * settings_.wait_time_between_apps(); + testing::Mock::AsyncVerifyAndClearExpectations(wait_time); +} + +TEST_F(AppLaunchCtrlTest, LaunchMultipleAppsInHMILevelOrder) { + std::vector<AppAndAppData> apps_and_data = DeviceApps(DeviceMac(1)); + DCHECK(apps_and_data.size() == 3); + std::vector<app_launch::ApplicationDataPtr> apps; + + { + app_launch::ApplicationDataPtr app_data = apps_and_data[0].second; + EXPECT_CALL( + resume_ctrl_mock_, + GetSavedAppHmiLevel(app_data->mobile_app_id_, app_data->device_mac_)) + .WillOnce(Return(mobile_apis::HMILevel::HMI_FULL)); + apps.push_back(app_data); + } + + { + app_launch::ApplicationDataPtr app_data = apps_and_data[1].second; + EXPECT_CALL( + resume_ctrl_mock_, + GetSavedAppHmiLevel(app_data->mobile_app_id_, app_data->device_mac_)) + .WillOnce(Return(mobile_apis::HMILevel::HMI_LIMITED)); + ; + apps.push_back(app_data); + } + + { + app_launch::ApplicationDataPtr app_data = apps_and_data[2].second; + EXPECT_CALL( + resume_ctrl_mock_, + GetSavedAppHmiLevel(app_data->mobile_app_id_, app_data->device_mac_)) + .WillOnce(Return(mobile_apis::HMILevel::HMI_BACKGROUND)); + ; + apps.push_back(app_data); + } + + EXPECT_CALL(app_launch_data_mock_, GetApplicationDataByDevice(DeviceMac(1))) + .WillOnce(Return(apps)); + { + InSequence s; + + ExpectRegisteration(apps_and_data[0]); + ExpectRegisteration(apps_and_data[1]); + ExpectRegisteration(apps_and_data[2]); + } + + app_launch_ctrl_->OnDeviceConnected(DeviceMac(1)); + const uint32_t wait_time = MAX_TEST_DURATION + + settings_.app_launch_wait_time() + + apps.size() * settings_.wait_time_between_apps(); + testing::Mock::AsyncVerifyAndClearExpectations(wait_time); +} + +void AppLaunchCtrlTest::ExpectRegisteration( + const AppLaunchCtrlTest::AppAndAppData& app_data) { + EXPECT_CALL( + connection_handler_mock_, + RunAppOnDevice(app_data.second->device_mac_, app_data.second->bundle_id_)) + .Times(AtLeast(1)) + .WillOnce( + InvokeOnAppRegistered(app_launch_ctrl_.get(), app_data.first.get())); +} + +} // namespace app_launch_test +} // namespace components +} // namespace test diff --git a/src/components/application_manager/test/app_launch/app_launch_data_db_test.cc b/src/components/application_manager/test/app_launch/app_launch_data_db_test.cc new file mode 100644 index 0000000000..e095f0682e --- /dev/null +++ b/src/components/application_manager/test/app_launch/app_launch_data_db_test.cc @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <algorithm> +#include <sstream> +#include <string> +#include <memory> +#include "gtest/gtest.h" +#include "utils/macro.h" +#include "sql_database.h" +#include "sql_query.h" +#include "utils/make_shared.h" +#include "utils/file_system.h" +#include "application_manager/mock_app_launch_settings.h" +#include "application_manager/app_launch/app_launch_data_db.h" +#include "application_manager/app_launch/app_launch_sql_queries.h" + +namespace test { +namespace components { +namespace app_launch_test { + +using namespace file_system; +using namespace app_launch; + +using ::testing::ReturnRef; +using ::testing::Return; +using ::testing::NiceMock; + +namespace { +const std::string kEmptyString = ""; +const std::string kMobileAppId = "mobile_app_id"; +const std::string kBundleId = "bundle_id"; +const std::string kDeviceMac = "device_mac"; +} // namespace + +class AppLaunchDataDBTest : public ::testing::Test { + protected: + virtual void SetUp() { + utils::dbms::SQLQuery query(test_db()); + EXPECT_TRUE(query.Prepare(kCreateSchema)); + EXPECT_TRUE(query.Exec()); + printf("Create table\n"); + } + + virtual void TearDown() { + utils::dbms::SQLQuery query(test_db()); + EXPECT_TRUE(query.Prepare(kDropSchema)); + EXPECT_TRUE(query.Exec()); + printf("Delete table\n"); + } + + static void SetUpTestCase() { + NiceMock<MockAppLaunchSettings> mock_app_launch_settings_; + std::string curr_dir = file_system::CurrentWorkingDirectory(); + ON_CALL(mock_app_launch_settings_, app_storage_folder()) + .WillByDefault(ReturnRef(curr_dir)); + ON_CALL(mock_app_launch_settings_, max_number_of_ios_device()) + .WillByDefault(Return(15u)); + ON_CALL(mock_app_launch_settings_, app_launch_max_retry_attempt()) + .WillByDefault(Return(5u)); + ON_CALL(mock_app_launch_settings_, app_launch_retry_wait_time()) + .WillByDefault(Return(500u)); + if (is_in_file) { + res_db_.reset( + new AppLaunchDataDB(mock_app_launch_settings_, In_File_Storage)); + } else { + res_db_.reset( + new AppLaunchDataDB(mock_app_launch_settings_, In_Memory_Storage)); + } + test_db_ = (res_db_->db()); + + EXPECT_TRUE(test_db()->Open()); + EXPECT_TRUE(test_db()->IsReadWrite()); + } + + // Memory keep and clear AppLaunchDataDb + static utils::dbms::SQLDatabase* test_db_; + + static void TearDownTestCase() { + DeleteFile(kDatabaseName + ".sqlite"); + } + + static utils::dbms::SQLDatabase* test_db() { + return test_db_; + } + + static std::auto_ptr<AppLaunchDataDB> res_db_; + + AppLaunchDataDB* res_db() { + return res_db_.get(); + } + + const std::string kGetSsession = + " SELECT * FROM `app_launch` WHERE `deviceMac` = ? AND `appID` = ? AND " + "`bundleID` = ?;"; + const std::string kCheckTablesExist = + "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND " + "name='app_launch';"; + + const std::string kInsertTimestamp = + "UPDATE 'app_launch' " + "SET 'last_session' = ' 1666-06-16 06:06:06.666 '" + "WHERE `deviceMac` = ? AND `appID` = ? " + "AND `bundleID` = ?;"; + + // Write BD to file or memory + static const bool is_in_file = false; + + public: + void AddApplicationDataWithIncreaseTable(const ApplicationData& data); + void AddApplicationDataWithoutIncreaseTable(const ApplicationData& data); + std::string GetApplicationData(const ApplicationData& in_data, + ApplicationData& out_data); + std::string AddCounter(const std::string& inp, int32_t val); + void AddApplicationData_Expect_FALSE(const ApplicationData& data); +}; + +utils::dbms::SQLDatabase* AppLaunchDataDBTest::test_db_ = NULL; +std::auto_ptr<AppLaunchDataDB> AppLaunchDataDBTest::res_db_; + +void AppLaunchDataDBTest::AddApplicationDataWithIncreaseTable( + const ApplicationData& data) { + uint32_t sizeBeforeAdding = res_db()->GetCurentNumberOfAppData(); + EXPECT_TRUE(res_db()->AddApplicationData(data)); + + uint32_t sizeAfterAdding = res_db()->GetCurentNumberOfAppData(); + EXPECT_EQ(sizeBeforeAdding + 1u, sizeAfterAdding); +} + +void AppLaunchDataDBTest::AddApplicationDataWithoutIncreaseTable( + const ApplicationData& data) { + uint32_t sizeBeforeAdding = res_db()->GetCurentNumberOfAppData(); + EXPECT_TRUE(res_db()->AddApplicationData(data)); + + uint32_t sizeAfterAdding = res_db()->GetCurentNumberOfAppData(); + EXPECT_EQ(sizeBeforeAdding, sizeAfterAdding); +} + +std::string AppLaunchDataDBTest::GetApplicationData( + const ApplicationData& in_data, ApplicationData& out_data) { + utils::dbms::SQLQuery query(test_db()); + uint32_t sizeBeforeAdding = res_db()->GetCurentNumberOfAppData(); + EXPECT_TRUE(query.Prepare(kGetSsession)); + query.Bind(AppLaunchDataDB::device_mac_index, in_data.device_mac_); + query.Bind(AppLaunchDataDB::application_id_index, in_data.mobile_app_id_); + query.Bind(AppLaunchDataDB::bundle_id_index, in_data.bundle_id_); + EXPECT_TRUE(query.Exec()); + + uint32_t sizeAfterAdding = res_db()->GetCurentNumberOfAppData(); + + EXPECT_EQ(sizeBeforeAdding, sizeAfterAdding); + + out_data.device_mac_ = query.GetString(AppLaunchDataDB::device_mac_index); + out_data.mobile_app_id_ = + query.GetString(AppLaunchDataDB::application_id_index); + out_data.bundle_id_ = query.GetString(AppLaunchDataDB::bundle_id_index); + // Timestamp + return query.GetString(AppLaunchDataDB::timestamp_index); +} + +std::string AppLaunchDataDBTest::AddCounter(const std::string& inp, + int32_t val) { + std::stringstream ss; + ss << inp << "_" << val; + return ss.str(); +} + +TEST_F(AppLaunchDataDBTest, Init) { + utils::dbms::SQLQuery query_checks(test_db()); + EXPECT_TRUE(query_checks.Prepare(kCheckTablesExist)); + EXPECT_TRUE(query_checks.Exec()); + EXPECT_EQ(1u, query_checks.GetUInteger(0)); +} + +TEST_F(AppLaunchDataDBTest, SaveAndGetData) { + ApplicationData data(kMobileAppId, kBundleId, kDeviceMac); + AddApplicationDataWithIncreaseTable(data); + ApplicationData recoveredData(kEmptyString, kEmptyString, kEmptyString); + GetApplicationData(data, recoveredData); + EXPECT_TRUE(data == recoveredData); +} + +TEST_F(AppLaunchDataDBTest, NotAddEmptyAppData) { + ApplicationData data1(kEmptyString, kBundleId, kDeviceMac); + ApplicationData data2(kMobileAppId, kEmptyString, kDeviceMac); + ApplicationData data3(kMobileAppId, kBundleId, kEmptyString); + ApplicationData data4(kEmptyString, kEmptyString, kEmptyString); + EXPECT_FALSE(res_db()->AddApplicationData(data1)); + EXPECT_FALSE(res_db()->AddApplicationData(data2)); + EXPECT_FALSE(res_db()->AddApplicationData(data3)); + EXPECT_FALSE(res_db()->AddApplicationData(data4)); + EXPECT_EQ(0u, res_db()->GetCurentNumberOfAppData()); +} + +TEST_F(AppLaunchDataDBTest, SaveOneAndGetAnotherData) { + ApplicationData data(kMobileAppId, kBundleId, kDeviceMac); + ApplicationData recoverData = data; + AddApplicationDataWithIncreaseTable(data); + recoverData.device_mac_ += "test"; + GetApplicationData(recoverData, recoverData); + EXPECT_FALSE(data == recoverData); +} + +TEST_F(AppLaunchDataDBTest, MaxCount) { + const uint32_t max_ios_devs = res_db()->get_max_number_iOS_devs(); + + for (uint32_t i = 0; i < max_ios_devs; i++) { + ApplicationData data( + AddCounter(kMobileAppId, i), AddCounter(kBundleId, i), kDeviceMac); + AddApplicationDataWithIncreaseTable(data); + } + + utils::dbms::SQLQuery query(test_db()); + ApplicationData changedRecord( + AddCounter(kMobileAppId, 0), AddCounter(kBundleId, 0), kDeviceMac); + EXPECT_TRUE(query.Prepare(kInsertTimestamp)); + query.Bind(AppLaunchDataDB::device_mac_index, changedRecord.device_mac_); + query.Bind(AppLaunchDataDB::application_id_index, + changedRecord.mobile_app_id_); + query.Bind(AppLaunchDataDB::bundle_id_index, changedRecord.bundle_id_); + EXPECT_TRUE(query.Exec()); + + uint32_t size_max = res_db()->GetCurentNumberOfAppData(); + EXPECT_EQ(max_ios_devs, size_max); + EXPECT_TRUE(res_db()->AddApplicationData( + ApplicationData(AddCounter(kMobileAppId, max_ios_devs), + AddCounter(kBundleId, max_ios_devs), + kDeviceMac))); + uint32_t size_after_max = res_db()->GetCurentNumberOfAppData(); + EXPECT_EQ(size_max, size_after_max); + EXPECT_FALSE(res_db()->IsAppDataAlreadyExisted(changedRecord)); +} + +namespace { +bool ApplicationDataComporator(const ApplicationDataPtr& left, + const ApplicationDataPtr& right) { + return (left->device_mac_ < right->device_mac_ && + left->mobile_app_id_ < right->mobile_app_id_ && + left->bundle_id_ < right->bundle_id_); +} +} // namespace + +TEST_F(AppLaunchDataDBTest, SelectMultipleData) { + std::vector<ApplicationDataPtr> input_data1; + std::vector<ApplicationDataPtr> input_data2; + std::vector<ApplicationDataPtr> output_data1; + std::vector<ApplicationDataPtr> output_data2; + const std::string device_mac_1 = "device_mac_1"; + const std::string device_mac_2 = "device_mac_2"; + + uint32_t half_of_max_number_iOS_devs = + res_db()->get_max_number_iOS_devs() / 2u; + + for (uint32_t i = 0; i < half_of_max_number_iOS_devs; i++) { + const std::string mobile_app_id = AddCounter("d1_mobile_app_id", i); + const std::string bundle_id = AddCounter("d1_bundle_id", i); + + ApplicationDataPtr app_data = utils::MakeShared<ApplicationData>( + mobile_app_id, bundle_id, device_mac_1); + AddApplicationDataWithIncreaseTable(*app_data); + input_data1.push_back(app_data); + } + + for (uint32_t i = 0; i < half_of_max_number_iOS_devs; i++) { + const std::string mobile_app_id = AddCounter("d2_mobile_app_id", i); + const std::string bundle_id = AddCounter("d2_bundle_id", i); + + ApplicationDataPtr app_data = utils::MakeShared<ApplicationData>( + mobile_app_id, bundle_id, device_mac_2); + AddApplicationDataWithIncreaseTable(*app_data); + input_data2.push_back(app_data); + } + + output_data1 = res_db()->GetApplicationDataByDevice(device_mac_1); + output_data2 = res_db()->GetApplicationDataByDevice(device_mac_2); + + EXPECT_EQ(half_of_max_number_iOS_devs, output_data1.size()); + EXPECT_EQ(half_of_max_number_iOS_devs, output_data2.size()); + + std::sort( + output_data1.begin(), output_data1.end(), ApplicationDataComporator); + std::sort( + output_data2.begin(), output_data2.end(), ApplicationDataComporator); + std::sort(input_data1.begin(), input_data1.end(), ApplicationDataComporator); + std::sort(input_data2.begin(), input_data2.end(), ApplicationDataComporator); + + for (uint32_t i = 0; i < output_data1.size(); i++) { + EXPECT_TRUE(*output_data1[i] == *input_data1[i]); + } + + for (uint32_t i = 0; i < output_data2.size(); i++) { + EXPECT_TRUE(*output_data2[i] == *input_data2[i]); + } +} + +// Most be last cause after it AppLaunchDataDBTest +// requeste manual Init call +TEST_F(AppLaunchDataDBTest, DeleteAllTableDataTwice) { + for (uint32_t i = 0; i < res_db()->get_max_number_iOS_devs(); i++) { + ApplicationData data( + AddCounter(kMobileAppId, i), AddCounter(kBundleId, i), kDeviceMac); + AddApplicationDataWithIncreaseTable(data); + } + + uint32_t full_size = res_db()->GetCurentNumberOfAppData(); + + EXPECT_EQ(full_size, res_db()->get_max_number_iOS_devs()); + EXPECT_TRUE(res_db()->Clear()); // delete data + EXPECT_EQ(0u, res_db()->GetCurentNumberOfAppData()); + EXPECT_TRUE(res_db()->Clear()); // second time delete data + EXPECT_EQ(0u, res_db()->GetCurentNumberOfAppData()); +} + +} // namespace app_launch_test +} // namespace components +} // namespace test diff --git a/src/components/application_manager/test/app_launch/app_launch_data_json_test.cc b/src/components/application_manager/test/app_launch/app_launch_data_json_test.cc new file mode 100644 index 0000000000..6b00365dd3 --- /dev/null +++ b/src/components/application_manager/test/app_launch/app_launch_data_json_test.cc @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <algorithm> +#include <sstream> +#include <memory> +#include "json/json.h" +#include "gtest/gtest.h" +#include "utils/macro.h" +#include "utils/make_shared.h" +#include "utils/file_system.h" +#include "utils/date_time.h" +#include "resumption/last_state.h" +#include "smart_objects/smart_object.h" +#include "application_manager/smart_object_keys.h" +#include "application_manager/mock_app_launch_settings.h" +#include "application_manager/app_launch/app_launch_data_json.h" + +namespace test { +namespace components { +namespace test_app_launch { + +using ::testing::_; +using ::testing::Return; +using ::testing::NiceMock; + +namespace am = application_manager; +using namespace Json; +using namespace file_system; + +using namespace app_launch; + +const std::string kAppStorageFolder = "app_storage_folder"; +const std::string kAppStorageFile = "./app_info.dat"; +const std::string kAppInfoStorage = "app_info_storage"; + +class AppLaunchDataJsonTest : public ::testing::Test { + private: + virtual void SetUp() { + ::file_system::DeleteFile(kAppStorageFile); + test_last_state_ = std::auto_ptr<resumption::LastState>( + new resumption::LastState(kAppStorageFolder, kAppInfoStorage)); + ASSERT_TRUE(::file_system::CreateFile(kAppStorageFile)); + + NiceMock<app_launch_test::MockAppLaunchSettings> mock_app_launch_settings_; + ON_CALL(mock_app_launch_settings_, max_number_of_ios_device()) + .WillByDefault(Return(15u)); + + res_json_.reset( + new AppLaunchDataJson(mock_app_launch_settings_, *test_last_state_)); + } + + public: + void TearDown() OVERRIDE { + res_json_.get()->Clear(); + } + + static void SetUpTestCase() {} + + static void TearDownTestCase() { + ::file_system::DeleteFile(kAppStorageFile); + ::file_system::RemoveDirectory(kAppStorageFolder); + } + + AppLaunchDataJson* res_json() { + return res_json_.get(); + } + + void AddApplicationDataWithIncreaseTable(const ApplicationData& data); + void AddApplicationDataWithoutIncreaseTable(const ApplicationData& data); + TimevalStruct GetApplicationData_EXPECT_TRUE(const ApplicationData& in_data, + ApplicationData& out_data); + void GetApplicationData_EXPECT_FALSE(const ApplicationData& in_data); + std::string AddCounter(const std::string& inp, int32_t val); + + std::auto_ptr<resumption::LastState> test_last_state_; + std::auto_ptr<AppLaunchDataJson> res_json_; + void SetTimestamp(const ApplicationData& in_data, TimevalStruct& timestamp); +}; + +void AppLaunchDataJsonTest::AddApplicationDataWithIncreaseTable( + const ApplicationData& data) { + uint32_t sizeBeforeAdding = res_json()->GetCurentNumberOfAppData(); + + EXPECT_TRUE(res_json()->AddApplicationData(data)); + + uint32_t sizeAfterAdding = res_json()->GetCurentNumberOfAppData(); + + EXPECT_EQ(sizeBeforeAdding + 1u, sizeAfterAdding); +} + +void AppLaunchDataJsonTest::AddApplicationDataWithoutIncreaseTable( + const ApplicationData& data) { + uint32_t sizeBeforeAdding = res_json()->GetCurentNumberOfAppData(); + + EXPECT_TRUE(res_json()->AddApplicationData(data)); + + uint32_t sizeAfterAdding = res_json()->GetCurentNumberOfAppData(); + + EXPECT_EQ(sizeBeforeAdding, sizeAfterAdding); +} + +TimevalStruct AppLaunchDataJsonTest::GetApplicationData_EXPECT_TRUE( + const ApplicationData& in_data, ApplicationData& out_data) { + uint32_t sizeBeforeGetting = res_json()->GetCurentNumberOfAppData(); + + int32_t index = NotFound; + Json::Value& json_data_list = + res_json()->GetApplicationListAndIndex(in_data, index); + EXPECT_FALSE(index == NotFound); + + uint32_t sizeAfterGetting = res_json()->GetCurentNumberOfAppData(); + + EXPECT_EQ(sizeBeforeGetting, sizeAfterGetting); + out_data.device_mac_ = + json_data_list[index][am::strings::device_id].asString(); + out_data.mobile_app_id_ = + json_data_list[index][am::strings::app_id].asString(); + out_data.bundle_id_ = + json_data_list[index][am::strings::bundle_id].asString(); + // time stamp + TimevalStruct tmVal = {0}; + tmVal.tv_sec = + json_data_list[index][am::strings::app_launch_last_session].asUInt64(); + return tmVal; +} + +void AppLaunchDataJsonTest::GetApplicationData_EXPECT_FALSE( + const ApplicationData& in_data) { + uint32_t sizeBeforeGetting = res_json()->GetCurentNumberOfAppData(); + + int32_t index = NotFound; + res_json()->GetApplicationListAndIndex(in_data, index); + EXPECT_TRUE(index == NotFound); + + uint32_t sizeAfterGetting = res_json()->GetCurentNumberOfAppData(); + + EXPECT_EQ(sizeBeforeGetting, sizeAfterGetting); +} + +void AppLaunchDataJsonTest::SetTimestamp(const ApplicationData& in_data, + TimevalStruct& timestamp) { + uint32_t sizeBeforeGetting = res_json()->GetCurentNumberOfAppData(); + + int32_t index = NotFound; + Json::Value& json_data_list = + res_json()->GetApplicationListAndIndex(in_data, index); + EXPECT_FALSE(index == NotFound); + + uint32_t sizeAfterGetting = res_json()->GetCurentNumberOfAppData(); + + EXPECT_FALSE(index == NotFound); + + EXPECT_EQ(sizeBeforeGetting, sizeAfterGetting); + // time stamp + json_data_list[index][am::strings::app_launch_last_session] = + static_cast<Json::Value::UInt64>(timestamp.tv_sec); +} + +std::string AppLaunchDataJsonTest::AddCounter(const std::string& inp, + int32_t val) { + std::stringstream ss; + ss << inp << val; + return ss.str(); +} + +TEST_F(AppLaunchDataJsonTest, SaveAndGetData) { + ApplicationData data("mobile_app_id", "bundle_id", "device_mac"); + AddApplicationDataWithIncreaseTable(data); + ApplicationData recoveredData("", "", ""); + GetApplicationData_EXPECT_TRUE(data, recoveredData); + EXPECT_TRUE(data == recoveredData); +} + +TEST_F(AppLaunchDataJsonTest, NotAddEmptyAppData) { + ApplicationData data1("", "bundle_id", "device_mac"); + ApplicationData data2("mobile_app_id", "", "device_mac"); + ApplicationData data3("mobile_app_id", "bundle_id", ""); + ApplicationData data4("", "", ""); + EXPECT_FALSE(res_json()->AddApplicationData(data1)); + EXPECT_FALSE(res_json()->AddApplicationData(data2)); + EXPECT_FALSE(res_json()->AddApplicationData(data3)); + EXPECT_FALSE(res_json()->AddApplicationData(data4)); + EXPECT_EQ(0u, res_json()->GetCurentNumberOfAppData()); +} + +TEST_F(AppLaunchDataJsonTest, SaveOneAndGetAnotherData) { + ApplicationData data("mobile_app_id", "bundle_id", "device_mac"); + ApplicationData recoverData = data; + AddApplicationDataWithIncreaseTable(data); + recoverData.device_mac_ += "test"; + GetApplicationData_EXPECT_FALSE(recoverData); +} + +TEST_F(AppLaunchDataJsonTest, RefreshTimestamp) { + ApplicationData data("mobile_app_id", "bundle_id", "device_mac"); + AddApplicationDataWithIncreaseTable(data); + ApplicationData recoveredData("", "", ""); + TimevalStruct timestamp1 = + GetApplicationData_EXPECT_TRUE(data, recoveredData); + TimevalStruct tm = {0, 0}; + SetTimestamp(data, tm); + TimevalStruct timestamp2 = + GetApplicationData_EXPECT_TRUE(data, recoveredData); + EXPECT_NE(timestamp1.tv_sec, timestamp2.tv_sec); + AddApplicationDataWithoutIncreaseTable(data); // again insert the same + TimevalStruct timestamp3 = + GetApplicationData_EXPECT_TRUE(data, recoveredData); + EXPECT_TRUE(data == recoveredData); + EXPECT_NE(timestamp2.tv_sec, timestamp3.tv_sec); +} + +TEST_F(AppLaunchDataJsonTest, MaxCount) { + const uint32_t max_ios_devs = res_json()->get_max_number_iOS_devs(); + for (uint32_t i = 0; i < max_ios_devs; i++) { + ApplicationData data(AddCounter("mobile_app_id_", i), + AddCounter("bundle_id_", i), + "device_mac"); + AddApplicationDataWithIncreaseTable(data); + } + + // insert new time stamp + ApplicationData changedRecord("mobile_app_id_0", "bundle_id_0", "device_mac"); + TimevalStruct tm = {0, 0}; + SetTimestamp(changedRecord, tm); + + uint32_t size_max = res_json()->GetCurentNumberOfAppData(); + EXPECT_EQ(max_ios_devs, size_max); + EXPECT_TRUE(res_json()->AddApplicationData(ApplicationData( + "mobile_app_id_last", "bundle_id_last", "device_mac_last"))); + uint32_t size_after_max = res_json()->GetCurentNumberOfAppData(); + EXPECT_EQ(size_max, size_after_max); + EXPECT_FALSE(res_json()->IsAppDataAlreadyExisted(changedRecord)); +} + +TEST_F(AppLaunchDataJsonTest, DeleteAllJsonDataTwice) { + for (uint32_t i = 0; i < res_json()->get_max_number_iOS_devs(); i++) { + ApplicationData data(AddCounter("mobile_app_id_", i), + AddCounter("bundle_id_", i), + "device_mac"); + AddApplicationDataWithIncreaseTable(data); + } + + uint32_t full_size = res_json()->GetCurentNumberOfAppData(); + + EXPECT_EQ(full_size, res_json()->get_max_number_iOS_devs()); + EXPECT_TRUE(res_json()->Clear()); // delete data + EXPECT_EQ(0u, res_json()->GetCurentNumberOfAppData()); + EXPECT_TRUE(res_json()->Clear()); // second time delete data + EXPECT_EQ(0u, res_json()->GetCurentNumberOfAppData()); +} + +namespace { +bool ApplicationDataComporator(const ApplicationDataPtr& left, + const ApplicationDataPtr& right) { + return (left->device_mac_ < right->device_mac_ && + left->mobile_app_id_ < right->mobile_app_id_ && + left->bundle_id_ < right->bundle_id_); +} +} // namespace + +TEST_F(AppLaunchDataJsonTest, SelectMultipleData) { + std::vector<ApplicationDataPtr> input_data1; + std::vector<ApplicationDataPtr> input_data2; + std::vector<ApplicationDataPtr> output_data1; + std::vector<ApplicationDataPtr> output_data2; + const std::string device_mac_1 = "device_mac_1"; + const std::string device_mac_2 = "device_mac_2"; + uint32_t half_part = res_json()->get_max_number_iOS_devs() / 2u; + + for (uint32_t i = 0; i < half_part; i++) { + const std::string mobile_app_id = AddCounter("d1_mobile_app_id_", i); + const std::string bundle_id = AddCounter("d1_bundle_id_", i); + + ApplicationDataPtr app_data = utils::MakeShared<ApplicationData>( + mobile_app_id, bundle_id, device_mac_1); + AddApplicationDataWithIncreaseTable(*app_data); + input_data1.push_back(app_data); + } + + for (uint32_t i = 0; i < half_part; i++) { + const std::string mobile_app_id = AddCounter("d2_mobile_app_id_", i); + const std::string bundle_id = AddCounter("d2_bundle_id_", i); + + ApplicationDataPtr app_data = utils::MakeShared<ApplicationData>( + mobile_app_id, bundle_id, device_mac_2); + AddApplicationDataWithIncreaseTable(*app_data); + input_data2.push_back(app_data); + } + + output_data1 = res_json()->GetApplicationDataByDevice(device_mac_1); + output_data2 = res_json()->GetApplicationDataByDevice(device_mac_2); + + EXPECT_EQ(half_part, output_data1.size()); + EXPECT_EQ(half_part, output_data2.size()); + + std::sort( + output_data1.begin(), output_data1.end(), ApplicationDataComporator); + std::sort( + output_data2.begin(), output_data2.end(), ApplicationDataComporator); + std::sort(input_data1.begin(), input_data1.end(), ApplicationDataComporator); + std::sort(input_data2.begin(), input_data2.end(), ApplicationDataComporator); + + for (uint32_t i = 0; i < output_data1.size(); i++) { + EXPECT_TRUE(*output_data1[i] == *input_data1[i]); + } + + for (uint32_t i = 0; i < output_data2.size(); i++) { + EXPECT_TRUE(*output_data2[i] == *input_data2[i]); + } +} + +} // namespace app_launch +} // namespace components +} // namespace test diff --git a/src/components/application_manager/test/hmi_capabilities_test.cc b/src/components/application_manager/test/hmi_capabilities_test.cc index 1ed2123eba..3f14981f7f 100644 --- a/src/components/application_manager/test/hmi_capabilities_test.cc +++ b/src/components/application_manager/test/hmi_capabilities_test.cc @@ -30,6 +30,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include <string> + #include "application_manager/hmi_capabilities.h" #include "gtest/gtest.h" #include "smart_objects/smart_object.h" @@ -62,14 +64,16 @@ using namespace application_manager; class HMICapabilitiesTest : public ::testing::Test { protected: - HMICapabilitiesTest() : last_state_("app_storage_folder", "app_info_data") {} + HMICapabilitiesTest() + : last_state_("app_storage_folder", "app_info_data") + , file_name_("hmi_capabilities.json") {} virtual void SetUp() OVERRIDE { EXPECT_CALL(app_mngr_, event_dispatcher()) .WillOnce(ReturnRef(mock_event_dispatcher)); EXPECT_CALL(app_mngr_, get_settings()) .WillRepeatedly(ReturnRef(mock_application_manager_settings_)); EXPECT_CALL(mock_application_manager_settings_, - hmi_capabilities_file_name()).WillOnce(ReturnRef(kFileName)); + hmi_capabilities_file_name()).WillOnce(ReturnRef(file_name_)); EXPECT_CALL(mock_event_dispatcher, add_observer(_, _, _)).Times(1); EXPECT_CALL(mock_event_dispatcher, remove_observer(_)).Times(1); EXPECT_CALL(mock_application_manager_settings_, launch_hmi()) @@ -94,7 +98,7 @@ class HMICapabilitiesTest : public ::testing::Test { resumption::LastState last_state_; MockApplicationManagerSettings mock_application_manager_settings_; utils::SharedPtr<HMICapabilitiesForTesting> hmi_capabilities_test; - const std::string kFileName = "hmi_capabilities.json"; + const std::string file_name_; }; const char* const cstring_values_[] = { @@ -349,29 +353,6 @@ TEST_F(HMICapabilitiesTest, LoadCapabilitiesFromFile) { EXPECT_EQ("SE", vehicle_type_so["trim"].asString()); } -TEST_F(HMICapabilitiesTest, ConvertJsonLanguagesToObj) { - Json::Value json_languages(Json::arrayValue); - json_languages[0] = "EN_US"; - json_languages[1] = "ES_MX"; - smart_objects::SmartObject sm_obj = - smart_objects::SmartObject(smart_objects::SmartType_Array); - - EXPECT_CALL(*(MockMessageHelper::message_helper_mock()), - CommonLanguageFromString(json_languages[0].asString())) - .WillOnce(Return(hmi_apis::Common_Language::EN_US)); - - EXPECT_CALL(*(MockMessageHelper::message_helper_mock()), - CommonLanguageFromString(json_languages[1].asString())) - .WillOnce(Return(hmi_apis::Common_Language::ES_MX)); - - hmi_capabilities_test->ConvertJsonLanguagesToObj(json_languages, sm_obj); - - EXPECT_EQ(hmi_apis::Common_Language::EN_US, - static_cast<hmi_apis::Common_Language::eType>(sm_obj[0].asInt())); - EXPECT_EQ(hmi_apis::Common_Language::ES_MX, - static_cast<hmi_apis::Common_Language::eType>(sm_obj[1].asInt())); -} - TEST_F(HMICapabilitiesTest, HmiCapabilitiesInitialized_UiVrTtsIviNotCooperating) { // Precondition diff --git a/src/components/application_manager/test/include/application_manager/hmi_capabilities_for_testing.h b/src/components/application_manager/test/include/application_manager/hmi_capabilities_for_testing.h index ec8e92e859..9764a9997f 100644 --- a/src/components/application_manager/test/include/application_manager/hmi_capabilities_for_testing.h +++ b/src/components/application_manager/test/include/application_manager/hmi_capabilities_for_testing.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,26 +33,20 @@ #ifndef SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_HMI_CAPABILITIES_FOR_TESTING_H_ #define SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_HMI_CAPABILITIES_FOR_TESTING_H_ -#include "application_manager/hmi_capabilities.h" +#include "application_manager/hmi_capabilities_impl.h" namespace test { namespace components { namespace application_manager_test { class HMICapabilitiesForTesting - : public ::application_manager::HMICapabilities { + : public ::application_manager::HMICapabilitiesImpl { public: HMICapabilitiesForTesting(::application_manager::ApplicationManager& app_mngr) - : HMICapabilities(app_mngr) {} + : HMICapabilitiesImpl(app_mngr) {} bool LoadCapabilitiesFromFile() { return load_capabilities_from_file(); } - - void ConvertJsonLanguagesToObj( - Json::Value& json_languages, - ::NsSmartDeviceLink::NsSmartObjects::SmartObject& languages) { - convert_json_languages_to_obj(json_languages, languages); - } }; } // namespace application_manager_test diff --git a/src/components/application_manager/test/include/application_manager/mock_app_launch_ctrl.h b/src/components/application_manager/test/include/application_manager/mock_app_launch_ctrl.h new file mode 100644 index 0000000000..181b8c4691 --- /dev/null +++ b/src/components/application_manager/test/include/application_manager/mock_app_launch_ctrl.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_APP_LAUNCH_CTRL_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_APP_LAUNCH_CTRL_H_ + +#include "application_manager/app_launch/app_launch_ctrl.h" + +namespace test { +namespace components { +namespace app_launch_test { + +class AppLaunchCtrlMock : public app_launch::AppLaunchCtrl {}; + +} // namespace app_launch_test +} // namespace components +} // namespace test + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_APP_LAUNCH_CTRL_H_ diff --git a/src/components/application_manager/test/include/application_manager/mock_app_launch_data.h b/src/components/application_manager/test/include/application_manager/mock_app_launch_data.h new file mode 100644 index 0000000000..881ebb2575 --- /dev/null +++ b/src/components/application_manager/test/include/application_manager/mock_app_launch_data.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_APP_LAUNCH_DATA_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_APP_LAUNCH_DATA_H_ + +#include "gmock/gmock.h" +#include "application_manager/app_launch/app_launch_data.h" + +namespace test { +namespace components { +namespace app_launch_test { + +class AppLaunchDataMock : public app_launch::AppLaunchData { + // AppLaunchData interface + public: + MOCK_METHOD1(AddApplicationData, bool(const app_launch::ApplicationData&)); + MOCK_METHOD1(GetApplicationDataByDevice, + std::vector<app_launch::ApplicationDataPtr>(const std::string&)); + MOCK_METHOD0(Clear, bool()); + MOCK_METHOD0(Persist, bool()); +}; + +} // namespace app_launch_test +} // namespace components +} // namespace test + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_APP_LAUNCH_DATA_H_ diff --git a/src/components/application_manager/test/include/application_manager/mock_application.h b/src/components/application_manager/test/include/application_manager/mock_application.h index 066ad9baae..a6f86eafa0 100644 --- a/src/components/application_manager/test/include/application_manager/mock_application.h +++ b/src/components/application_manager/test/include/application_manager/mock_application.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2016, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,6 +36,7 @@ #include "application_manager/application.h" #include "smart_objects/smart_object.h" #include "utils/custom_string.h" +#include "application_manager/usage_statistics.h" namespace test { namespace components { @@ -271,6 +272,8 @@ class MockApplication : public ::application_manager::Application { MOCK_CONST_METHOD0(is_reset_global_properties_active, bool()); MOCK_CONST_METHOD0(app_id, uint32_t()); MOCK_CONST_METHOD0(mac_address, const std::string&()); + MOCK_CONST_METHOD0(bundle_id, const std::string&()); + MOCK_METHOD1(set_bundle_id, void(const std::string& bundle_id)); MOCK_METHOD0(GetAvailableDiskSpace, uint32_t()); MOCK_METHOD1(set_mobile_app_id, void(const std::string& policy_app_id)); MOCK_CONST_METHOD0(is_foreground, bool()); diff --git a/src/components/application_manager/test/include/application_manager/mock_application_manager.h b/src/components/application_manager/test/include/application_manager/mock_application_manager.h index 6ad8aeb250..f334093b5e 100644 --- a/src/components/application_manager/test/include/application_manager/mock_application_manager.h +++ b/src/components/application_manager/test/include/application_manager/mock_application_manager.h @@ -47,6 +47,9 @@ #include "application_manager/state_controller.h" #include "resumption/last_state.h" #include "interfaces/MOBILE_API.h" +#include "application_manager/app_launch/app_launch_ctrl.h" +#include "application_manager/event_engine/event_dispatcher.h" +#include "application_manager/state_controller.h" namespace test { namespace components { @@ -197,6 +200,7 @@ class MockApplicationManager : public application_manager::ApplicationManager { bool(uint32_t connection_key, const std::string& policy_app_id)); MOCK_METHOD0(resume_controller, resumption::ResumeCtrl&()); + MOCK_METHOD0(app_launch_ctrl, app_launch::AppLaunchCtrl&()); MOCK_METHOD1( GetDeviceTransportType, hmi_apis::Common_TransportType::eType(const std::string& transport_type)); diff --git a/src/components/application_manager/test/include/application_manager/mock_resume_ctrl.h b/src/components/application_manager/test/include/application_manager/mock_resume_ctrl.h new file mode 100644 index 0000000000..b06b207f84 --- /dev/null +++ b/src/components/application_manager/test/include/application_manager/mock_resume_ctrl.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_RESUME_CTRL_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_RESUME_CTRL_H_ +#include "gmock/gmock.h" +#include "application_manager/resumption/resume_ctrl.h" +#include "application_manager/application.h" +#include "resumption/last_state.h" + +namespace test { +namespace components { +namespace resumprion_test { + +class MockResumeCtrl : public resumption::ResumeCtrl { + public: + MOCK_METHOD0(SaveAllApplications, void()); + MOCK_METHOD1(SaveApplication, + void(app_mngr::ApplicationSharedPtr application)); + MOCK_METHOD1(RemoveApplicationFromSaved, + bool(app_mngr::ApplicationConstSharedPtr application)); + MOCK_METHOD0(OnSuspend, void()); + MOCK_METHOD0(OnAwake, void()); + MOCK_METHOD0(StopSavePersistentDataTimer, void()); + MOCK_METHOD2(StartResumption, + bool(app_mngr::ApplicationSharedPtr application, + const std::string& hash)); + MOCK_METHOD1(StartResumptionOnlyHMILevel, + bool(app_mngr::ApplicationSharedPtr application)); + MOCK_METHOD1(CheckPersistenceFilesForResumption, + bool(app_mngr::ApplicationSharedPtr application)); + MOCK_METHOD2(CheckApplicationHash, + bool(app_mngr::ApplicationSharedPtr application, + const std::string& hash)); + MOCK_METHOD1(IsHMIApplicationIdExist, bool(uint32_t hmi_app_id)); + MOCK_METHOD2(IsApplicationSaved, + bool(const std::string& policy_app_id, + const std::string& device_id)); + MOCK_CONST_METHOD2(GetHMIApplicationID, + uint32_t(const std::string& policy_app_id, + const std::string& device_id)); + MOCK_METHOD0(ApplicationsDataUpdated, void()); + MOCK_METHOD0(ResetLaunchTime, void()); + MOCK_METHOD1(OnAppActivated, + void(app_mngr::ApplicationSharedPtr application)); + MOCK_METHOD1(RemoveFromResumption, void(uint32_t app_id)); + MOCK_METHOD1(Init, bool(resumption::LastState& last_state)); + MOCK_METHOD2(OnAppRegistrationStart, + void(const std::string& policy_app_id, + const std::string& device_id)); + MOCK_METHOD0(OnAppRegistrationEnd, void()); + MOCK_CONST_METHOD2(GetSavedAppHmiLevel, + int32_t(const std::string&, const std::string&)); + MOCK_METHOD1(RestoreAppHMIState, + bool(application_manager::ApplicationSharedPtr application)); + MOCK_METHOD1(SetupDefaultHMILevel, + bool(application_manager::ApplicationSharedPtr application)); + MOCK_METHOD1(StartAppHmiStateResumption, + void(application_manager::ApplicationSharedPtr application)); + MOCK_METHOD3(SetAppHMIState, + bool(application_manager::ApplicationSharedPtr application, + const mobile_apis::HMILevel::eType hmi_level, + bool check_policy)); + MOCK_CONST_METHOD0(LaunchTime, time_t()); + +#ifdef BUILD_TESTS + MOCK_METHOD1(set_resumption_storage, + void(utils::SharedPtr<resumption::ResumptionData> mock_storage)); +#endif // BUILD_TESTS +}; + +} // namespace resumprion_test +} // namespace components +} // namespace test + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_RESUME_CTRL_H_ diff --git a/src/components/application_manager/test/resumption/resume_ctrl_test.cc b/src/components/application_manager/test/resumption/resume_ctrl_test.cc index 9857072674..16bf968da2 100644 --- a/src/components/application_manager/test/resumption/resume_ctrl_test.cc +++ b/src/components/application_manager/test/resumption/resume_ctrl_test.cc @@ -30,10 +30,11 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "application_manager/resumption/resume_ctrl.h" #include <string> #include <algorithm> + #include "gtest/gtest.h" +#include "application_manager/resumption/resume_ctrl_impl.h" #include "application_manager/usage_statistics.h" #include "application_manager/mock_application.h" #include "application_manager/mock_resumption_data.h" @@ -85,7 +86,7 @@ class ResumeCtrlTest : public ::testing::Test { ::utils::MakeShared<NiceMock<resumption_test::MockResumptionData>>( app_mngr_); app_mock = utils::MakeShared<NiceMock<MockApplication>>(); - res_ctrl = utils::MakeShared<ResumeCtrl>(app_mngr_); + res_ctrl = utils::MakeShared<ResumeCtrlImpl>(app_mngr_); res_ctrl->set_resumption_storage(mock_storage); ON_CALL(app_mngr_, state_controller()) diff --git a/src/components/application_manager/test/smartDeviceLink_test.ini b/src/components/application_manager/test/smartDeviceLink_test.ini index c544a6e02d..48f4d2c808 100644 --- a/src/components/application_manager/test/smartDeviceLink_test.ini +++ b/src/components/application_manager/test/smartDeviceLink_test.ini @@ -37,3 +37,19 @@ AttemptsToOpenResumptionDB = 5 # Timeout between attempts during opening DB in milliseconds OpenAttemptTimeoutMsResumptionDB = 500 + +[AppLaunch] +; time in milliseconds started from device connection - after expiring SDL remotely launches all known not-yet-registered apps from this device +AppLaunchWaitTime = 5000 +; the number of times SDL attempts to launch an application after device connection - applied separately to each application from the given device +AppLaunchMaxRetryAttempt = 3 +; time in milliseconds started by SDL after app launch request. if expired and app did not register, SDL sends new launch request. applied separately to each app +AppLaunchRetryWaitTime = 15000 +; the number of the given device connections that the requested application failed to register after SDL's launch attempts - SDL removes app's bundleID on "value + 1" device connection +RemoveBundleIDattempts = 3 +; the maximum number of iOS devices for which entries can be remembered by SDL +MaxNumberOfiOSDevice = 10 +; time in milliseconds started after request to launch the first app. after either expires or the first app registers SDL requests to launch the second app. +WaitTimeBetweenApps = 4000 +; App Launch on iOS devices SDL feature enabler/disabler +EnableAppLaunchIOS = true diff --git a/src/components/config_profile/include/config_profile/profile.h b/src/components/config_profile/include/config_profile/profile.h index 5abf8a9f78..14983a46b2 100644 --- a/src/components/config_profile/include/config_profile/profile.h +++ b/src/components/config_profile/include/config_profile/profile.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -271,13 +271,13 @@ class Profile : public protocol_handler::ProtocolHandlerSettings, * @brief Returns timeout for SDL to wait for the next package of raw data * over audio service */ - const std::uint32_t audio_data_stopped_timeout() const; + const uint32_t audio_data_stopped_timeout() const; /** * @brief Returns timeout for SDL to wait for the next package of raw data * over video service */ - const std::uint32_t video_data_stopped_timeout() const; + const uint32_t video_data_stopped_timeout() const; /** * @brief Returns allowable max amount of requests per time scale for @@ -560,7 +560,7 @@ class Profile : public protocol_handler::ProtocolHandlerSettings, uint32_t resumption_delay_before_ign() const; - uint32_t resumption_delay_after_ign() const; + const uint32_t resumption_delay_after_ign() const; uint32_t hash_string_size() const; @@ -582,6 +582,44 @@ class Profile : public protocol_handler::ProtocolHandlerSettings, */ uint16_t open_attempt_timeout_ms_resumption_db() const; + /** + * @brief Returns wait time after device connection + * before app launch request + */ + const uint16_t app_launch_wait_time() const OVERRIDE; + + /** + * @brief Returns max number of attempts to launch an application + * after device connection + */ + const uint16_t app_launch_max_retry_attempt() const OVERRIDE; + + /** + * @brief Returns wait time before next app launch request + */ + const uint16_t app_launch_retry_wait_time() const OVERRIDE; + + /** + * @brief Returns max number of failed iOS app + * registration requests + */ + const uint16_t remove_bundle_id_attempts() const OVERRIDE; + + /** + * @brief Returns max number of iOS devices to be stored + */ + const uint16_t max_number_of_ios_device() const OVERRIDE; + + /** + * @brief Returns wait time before attempt to launch next app + */ + const uint16_t wait_time_between_apps() const OVERRIDE; + + /** + * @brief Returns status of feature of app launch on iOS + */ + const bool enable_app_launch_ios() const OVERRIDE; + /* * @brief Updates all related values from ini file */ @@ -752,8 +790,8 @@ class Profile : public protocol_handler::ProtocolHandlerSettings, std::string system_files_path_; uint16_t transport_manager_tcp_adapter_port_; std::string tts_delimiter_; - std::uint32_t audio_data_stopped_timeout_; - std::uint32_t video_data_stopped_timeout_; + uint32_t audio_data_stopped_timeout_; + uint32_t video_data_stopped_timeout_; std::string mme_db_name_; std::string event_mq_name_; std::string ack_mq_name_; @@ -810,6 +848,13 @@ class Profile : public protocol_handler::ProtocolHandlerSettings, bool use_db_for_resumption_; uint16_t attempts_to_open_resumption_db_; uint16_t open_attempt_timeout_ms_resumption_db_; + uint16_t app_launch_wait_time_; + uint16_t app_launch_max_retry_attempt_; + uint16_t app_launch_retry_wait_time_; + uint16_t remove_bundle_id_attempts_; + uint16_t max_number_of_ios_device_; + uint16_t wait_time_between_apps_; + bool enable_app_launch_ios_; DISALLOW_COPY_AND_ASSIGN(Profile); }; diff --git a/src/components/config_profile/src/profile.cc b/src/components/config_profile/src/profile.cc index 4eacbe88ec..1a38b77254 100644 --- a/src/components/config_profile/src/profile.cc +++ b/src/components/config_profile/src/profile.cc @@ -84,6 +84,7 @@ const char* kIAPSection = "IAP"; const char* kProtocolHandlerSection = "ProtocolHandler"; const char* kSDL4Section = "SDL4"; const char* kResumptionSection = "Resumption"; +const char* kAppLaunchSection = "AppLaunch"; const char* kSDLVersionKey = "SDLVersion"; const char* kHmiCapabilitiesKey = "HMICapabilities"; @@ -102,7 +103,6 @@ const char* kAppIconsFolderKey = "AppIconsFolder"; const char* kAppIconsFolderMaxSizeKey = "AppIconsFolderMaxSize"; const char* kAppIconsAmountToRemoveKey = "AppIconsAmountToRemove"; const char* kLaunchHMIKey = "LaunchHMI"; - const char* kDefaultSDLVersion = ""; #ifdef WEB_HMI const char* kLinkToWebHMI = "LinkToWebHMI"; @@ -197,6 +197,13 @@ const char* kAttemptsToOpenResumptionDBKey = "AttemptsToOpenResumptionDB"; const char* kOpenAttemptTimeoutMsResumptionDBKey = "OpenAttemptTimeoutMsResumptionDB"; +const char* kAppLaunchWaitTimeKey = "AppLaunchWaitTime"; +const char* kAppLaunchMaxRetryAttemptKey = "AppLaunchMaxRetryAttempt"; +const char* kAppLaunchRetryWaitTimeKey = "AppLaunchRetryWaitTime"; +const char* kRemoveBundleIDattemptsKey = "RemoveBundleIDattempts"; +const char* kMaxNumberOfiOSDeviceKey = "MaxNumberOfiOSDevice"; +const char* kWaitTimeBetweenAppsKey = "WaitTimeBetweenApps"; +const char* kEnableAppLaunchIOSKey = "EnableAppLaunchIOS"; #ifdef WEB_HMI const char* kDefaultLinkToWebHMI = "HMI/index.html"; #endif // WEB_HMI @@ -278,6 +285,13 @@ const uint32_t kDefaultAppIconsFolderMaxSize = 104857600; const uint32_t kDefaultAppIconsAmountToRemove = 1; const uint16_t kDefaultAttemptsToOpenResumptionDB = 5; const uint16_t kDefaultOpenAttemptTimeoutMsResumptionDB = 500; +const uint16_t kDefaultAppLaunchWaitTime = 5000; +const uint16_t kDefaultAppLaunchMaxRetryAttempt = 3; +const uint16_t kDefaultAppLaunchRetryWaitTime = 15000; +const uint16_t kDefaultRemoveBundleIDattempts = 3; +const uint16_t kDefaultMaxNumberOfiOSDevice = 10; +const uint16_t kDefaultWaitTimeBetweenApps = 4000; +const bool kDefaultEnableAppLaunchIOS = true; } // namespace namespace profile { @@ -359,7 +373,17 @@ Profile::Profile() , use_db_for_resumption_(false) , attempts_to_open_resumption_db_(kDefaultAttemptsToOpenResumptionDB) , open_attempt_timeout_ms_resumption_db_( - kDefaultOpenAttemptTimeoutMsResumptionDB) { + kDefaultOpenAttemptTimeoutMsResumptionDB) + , app_launch_wait_time_(kDefaultAppLaunchWaitTime) + , app_launch_max_retry_attempt_(kDefaultAppLaunchMaxRetryAttempt) + , app_launch_retry_wait_time_(kDefaultAppLaunchRetryWaitTime) + , remove_bundle_id_attempts_(kDefaultRemoveBundleIDattempts) + , max_number_of_ios_device_(kDefaultMaxNumberOfiOSDevice) + , wait_time_between_apps_(kDefaultWaitTimeBetweenApps) + , enable_app_launch_ios_(kDefaultEnableAppLaunchIOS) { + // SDL version + ReadStringValue( + &sdl_version_, kDefaultSDLVersion, kMainSection, kSDLVersionKey); } Profile::~Profile() {} @@ -525,11 +549,11 @@ const std::string& Profile::audio_stream_file() const { return audio_stream_file_; } -const std::uint32_t Profile::audio_data_stopped_timeout() const { +const uint32_t Profile::audio_data_stopped_timeout() const { return audio_data_stopped_timeout_; } -const std::uint32_t Profile::video_data_stopped_timeout() const { +const uint32_t Profile::video_data_stopped_timeout() const { return video_data_stopped_timeout_; } @@ -751,7 +775,7 @@ uint32_t Profile::resumption_delay_before_ign() const { return resumption_delay_before_ign_; } -uint32_t Profile::resumption_delay_after_ign() const { +const uint32_t Profile::resumption_delay_after_ign() const { return resumption_delay_after_ign_; } @@ -822,6 +846,34 @@ uint16_t Profile::open_attempt_timeout_ms_resumption_db() const { return open_attempt_timeout_ms_resumption_db_; } +const uint16_t Profile::app_launch_max_retry_attempt() const { + return app_launch_max_retry_attempt_; +} + +const uint16_t Profile::app_launch_retry_wait_time() const { + return app_launch_retry_wait_time_; +} + +const uint16_t Profile::app_launch_wait_time() const { + return app_launch_wait_time_; +} + +const bool Profile::enable_app_launch_ios() const { + return enable_app_launch_ios_; +} + +const uint16_t Profile::max_number_of_ios_device() const { + return max_number_of_ios_device_; +} + +const uint16_t Profile::remove_bundle_id_attempts() const { + return remove_bundle_id_attempts_; +} + +const uint16_t Profile::wait_time_between_apps() const { + return wait_time_between_apps_; +} + void Profile::UpdateValues() { LOG4CXX_AUTO_TRACE(logger_); @@ -1680,6 +1732,66 @@ void Profile::UpdateValues() { LOG_UPDATED_VALUE(open_attempt_timeout_ms_resumption_db_, kOpenAttemptTimeoutMsResumptionDBKey, kResumptionSection); + + // Read parameters from App Launch section + ReadUIntValue(&app_launch_wait_time_, + kDefaultAppLaunchWaitTime, + kAppLaunchSection, + kAppLaunchWaitTimeKey); + + LOG_UPDATED_VALUE( + app_launch_wait_time_, kAppLaunchWaitTimeKey, kAppLaunchSection); + + ReadUIntValue(&app_launch_max_retry_attempt_, + kDefaultAppLaunchMaxRetryAttempt, + kAppLaunchSection, + kAppLaunchMaxRetryAttemptKey); + + LOG_UPDATED_VALUE(app_launch_max_retry_attempt_, + kAppLaunchMaxRetryAttemptKey, + kAppLaunchSection); + + ReadUIntValue(&app_launch_retry_wait_time_, + kDefaultAppLaunchRetryWaitTime, + kAppLaunchSection, + kAppLaunchRetryWaitTimeKey); + + LOG_UPDATED_VALUE(app_launch_retry_wait_time_, + kAppLaunchRetryWaitTimeKey, + kAppLaunchSection); + + ReadUIntValue(&remove_bundle_id_attempts_, + kDefaultRemoveBundleIDattempts, + kAppLaunchSection, + kRemoveBundleIDattemptsKey); + + LOG_UPDATED_VALUE(remove_bundle_id_attempts_, + kRemoveBundleIDattemptsKey, + kAppLaunchSection); + + ReadUIntValue(&max_number_of_ios_device_, + kDefaultMaxNumberOfiOSDevice, + kAppLaunchSection, + kMaxNumberOfiOSDeviceKey); + + LOG_UPDATED_VALUE( + max_number_of_ios_device_, kMaxNumberOfiOSDeviceKey, kAppLaunchSection); + + ReadUIntValue(&wait_time_between_apps_, + kDefaultWaitTimeBetweenApps, + kAppLaunchSection, + kWaitTimeBetweenAppsKey); + + LOG_UPDATED_VALUE( + wait_time_between_apps_, kWaitTimeBetweenAppsKey, kAppLaunchSection); + + ReadBoolValue(&enable_app_launch_ios_, + kDefaultEnableAppLaunchIOS, + kAppLaunchSection, + kEnableAppLaunchIOSKey); + + LOG_UPDATED_BOOL_VALUE( + enable_app_launch_ios_, kEnableAppLaunchIOSKey, kAppLaunchSection); } bool Profile::ReadValue(bool* value, diff --git a/src/components/config_profile/test/smartDeviceLink.ini b/src/components/config_profile/test/smartDeviceLink.ini index 41dabaa530..6ea131b095 100644 --- a/src/components/config_profile/test/smartDeviceLink.ini +++ b/src/components/config_profile/test/smartDeviceLink.ini @@ -183,3 +183,19 @@ ResumptionDelayBeforeIgn = 30; # Timeout in seconds to restore hmi_level for media app after sdl run ResumptionDelayAfterIgn = 30; + +[AppLaunch] +; time in milliseconds started from device connection - after expiring SDL remotely launches all known not-yet-registered apps from this device +AppLaunchWaitTime = 5000 +; the number of times SDL attempts to launch an application after device connection - applied separately to each application from the given device +AppLaunchMaxRetryAttempt = 3 +; time in milliseconds started by SDL after app launch request. if expired and app did not register, SDL sends new launch request. applied separately to each app +AppLaunchRetryWaitTime = 15000 +; the number of the given device connections that the requested application failed to register after SDL's launch attempts - SDL removes app's bundleID on "value + 1" device connection +RemoveBundleIDattempts = 3 +; the maximum number of iOS devices for which entries can be remembered by SDL +MaxNumberOfiOSDevice = 10 +; time in milliseconds started after request to launch the first app. after either expires or the first app registers SDL requests to launch the second app. +WaitTimeBetweenApps = 4000 +; App Launch on iOS devices SDL feature enabler/disabler +EnableAppLaunchIOS = true diff --git a/src/components/config_profile/test/smartDeviceLink_invalid_boolean.ini b/src/components/config_profile/test/smartDeviceLink_invalid_boolean.ini index 560fb5117a..f93fa39597 100644 --- a/src/components/config_profile/test/smartDeviceLink_invalid_boolean.ini +++ b/src/components/config_profile/test/smartDeviceLink_invalid_boolean.ini @@ -183,3 +183,19 @@ ResumptionDelayBeforeIgn = 30; # Timeout in seconds to restore hmi_level for media app after sdl run ResumptionDelayAfterIgn = 30; + +[AppLaunch] +; time in milliseconds started from device connection - after expiring SDL remotely launches all known not-yet-registered apps from this device +AppLaunchWaitTime = 5000 +; the number of times SDL attempts to launch an application after device connection - applied separately to each application from the given device +AppLaunchMaxRetryAttempt = 3 +; time in milliseconds started by SDL after app launch request. if expired and app did not register, SDL sends new launch request. applied separately to each app +AppLaunchRetryWaitTime = 15000 +; the number of the given device connections that the requested application failed to register after SDL's launch attempts - SDL removes app's bundleID on "value + 1" device connection +RemoveBundleIDattempts = 3 +; the maximum number of iOS devices for which entries can be remembered by SDL +MaxNumberOfiOSDevice = 10 +; time in milliseconds started after request to launch the first app. after either expires or the first app registers SDL requests to launch the second app. +WaitTimeBetweenApps = 4000 +; App Launch on iOS devices SDL feature enabler/disabler +EnableAppLaunchIOS = true
\ No newline at end of file diff --git a/src/components/config_profile/test/smartDeviceLink_invalid_int.ini b/src/components/config_profile/test/smartDeviceLink_invalid_int.ini index 76bcc5a0f0..9c88a8950c 100644 --- a/src/components/config_profile/test/smartDeviceLink_invalid_int.ini +++ b/src/components/config_profile/test/smartDeviceLink_invalid_int.ini @@ -185,3 +185,19 @@ ResumptionDelayBeforeIgn = 30; # Timeout in seconds to restore hmi_level for media app after sdl run ResumptionDelayAfterIgn = 30; + +[AppLaunch] +; time in milliseconds started from device connection - after expiring SDL remotely launches all known not-yet-registered apps from this device +AppLaunchWaitTime = 5000 +; the number of times SDL attempts to launch an application after device connection - applied separately to each application from the given device +AppLaunchMaxRetryAttempt = 3 +; time in milliseconds started by SDL after app launch request. if expired and app did not register, SDL sends new launch request. applied separately to each app +AppLaunchRetryWaitTime = 15000 +; the number of the given device connections that the requested application failed to register after SDL's launch attempts - SDL removes app's bundleID on "value + 1" device connection +RemoveBundleIDattempts = 3 +; the maximum number of iOS devices for which entries can be remembered by SDL +MaxNumberOfiOSDevice = 10 +; time in milliseconds started after request to launch the first app. after either expires or the first app registers SDL requests to launch the second app. +WaitTimeBetweenApps = 4000 +; App Launch on iOS devices SDL feature enabler/disabler +EnableAppLaunchIOS = true
\ No newline at end of file diff --git a/src/components/config_profile/test/smartDeviceLink_invalid_pairs.ini b/src/components/config_profile/test/smartDeviceLink_invalid_pairs.ini index 1507b2a84c..b389b0b492 100644 --- a/src/components/config_profile/test/smartDeviceLink_invalid_pairs.ini +++ b/src/components/config_profile/test/smartDeviceLink_invalid_pairs.ini @@ -185,3 +185,19 @@ ResumptionDelayBeforeIgn = 30; # Timeout in seconds to restore hmi_level for media app after sdl run ResumptionDelayAfterIgn = 30; + +[AppLaunch] +; time in milliseconds started from device connection - after expiring SDL remotely launches all known not-yet-registered apps from this device +AppLaunchWaitTime = 5000 +; the number of times SDL attempts to launch an application after device connection - applied separately to each application from the given device +AppLaunchMaxRetryAttempt = 3 +; time in milliseconds started by SDL after app launch request. if expired and app did not register, SDL sends new launch request. applied separately to each app +AppLaunchRetryWaitTime = 15000 +; the number of the given device connections that the requested application failed to register after SDL's launch attempts - SDL removes app's bundleID on "value + 1" device connection +RemoveBundleIDattempts = 3 +; the maximum number of iOS devices for which entries can be remembered by SDL +MaxNumberOfiOSDevice = 10 +; time in milliseconds started after request to launch the first app. after either expires or the first app registers SDL requests to launch the second app. +WaitTimeBetweenApps = 4000 +; App Launch on iOS devices SDL feature enabler/disabler +EnableAppLaunchIOS = true
\ No newline at end of file diff --git a/src/components/config_profile/test/smartDeviceLink_invalid_string.ini b/src/components/config_profile/test/smartDeviceLink_invalid_string.ini index 6669b580c5..f18b43cb41 100644 --- a/src/components/config_profile/test/smartDeviceLink_invalid_string.ini +++ b/src/components/config_profile/test/smartDeviceLink_invalid_string.ini @@ -188,3 +188,19 @@ ResumptionDelayBeforeIgn = 30; # Timeout in seconds to restore hmi_level for media app after sdl run ResumptionDelayAfterIgn = 30; + +[AppLaunch] +; time in milliseconds started from device connection - after expiring SDL remotely launches all known not-yet-registered apps from this device +AppLaunchWaitTime = 5000 +; the number of times SDL attempts to launch an application after device connection - applied separately to each application from the given device +AppLaunchMaxRetryAttempt = 3 +; time in milliseconds started by SDL after app launch request. if expired and app did not register, SDL sends new launch request. applied separately to each app +AppLaunchRetryWaitTime = 15000 +; the number of the given device connections that the requested application failed to register after SDL's launch attempts - SDL removes app's bundleID on "value + 1" device connection +RemoveBundleIDattempts = 3 +; the maximum number of iOS devices for which entries can be remembered by SDL +MaxNumberOfiOSDevice = 10 +; time in milliseconds started after request to launch the first app. after either expires or the first app registers SDL requests to launch the second app. +WaitTimeBetweenApps = 4000 +; App Launch on iOS devices SDL feature enabler/disabler +EnableAppLaunchIOS = true
\ No newline at end of file diff --git a/src/components/config_profile/test/smartDeviceLink_test.ini b/src/components/config_profile/test/smartDeviceLink_test.ini index 6e2943b569..9791544e16 100644 --- a/src/components/config_profile/test/smartDeviceLink_test.ini +++ b/src/components/config_profile/test/smartDeviceLink_test.ini @@ -190,3 +190,19 @@ ResumptionDelayBeforeIgn = 30; # Timeout in seconds to restore hmi_level for media app after sdl run ResumptionDelayAfterIgn = 30; + +[AppLaunch] +; time in milliseconds started from device connection - after expiring SDL remotely launches all known not-yet-registered apps from this device +AppLaunchWaitTime = 5000 +; the number of times SDL attempts to launch an application after device connection - applied separately to each application from the given device +AppLaunchMaxRetryAttempt = 3 +; time in milliseconds started by SDL after app launch request. if expired and app did not register, SDL sends new launch request. applied separately to each app +AppLaunchRetryWaitTime = 15000 +; the number of the given device connections that the requested application failed to register after SDL's launch attempts - SDL removes app's bundleID on "value + 1" device connection +RemoveBundleIDattempts = 3 +; the maximum number of iOS devices for which entries can be remembered by SDL +MaxNumberOfiOSDevice = 10 +; time in milliseconds started after request to launch the first app. after either expires or the first app registers SDL requests to launch the second app. +WaitTimeBetweenApps = 4000 +; App Launch on iOS devices SDL feature enabler/disabler +EnableAppLaunchIOS = true diff --git a/src/components/connection_handler/include/connection_handler/connection_handler.h b/src/components/connection_handler/include/connection_handler/connection_handler.h index cb22b87bbb..7e7a7db114 100644 --- a/src/components/connection_handler/include/connection_handler/connection_handler.h +++ b/src/components/connection_handler/include/connection_handler/connection_handler.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -68,6 +68,18 @@ class ConnectionHandler { virtual void ConnectToDevice( connection_handler::DeviceHandle device_handle) = 0; + /** + * @brief RunAppOnDevice allows to run specific application on the certain + *device. + * + * @param device_handle device identifier to run application on. + * + * @param app_id application id also known as bundle id on some devices to + *run. + */ + virtual void RunAppOnDevice(const std::string& device_handle, + const std::string& bundle_id) const = 0; + virtual void ConnectToAllDevices() = 0; /** diff --git a/src/components/connection_handler/include/connection_handler/connection_handler_impl.h b/src/components/connection_handler/include/connection_handler/connection_handler_impl.h index d061e55491..cd8aec0ff3 100644 --- a/src/components/connection_handler/include/connection_handler/connection_handler_impl.h +++ b/src/components/connection_handler/include/connection_handler/connection_handler_impl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -102,6 +102,18 @@ class ConnectionHandlerImpl */ void ConnectToDevice(connection_handler::DeviceHandle device_handle) OVERRIDE; + /** + * @brief RunAppOnDevice allows to run specific application on the certain + *device. + * + * @param device_handle device identifier to run application on. + * + * @param app_id application id also known as bundle id on some devices to + *run. + */ + void RunAppOnDevice(const std::string& device_mac, + const std::string& bundle_id) const OVERRIDE; + void ConnectToAllDevices() OVERRIDE; void StartTransportManager() OVERRIDE; diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc index d8c05e6e6e..62a1f46fba 100644 --- a/src/components/connection_handler/src/connection_handler_impl.cc +++ b/src/components/connection_handler/src/connection_handler_impl.cc @@ -697,6 +697,20 @@ void ConnectionHandlerImpl::ConnectToDevice( } } +void ConnectionHandlerImpl::RunAppOnDevice(const std::string& device_mac, + const std::string& bundle_id) const { + for (DeviceMap::const_iterator i = device_list_.begin(); + i != device_list_.end(); + ++i) { + const connection_handler::Device& device = i->second; + if (device.mac_address() == device_mac) { + transport_manager_.RunAppOnDevice(device.device_handle(), bundle_id); + return; + } + } + LOG4CXX_WARN(logger_, "No apps found on device " << device_mac); +} + void ConnectionHandlerImpl::ConnectToAllDevices() { for (DeviceMap::iterator i = device_list_.begin(); i != device_list_.end(); ++i) { diff --git a/src/components/include/application_manager/app_launch_settings.h b/src/components/include/application_manager/app_launch_settings.h new file mode 100644 index 0000000000..47daf2f87c --- /dev/null +++ b/src/components/include/application_manager/app_launch_settings.h @@ -0,0 +1,22 @@ +#ifndef SRC_COMPONENTS_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_SETTINGS_H_ +#define SRC_COMPONENTS_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_SETTINGS_H_ + +#include <stdint.h> +#include <string> +namespace app_launch { +class AppLaunchSettings { + public: + virtual const uint16_t app_launch_wait_time() const = 0; + virtual const uint16_t app_launch_max_retry_attempt() const = 0; + virtual const uint16_t app_launch_retry_wait_time() const = 0; + virtual const uint16_t remove_bundle_id_attempts() const = 0; + virtual const uint16_t max_number_of_ios_device() const = 0; + virtual const uint16_t wait_time_between_apps() const = 0; + virtual const bool enable_app_launch_ios() const = 0; + virtual const uint32_t resumption_delay_after_ign() const = 0; + virtual const std::string& app_storage_folder() const = 0; +}; + +} // namespace application_manager + +#endif // SRC_COMPONENTS_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_SETTINGS_H_ diff --git a/src/components/include/application_manager/application_manager_settings.h b/src/components/include/application_manager/application_manager_settings.h index b429da88c2..899b098359 100644 --- a/src/components/include/application_manager/application_manager_settings.h +++ b/src/components/include/application_manager/application_manager_settings.h @@ -34,20 +34,21 @@ #define SRC_COMPONENTS_INCLUDE_APPLICATION_MANAGER_APPLICATION_MANAGER_SETTINGS_H_ #include "application_manager/request_controller_settings.h" +#include "application_manager/app_launch_settings.h" #include <stdint.h> #include <string> namespace application_manager { -class ApplicationManagerSettings : public RequestControlerSettings { +class ApplicationManagerSettings : public RequestControlerSettings, + public app_launch::AppLaunchSettings { public: virtual const uint32_t video_data_stopped_timeout() const = 0; - virtual const std::uint32_t audio_data_stopped_timeout() const = 0; + virtual const uint32_t audio_data_stopped_timeout() const = 0; virtual const std::pair<uint32_t, int32_t>& read_did_frequency() const = 0; virtual const std::pair<uint32_t, int32_t>& get_vehicle_data_frequency() const = 0; virtual uint32_t hash_string_size() const = 0; - virtual const std::string& app_storage_folder() const = 0; virtual const uint32_t& app_dir_quota() const = 0; virtual uint32_t stop_streaming_timeout() const = 0; virtual uint32_t application_list_update_timeout() const = 0; @@ -82,7 +83,6 @@ class ApplicationManagerSettings : public RequestControlerSettings { virtual const uint32_t& app_resumption_save_persistent_data_timeout() const = 0; virtual uint32_t resumption_delay_before_ign() const = 0; - virtual uint32_t resumption_delay_after_ign() const = 0; virtual const uint32_t& app_resuming_timeout() const = 0; virtual uint16_t attempts_to_open_resumption_db() const = 0; virtual uint16_t open_attempt_timeout_ms_resumption_db() const = 0; @@ -94,6 +94,7 @@ class ApplicationManagerSettings : public RequestControlerSettings { virtual const uint32_t& app_icons_amount_to_remove() const = 0; virtual const uint32_t& list_files_response_size() const = 0; }; + } // namespace application_manager #endif // SRC_COMPONENTS_INCLUDE_APPLICATION_MANAGER_APPLICATION_MANAGER_SETTINGS_H_ diff --git a/src/components/include/application_manager/hmi_capabilities.h b/src/components/include/application_manager/hmi_capabilities.h new file mode 100644 index 0000000000..d7bd7a6c05 --- /dev/null +++ b/src/components/include/application_manager/hmi_capabilities.h @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef SRC_COMPONENTS_INCLUDE_APPLICATION_MANAGER_HMI_CAPABILITIES_H_ +#define SRC_COMPONENTS_INCLUDE_APPLICATION_MANAGER_HMI_CAPABILITIES_H_ + +#include "interfaces/HMI_API.h" +#include "interfaces/MOBILE_API.h" +#include "json/json.h" +#include "utils/macro.h" +#include "application_manager/hmi_language_handler.h" + +namespace NsSmartDeviceLink { +namespace NsSmartObjects { +class SmartObject; +} +} +namespace resumption { +class LastState; +} + +namespace smart_objects = NsSmartDeviceLink::NsSmartObjects; + +namespace application_manager { +class ApplicationManager; + +class HMICapabilities { + public: + /* + * @brief Class destructor + * + */ + virtual ~HMICapabilities() {} + + /** + * @brief return component which follows for correctness of + * languages + * @return HMI language handler + */ + virtual HMILanguageHandler& get_hmi_language_handler() = 0; + + /** + * @brief Checks if all HMI capabilities received + * + * @return TRUE if all information received, otherwise FALSE + */ + virtual bool is_hmi_capabilities_initialized() const = 0; + + /* + * @brief Checks is image type(Static/Dynamic) requested by + * Mobile Device is supported on current HMI. + * @param image_type recieved type of image from Enum. + * @return Bool true if supported + */ + virtual bool VerifyImageType(const int32_t image_type) const = 0; + + /** + * @brief Checks if all HMI capabilities received + * + * @return TRUE if all information received, otherwise FALSE + */ + virtual bool is_vr_cooperating() const = 0; + virtual void set_is_vr_cooperating(const bool value) = 0; + + virtual bool is_tts_cooperating() const = 0; + virtual void set_is_tts_cooperating(const bool value) = 0; + + virtual bool is_ui_cooperating() const = 0; + virtual void set_is_ui_cooperating(const bool value) = 0; + + virtual bool is_navi_cooperating() const = 0; + virtual void set_is_navi_cooperating(const bool value) = 0; + + virtual bool is_ivi_cooperating() const = 0; + virtual void set_is_ivi_cooperating(const bool value) = 0; + + /* + * @brief Interface used to store information about software version of the + *target + * + * @param ccpu_version Received system/hmi software version + */ + virtual void set_ccpu_version(const std::string& ccpu_version) = 0; + + /* + * @brief Returns software version of the target + * + * @return TRUE if it supported, otherwise FALSE + */ + virtual const std::string& ccpu_version() const = 0; + + /* + * @brief Retrieves if mixing audio is supported by HMI + * (ie recording TTS command and playing audio) + * + * @return Current state of the mixing audio flag + */ + virtual bool attenuated_supported() const = 0; + + /* + * @brief Sets state for mixing audio + * + * @param state New state to be set + */ + virtual void set_attenuated_supported(const bool state) = 0; + + /* + * @brief Retrieves currently active UI language + * + * @return Currently active UI language + */ + virtual const hmi_apis::Common_Language::eType active_ui_language() const = 0; + + /* + * @brief Sets currently active UI language + * + * @param language Currently active UI language + */ + virtual void set_active_ui_language( + const hmi_apis::Common_Language::eType language) = 0; + + /* + * @brief Retrieves UI supported languages + * + * @return Currently supported UI languages + */ + virtual const smart_objects::SmartObject* ui_supported_languages() const = 0; + + /* + * @brief Sets supported UI languages + * + * @param supported_languages Supported UI languages + */ + virtual void set_ui_supported_languages( + const smart_objects::SmartObject& supported_languages) = 0; + + /* + * @brief Retrieves currently active VR language + * + * @return Currently active VR language + */ + virtual const hmi_apis::Common_Language::eType active_vr_language() const = 0; + + /* + * @brief Sets currently active VR language + * + * @param language Currently active VR language + */ + virtual void set_active_vr_language( + const hmi_apis::Common_Language::eType language) = 0; + + /* + * @brief Retrieves VR supported languages + * + * @return Currently supported VR languages + */ + virtual const smart_objects::SmartObject* vr_supported_languages() const = 0; + + /* + * @brief Sets supported VR languages + * + * @param supported_languages Supported VR languages + */ + virtual void set_vr_supported_languages( + const smart_objects::SmartObject& supported_languages) = 0; + + /* + * @brief Retrieves currently active TTS language + * + * @return Currently active TTS language + */ + virtual const hmi_apis::Common_Language::eType active_tts_language() + const = 0; + + /* + * @brief Sets currently active TTS language + * + * @param language Currently active TTS language + */ + virtual void set_active_tts_language( + const hmi_apis::Common_Language::eType language) = 0; + + /* + * @brief Retrieves TTS supported languages + * + * @return Currently supported TTS languages + */ + virtual const smart_objects::SmartObject* tts_supported_languages() const = 0; + + /* + * @brief Sets supported TTS languages + * + * @param supported_languages Supported TTS languages + */ + virtual void set_tts_supported_languages( + const smart_objects::SmartObject& supported_languages) = 0; + + /* + * @brief Retrieves information about the display capabilities + * + * @return Currently supported display capabilities + */ + virtual const smart_objects::SmartObject* display_capabilities() const = 0; + + /* + * @brief Sets supported display capabilities + * + * @param display_capabilities supported display capabilities + */ + virtual void set_display_capabilities( + const smart_objects::SmartObject& display_capabilities) = 0; + + /* + * @brief Retrieves information about the HMI zone capabilities + * + * @return Currently supported HMI zone capabilities + */ + virtual const smart_objects::SmartObject* hmi_zone_capabilities() const = 0; + + /* + * @brief Sets supported HMI zone capabilities + * + * @param hmi_zone_capabilities supported HMI zone capabilities + */ + virtual void set_hmi_zone_capabilities( + const smart_objects::SmartObject& hmi_zone_capabilities) = 0; + + /* + * @brief Retrieves information about the SoftButton's capabilities + * + * @return Currently supported SoftButton's capabilities + */ + virtual const smart_objects::SmartObject* soft_button_capabilities() + const = 0; + + /* + * @brief Sets supported SoftButton's capabilities + * + * @param soft_button_capabilities supported SoftButton's capabilities + */ + virtual void set_soft_button_capabilities( + const smart_objects::SmartObject& soft_button_capabilities) = 0; + + /* + * @brief Retrieves information about the Button's capabilities + * + * @return Currently supported Button's capabilities + */ + virtual const smart_objects::SmartObject* button_capabilities() const = 0; + + /* + * @brief Sets supported Button's capabilities + * + * @param soft_button_capabilities supported Button's capabilities + */ + virtual void set_button_capabilities( + const smart_objects::SmartObject& button_capabilities) = 0; + + /* + * @brief Sets supported speech capabilities + * + * @param speech_capabilities supported speech capabilities + */ + virtual void set_speech_capabilities( + const smart_objects::SmartObject& speech_capabilities) = 0; + + /* + * @brief Retrieves information about the speech capabilities + * + * @return Currently supported speech capabilities + */ + virtual const smart_objects::SmartObject* speech_capabilities() const = 0; + + /* + * @brief Sets supported VR capabilities + * + * @param vr_capabilities supported VR capabilities + */ + virtual void set_vr_capabilities( + const smart_objects::SmartObject& vr_capabilities) = 0; + + /* + * @brief Retrieves information about the VR capabilities + * + * @return Currently supported VR capabilities + */ + virtual const smart_objects::SmartObject* vr_capabilities() const = 0; + + /* + * @brief Sets supported audio_pass_thru capabilities + * + * @param vr_capabilities supported audio_pass_thru capabilities + */ + virtual void set_audio_pass_thru_capabilities( + const smart_objects::SmartObject& audio_pass_thru_capabilities) = 0; + + /* + * @brief Retrieves information about the audio_pass_thru capabilities + * + * @return Currently supported audio_pass_thru capabilities + */ + virtual const smart_objects::SmartObject* audio_pass_thru_capabilities() + const = 0; + + /* + * @brief Sets supported pcm_stream capabilities + * + * @param supported pcm_stream capabilities + */ + virtual void set_pcm_stream_capabilities( + const smart_objects::SmartObject& pcm_stream_capabilities) = 0; + + /* + * @brief Retrieves information about the pcm_stream capabilities + * + * @return Currently supported pcm_streaming capabilities + */ + virtual const smart_objects::SmartObject* pcm_stream_capabilities() const = 0; + + /* + * @brief Retrieves information about the preset bank capabilities + * + * @return Currently supported preset bank capabilities + */ + virtual const smart_objects::SmartObject* preset_bank_capabilities() + const = 0; + + /* + * @brief Sets supported preset bank capabilities + * + * @param soft_button_capabilities supported preset bank capabilities + */ + virtual void set_preset_bank_capabilities( + const smart_objects::SmartObject& preset_bank_capabilities) = 0; + + /* + * @brief Sets vehicle information(make, model, modelYear) + * + * @param vehicle_type Cuurent vehicle information + */ + virtual void set_vehicle_type( + const smart_objects::SmartObject& vehicle_type) = 0; + + /* + * @brief Retrieves vehicle information(make, model, modelYear) + * + * @param vehicle_type Cuurent vehicle information + */ + virtual const smart_objects::SmartObject* vehicle_type() const = 0; + + /* + * @brief Retrieves information about the prerecorded speech + * + * @return Currently supported prerecorded speech + */ + virtual const smart_objects::SmartObject* prerecorded_speech() const = 0; + + /* + * @brief Sets supported prerecorded speech + * + * @param prerecorded_speech supported prerecorded speech + */ + virtual void set_prerecorded_speech( + const smart_objects::SmartObject& prerecorded_speech) = 0; + + /* + * @brief Interface used to store information if navigation + * supported by the system + * + * @param supported Indicates if navigation supported by the system + */ + virtual void set_navigation_supported(const bool supported) = 0; + + /* + * @brief Retrieves information if navi supported by the system + * + * @return TRUE if it supported, otherwise FALSE + */ + virtual bool navigation_supported() const = 0; + + /* + * @brief Interface used to store information if phone call + * supported by the system + * + * @param supported Indicates if navigation supported by the sustem + */ + virtual void set_phone_call_supported(const bool supported) = 0; + + /* + * @brief Retrieves information if phone call supported by the system + * + * @return TRUE if it supported, otherwise FALSE + */ + virtual bool phone_call_supported() const = 0; + + virtual void Init(resumption::LastState* last_state) = 0; + + protected: + /* + * @brief function checks if json member exists + * + * @param json_member from file hmi_capabilities.json + * @param name_of_member name which we should check + * hmi_capabilities.json + * + * @returns TRUE if member exists and returns FALSE if + * member does not exist. + */ + virtual bool check_existing_json_member(const Json::Value& json_member, + const char* name_of_member) const = 0; + + virtual void convert_json_languages_to_obj( + const Json::Value& json_languages, + smart_objects::SmartObject& languages) const = 0; +}; + +} // namespace application_manager + +#endif // SRC_COMPONENTS_INCLUDE_APPLICATION_MANAGER_HMI_CAPABILITIES_H_ diff --git a/src/components/include/test/application_manager/mock_app_launch_settings.h b/src/components/include/test/application_manager/mock_app_launch_settings.h new file mode 100644 index 0000000000..2ceaefcae4 --- /dev/null +++ b/src/components/include/test/application_manager/mock_app_launch_settings.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_INCLUDE_TEST_APPLICATION_MANAGER_MOCK_APP_LAUNCH_SETTINGS_H_ +#define SRC_COMPONENTS_INCLUDE_TEST_APPLICATION_MANAGER_MOCK_APP_LAUNCH_SETTINGS_H_ + +#include <string> +#include "gmock/gmock.h" +#include "application_manager/app_launch_settings.h" + +namespace test { +namespace components { +namespace app_launch_test { + +class MockAppLaunchSettings : public app_launch::AppLaunchSettings { + public: + MOCK_CONST_METHOD0(app_launch_wait_time, const uint16_t()); + MOCK_CONST_METHOD0(app_launch_max_retry_attempt, const uint16_t()); + MOCK_CONST_METHOD0(app_launch_retry_wait_time, const uint16_t()); + MOCK_CONST_METHOD0(remove_bundle_id_attempts, const uint16_t()); + MOCK_CONST_METHOD0(max_number_of_ios_device, const uint16_t()); + MOCK_CONST_METHOD0(wait_time_between_apps, const uint16_t()); + MOCK_CONST_METHOD0(enable_app_launch_ios, const bool()); + MOCK_CONST_METHOD0(resumption_delay_after_ign, const uint32_t()); + MOCK_CONST_METHOD0(app_storage_folder, std::string&()); +}; + +} // namespace app_launch_test +} // namespace components +} // namespace test + +#endif // SRC_COMPONENTS_INCLUDE_TEST_APPLICATION_MANAGER_MOCK_APP_LAUNCH_SETTINGS_H_ 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 b1c32c982b..eee121149e 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 @@ -90,7 +90,7 @@ class MockApplicationManagerSettings MOCK_CONST_METHOD0(app_resumption_save_persistent_data_timeout, const uint32_t&()); MOCK_CONST_METHOD0(resumption_delay_before_ign, uint32_t()); - MOCK_CONST_METHOD0(resumption_delay_after_ign, uint32_t()); + MOCK_CONST_METHOD0(resumption_delay_after_ign, const uint32_t()); MOCK_CONST_METHOD0(app_resuming_timeout, const uint32_t&()); MOCK_CONST_METHOD0(attempts_to_open_resumption_db, uint16_t()); MOCK_CONST_METHOD0(open_attempt_timeout_ms_resumption_db, uint16_t()); @@ -113,6 +113,15 @@ class MockApplicationManagerSettings MOCK_CONST_METHOD0(app_time_scale, const uint32_t&()); MOCK_CONST_METHOD0(app_time_scale_max_requests, const uint32_t&()); MOCK_CONST_METHOD0(pending_requests_amount, const uint32_t&()); + + // app_launch::AppLaunchSettings + MOCK_CONST_METHOD0(app_launch_wait_time, const uint16_t()); + MOCK_CONST_METHOD0(app_launch_max_retry_attempt, const uint16_t()); + MOCK_CONST_METHOD0(app_launch_retry_wait_time, const uint16_t()); + MOCK_CONST_METHOD0(remove_bundle_id_attempts, const uint16_t()); + MOCK_CONST_METHOD0(max_number_of_ios_device, const uint16_t()); + MOCK_CONST_METHOD0(wait_time_between_apps, const uint16_t()); + MOCK_CONST_METHOD0(enable_app_launch_ios, const bool()); }; } // namespace application_manager_test diff --git a/src/components/include/test/connection_handler/mock_connection_handler.h b/src/components/include/test/connection_handler/mock_connection_handler.h index eac82cc177..e17224b097 100644 --- a/src/components/include/test/connection_handler/mock_connection_handler.h +++ b/src/components/include/test/connection_handler/mock_connection_handler.h @@ -59,6 +59,8 @@ class MockConnectionHandler : public connection_handler::ConnectionHandler { MOCK_METHOD0(StartTransportManager, void()); MOCK_METHOD1(ConnectToDevice, void(connection_handler::DeviceHandle device_handle)); + MOCK_CONST_METHOD2(RunAppOnDevice, + void(const std::string&, const std::string&)); MOCK_METHOD0(ConnectToAllDevices, void()); MOCK_METHOD1(CloseRevokedConnection, void(uint32_t connection_key)); MOCK_METHOD1(CloseConnection, void(ConnectionHandle connection_handle)); diff --git a/src/components/include/test/transport_manager/mock_transport_manager.h b/src/components/include/test/transport_manager/mock_transport_manager.h index 618e85a4fa..cc8bd5ab85 100644 --- a/src/components/include/test/transport_manager/mock_transport_manager.h +++ b/src/components/include/test/transport_manager/mock_transport_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -65,6 +65,7 @@ class MockTransportManager : public ::transport_manager::TransportManager, MOCK_METHOD1(DisconnectForce, int(const ConnectionUID)); MOCK_METHOD1(SendMessageToDevice, int(const ::protocol_handler::RawMessagePtr)); + MOCK_METHOD2(RunAppOnDevice, void(const DeviceHandle, const std::string&)); MOCK_METHOD1(ReceiveEventFromDevice, int(const TransportAdapterEvent&)); MOCK_METHOD1(AddTransportAdapter, int(TransportAdapter* adapter)); MOCK_METHOD1(AddEventListener, int(TransportManagerListener* listener)); diff --git a/src/components/include/transport_manager/transport_adapter/device.h b/src/components/include/transport_manager/transport_adapter/device.h index a1dd7b9bcf..3adb6cd2e6 100644 --- a/src/components/include/transport_manager/transport_adapter/device.h +++ b/src/components/include/transport_manager/transport_adapter/device.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,6 +38,7 @@ #include "transport_manager/common.h" #include "utils/shared_ptr.h" +#include "utils/macro.h" namespace transport_manager { namespace transport_adapter { @@ -76,6 +77,15 @@ class Device { virtual ApplicationList GetApplicationList() const = 0; + /** + * @brief LaunchApp allows to run appropriate application on the device. + * + * @param bundle_id application identifier to run. + */ + virtual void LaunchApp(const std::string& bundle_id) const { + UNUSED(bundle_id); + } + virtual void Stop() {} inline const DeviceUID& unique_device_id() const { diff --git a/src/components/include/transport_manager/transport_adapter/transport_adapter.h b/src/components/include/transport_manager/transport_adapter/transport_adapter.h index 3ff1aa6eee..ee726ff1d3 100644 --- a/src/components/include/transport_manager/transport_adapter/transport_adapter.h +++ b/src/components/include/transport_manager/transport_adapter/transport_adapter.h @@ -2,7 +2,7 @@ * \file transport_adapter.h * \brief TransportAdapter class header file. * - * Copyright (c) 2013, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -175,6 +175,18 @@ class TransportAdapter { virtual Error ConnectDevice(const DeviceUID& device_handle) = 0; /** + * @brief RunAppOnDevice allows to run specific application on the certain + *device. + * + * @param device_handle device identifier to run application on. + * + * @param app_id application id also known as bundle id on some devices to + *run. + */ + virtual void RunAppOnDevice(const std::string& device_uid, + const std::string& bundle_id) = 0; + + /** * @brief Notify that listener of client connection is available. * * @return true - available, false - not available. diff --git a/src/components/include/transport_manager/transport_manager.h b/src/components/include/transport_manager/transport_manager.h index 718f9e12aa..0847886c46 100644 --- a/src/components/include/transport_manager/transport_manager.h +++ b/src/components/include/transport_manager/transport_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -121,6 +121,18 @@ class TransportManager { const protocol_handler::RawMessagePtr message) = 0; /** + * @brief RunAppOnDevice allows run specific application on the certain + *device. + * + * @param device_handle device identifier to run application on. + * + * @param bundle_id application id alsow known as bundle id on some devices to + *run. + */ + virtual void RunAppOnDevice(const DeviceHandle device_handle, + const std::string& bundle_id) = 0; + + /** * @brief Post event in the event queue. * * @param event Current event information. diff --git a/src/components/interfaces/MOBILE_API.xml b/src/components/interfaces/MOBILE_API.xml index 1bff09ef38..08c7ef738e 100644 --- a/src/components/interfaces/MOBILE_API.xml +++ b/src/components/interfaces/MOBILE_API.xml @@ -1283,6 +1283,26 @@ </param>
</struct>
+ <struct name="AppInfo">
+ <description>Contains detailed information about the registered application.</description>
+
+ <param name="appDisplayName" type="String" maxlength="100" mandatory="true">
+ <description>The name displayed for the mobile application on the mobile device (can differ from the app name set in the initial RAI request).</description>
+ </param>
+
+ <param name="appBundleID" type="String" maxlength="256" mandatory="true">
+ <description>The AppBundleID of an iOS application or package name of the Android application. This supports App Launch strategies for each platform.</description>
+ </param>
+
+ <param name="appVersion" type="String" maxlength="256" mandatory="true">
+ <description>Represents the build version number of this particular mobile app.</description>
+ </param>
+
+ <param name="appIcon" type="String" maxlength="500" mandatory="false">
+ <description>A file reference to the icon utilized by this app (simplifies the process of setting an app icon during app registration).</description>
+ </param>
+ </struct>
+
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- Ford Specific Data Items -->
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~ -->
@@ -2446,6 +2466,11 @@ <param name="appID" type="String" maxlength="100" mandatory="true">
<description>ID used to validate app with policy table entries</description>
</param>
+ <param name="appInfo" type="AppInfo" mandatory="false">
+ <description>
+ See AppInfo.
+ </description>
+ </param>
</function>
<function name="RegisterAppInterface" functionID="RegisterAppInterfaceID" messagetype="response">
diff --git a/src/components/policy/src/policy_manager_impl.cc b/src/components/policy/src/policy_manager_impl.cc index 4e3f892b45..fed1a51af1 100644 --- a/src/components/policy/src/policy_manager_impl.cc +++ b/src/components/policy/src/policy_manager_impl.cc @@ -311,7 +311,7 @@ void PolicyManagerImpl::StartPTExchange() { if (update_status_manager_.IsUpdateRequired()) { if (RequestPTUpdate() && !timer_retry_sequence_.is_running()) { // Start retry sequency - timer_retry_sequence_.Start(NextRetryTimeout(), false); + timer_retry_sequence_.Start(NextRetryTimeout(), timer::kPeriodic); } } } @@ -1008,7 +1008,7 @@ void PolicyManagerImpl::RetrySequence() { return; } - timer_retry_sequence_.Start(timeout, false); + timer_retry_sequence_.Start(timeout, timer::kPeriodic); } } // namespace policy diff --git a/src/components/policy/src/usage_statistics/counter.cc b/src/components/policy/src/usage_statistics/counter.cc index c5d7eaf9df..60e34a929d 100644 --- a/src/components/policy/src/usage_statistics/counter.cc +++ b/src/components/policy/src/usage_statistics/counter.cc @@ -103,7 +103,8 @@ AppStopwatchImpl::AppStopwatchImpl( void AppStopwatchImpl::Start(AppStopwatchId stopwatch_type) { stopwatch_type_ = stopwatch_type; - timer_.Start(time_out_ * date_time::DateTime::MILLISECONDS_IN_SECOND, false); + timer_.Start(time_out_ * date_time::DateTime::MILLISECONDS_IN_SECOND, + timer::kPeriodic); } void AppStopwatchImpl::Switch(AppStopwatchId stopwatch_type) { diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h index 3dedead540..3e91c6f246 100644 --- a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h +++ b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -479,6 +479,18 @@ class TransportAdapterImpl : public TransportAdapter, TransportAdapter::Error ConnectDevice(DeviceSptr device); /** + * @brief RunAppOnDevice allows run specific application on the certain + *device. + * + * @param device_handle device identifier to run application on. + * + * @param bundle_id application id alsow known as bundle id on some devices to + *run. + */ + void RunAppOnDevice(const DeviceUID& device_uid, + const std::string& bundle_id) OVERRIDE; + + /** * @brief Remove specified device * @param device_handle Device unique identifier. */ diff --git a/src/components/transport_manager/include/transport_manager/transport_manager_impl.h b/src/components/transport_manager/include/transport_manager/transport_manager_impl.h index 289df3535d..4dd74086be 100644 --- a/src/components/transport_manager/include/transport_manager/transport_manager_impl.h +++ b/src/components/transport_manager/include/transport_manager/transport_manager_impl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -181,6 +181,18 @@ class TransportManagerImpl const protocol_handler::RawMessagePtr message) OVERRIDE; /** + * @brief RunAppOnDevice allows to run specific application on the certain + *device. + * + * @param device_handle device identifier to run application on. + * + * @param bundle_id application id also known as bundle id on some devices to + *run. + */ + void RunAppOnDevice(const DeviceHandle device_handle, + const std::string& bundle_id) OVERRIDE; + + /** * @brief Post event in the event queue. * * @param event Current event information. diff --git a/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc b/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc index 5638eecdee..0986271481 100644 --- a/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc +++ b/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc @@ -952,6 +952,21 @@ TransportAdapter::Error TransportAdapterImpl::ConnectDevice(DeviceSptr device) { } } +void TransportAdapterImpl::RunAppOnDevice(const DeviceUID& device_uid, + const std::string& bundle_id) { + LOG4CXX_AUTO_TRACE(logger_); + + DeviceSptr device = FindDevice(device_uid); + if (!device) { + LOG4CXX_WARN(logger_, + "Device with id: " << device_uid << " Not found" + << "withing list of connected deviced"); + return; + } + + device->LaunchApp(bundle_id); +} + void TransportAdapterImpl::RemoveDevice(const DeviceUID& device_handle) { LOG4CXX_AUTO_TRACE(logger_); LOG4CXX_DEBUG(logger_, "Device_handle: " << &device_handle); diff --git a/src/components/transport_manager/src/transport_manager_impl.cc b/src/components/transport_manager/src/transport_manager_impl.cc index 113d280c8d..8a4b01ad85 100644 --- a/src/components/transport_manager/src/transport_manager_impl.cc +++ b/src/components/transport_manager/src/transport_manager_impl.cc @@ -341,6 +341,34 @@ int TransportManagerImpl::SendMessageToDevice( return E_SUCCESS; } +void TransportManagerImpl::RunAppOnDevice(const DeviceHandle device_handle, + const std::string& bundle_id) { + if (!this->is_initialized_) { + LOG4CXX_ERROR(logger_, "TransportManager is not initialized."); + return; + } + DeviceUID device_id = converter_.HandleToUid(device_handle); + LOG4CXX_DEBUG(logger_, "Convert handle to id:" << device_id); + + sync_primitives::AutoReadLock lock(device_to_adapter_map_lock_); + DeviceToAdapterMap::iterator it = device_to_adapter_map_.find(device_id); + if (it == device_to_adapter_map_.end()) { + LOG4CXX_ERROR(logger_, "No device adapter found by id " << device_id); + return; + } + transport_adapter::TransportAdapter* ta = it->second; + + if (!ta) { + LOG4CXX_ERROR(logger_, + "Transport adapter for device: " << device_id << " is NULL"); + return; + } + + ta->RunAppOnDevice(device_id, bundle_id); + + return; +} + int TransportManagerImpl::ReceiveEventFromDevice( const TransportAdapterEvent& event) { LOG4CXX_TRACE(logger_, "enter. TransportAdapterEvent: " << &event); diff --git a/src/components/transport_manager/test/include/transport_manager/transport_adapter_mock.h b/src/components/transport_manager/test/include/transport_manager/transport_adapter_mock.h index d12741f49a..815b04930a 100644 --- a/src/components/transport_manager/test/include/transport_manager/transport_adapter_mock.h +++ b/src/components/transport_manager/test/include/transport_manager/transport_adapter_mock.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,8 +30,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SRC_COMPONENTS_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_ADAPTER_MOCK_H_ -#define SRC_COMPONENTS_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_ADAPTER_MOCK_H_ +#ifndef SRC_COMPONENTS_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_MANAGER_TRANSPORT_ADAPTER_MOCK_H_ +#define SRC_COMPONENTS_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_MANAGER_TRANSPORT_ADAPTER_MOCK_H_ #include "gmock/gmock.h" #include "transport_manager/transport_adapter/transport_adapter.h" @@ -66,6 +66,7 @@ class MockTransportAdapter MOCK_METHOD1(ConnectDevice, ::transport_manager::transport_adapter::TransportAdapter::Error( const ::transport_manager::DeviceUID& device_handle)); + MOCK_METHOD2(RunAppOnDevice, void(const std::string&, const std::string&)); MOCK_CONST_METHOD0(IsClientOriginatedConnectSupported, bool()); MOCK_METHOD0( StartClientListening, @@ -105,4 +106,4 @@ class MockTransportAdapter } // namespace components } // namespace test -#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_ADAPTER_MOCK_H_ +#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_MANAGER_TRANSPORT_ADAPTER_MOCK_H_ diff --git a/src/components/transport_manager/test/smartDeviceLink_test.ini b/src/components/transport_manager/test/smartDeviceLink_test.ini index 40aeb5a019..6fc8ab63ec 100644 --- a/src/components/transport_manager/test/smartDeviceLink_test.ini +++ b/src/components/transport_manager/test/smartDeviceLink_test.ini @@ -53,3 +53,18 @@ ResumptionDelayAfterIgn = 30; # Resumption ctrl uses JSON if UseDBForResumption=false for store data otherwise uses DB UseDBForResumption = false +[AppLaunch] +; time in milliseconds started from device connection - after expiring SDL remotely launches all known not-yet-registered apps from this device +AppLaunchWaitTime = 5000 +; the number of times SDL attempts to launch an application after device connection - applied separately to each application from the given device +AppLaunchMaxRetryAttempt = 3 +; time in milliseconds started by SDL after app launch request. if expired and app did not register, SDL sends new launch request. applied separately to each app +AppLaunchRetryWaitTime = 15000 +; the number of the given device connections that the requested application failed to register after SDL's launch attempts - SDL removes app's bundleID on "value + 1" device connection +RemoveBundleIDattempts = 3 +; the maximum number of iOS devices for which entries can be remembered by SDL +MaxNumberOfiOSDevice = 10 +; time in milliseconds started after request to launch the first app. after either expires or the first app registers SDL requests to launch the second app. +WaitTimeBetweenApps = 4000 +; App Launch on iOS devices SDL feature enabler/disabler +EnableAppLaunchIOS = true diff --git a/src/components/transport_manager/test/transport_manager_impl_test.cc b/src/components/transport_manager/test/transport_manager_impl_test.cc index ddfd827358..2fac0bfd56 100644 --- a/src/components/transport_manager/test/transport_manager_impl_test.cc +++ b/src/components/transport_manager/test/transport_manager_impl_test.cc @@ -319,9 +319,7 @@ class TransportManagerImplTest : public ::testing::Test { MockTransportAdapter* mock_adapter_; utils::SharedPtr<TransportManagerListenerMock> tm_listener_; - const ApplicationHandle application_id_ = 1; - ConnectionUID connection_key_; RawMessagePtr test_message_; DeviceHandle device_handle_; @@ -508,9 +506,9 @@ TEST_F(TransportManagerImplTest, SendMessageToDevice_SendingFailed) { // Arrange HandleConnection(); - MockTMTelemetryObserver* mock_metric_observer = new MockTMTelemetryObserver(); - tm_.SetTelemetryObserver(mock_metric_observer); - EXPECT_CALL(*mock_metric_observer, StartRawMsg(_)); +#ifdef TELEMETRY_MONITOR + EXPECT_CALL(mock_metric_observer_, StartRawMsg(_)); +#endif // TELEMETRY_MONITOR EXPECT_CALL(*mock_adapter_, SendData(mac_address_, application_id_, test_message_)) @@ -518,26 +516,25 @@ TEST_F(TransportManagerImplTest, SendMessageToDevice_SendingFailed) { EXPECT_CALL(*tm_listener_, OnTMMessageSendFailed(_, test_message_)); EXPECT_EQ(E_SUCCESS, tm_.SendMessageToDevice(test_message_)); +#ifdef TELEMETRY_MONITOR + EXPECT_CALL(mock_metric_observer_, StopRawMsg(_)).Times(0); +#endif // TELEMETRY_MONITOR - EXPECT_CALL(*mock_metric_observer, StopRawMsg(_)).Times(0); - - delete mock_metric_observer; testing::Mock::AsyncVerifyAndClearExpectations(kAsyncExpectationsTimeout); } TEST_F(TransportManagerImplTest, SendMessageToDevice_StartTimeObserver) { // Arrange HandleConnection(); - - MockTMTelemetryObserver* mock_metric_observer = new MockTMTelemetryObserver(); - tm_.SetTelemetryObserver(mock_metric_observer); EXPECT_CALL(*mock_adapter_, SendData(mac_address_, application_id_, test_message_)) .WillOnce(Return(TransportAdapter::OK)); - EXPECT_CALL(*mock_metric_observer, StartRawMsg(_)); + +#ifdef TELEMETRY_MONITOR + EXPECT_CALL(mock_metric_observer_, StartRawMsg(_)); +#endif // TELEMETRY_MONITOR EXPECT_EQ(E_SUCCESS, tm_.SendMessageToDevice(test_message_)); - delete mock_metric_observer; testing::Mock::AsyncVerifyAndClearExpectations(kAsyncExpectationsTimeout); } @@ -548,7 +545,9 @@ TEST_F(TransportManagerImplTest, SendMessageToDevice_SendDone) { EXPECT_CALL(*mock_adapter_, SendData(mac_address_, application_id_, test_message_)) .WillOnce(Return(TransportAdapter::OK)); +#ifdef TELEMETRY_MONITOR EXPECT_CALL(mock_metric_observer_, StartRawMsg(test_message_.get())); +#endif // TELEMETRY_MONITOR EXPECT_EQ(E_SUCCESS, tm_.SendMessageToDevice(test_message_)); HandleSendDone(); @@ -563,7 +562,9 @@ TEST_F(TransportManagerImplTest, SendMessageFailed_GetHandleSendFailed) { EXPECT_CALL(*mock_adapter_, SendData(mac_address_, application_id_, test_message_)) .WillOnce(Return(TransportAdapter::FAIL)); +#ifdef TELEMETRY_MONITOR EXPECT_CALL(mock_metric_observer_, StartRawMsg(test_message_.get())); +#endif // TELEMETRY_MONITOR EXPECT_CALL(*tm_listener_, OnTMMessageSendFailed(_, test_message_)); EXPECT_EQ(E_SUCCESS, tm_.SendMessageToDevice(test_message_)); diff --git a/src/components/utils/include/utils/timer.h b/src/components/utils/include/utils/timer.h index 690c9df5dc..ab3d48ef6f 100644 --- a/src/components/utils/include/utils/timer.h +++ b/src/components/utils/include/utils/timer.h @@ -47,6 +47,23 @@ namespace timer { typedef uint32_t Milliseconds; /** + * @brief Enumeration listing of possible timer types. + * Single shot timer signals only once and then stops counting. + * Periodic timer signals every time specific value is reached + * and then restarts. + */ +enum TimerType { + /** + * @brief Periodic calls to task + */ + kPeriodic = 0, + /** + * @brief Single call to task + */ + kSingleShot = 1 +}; + +/** * @brief Timer calls custom callback function after * specified timeout has been elapsed. * Thread-safe class @@ -70,9 +87,9 @@ class Timer { /** * @brief Starts timer with specified timeout * @param timeout Timer timeout - * @param single_shot Single shot flag for timer + * @param enum timer_type Timer type enum value. */ - void Start(const Milliseconds timeout, const bool single_shot); + void Start(const Milliseconds timeout, const TimerType timer_type); /** * @brief Stops timer if it's running diff --git a/src/components/utils/src/timer.cc b/src/components/utils/src/timer.cc index 00272a73eb..642f16e574 100644 --- a/src/components/utils/src/timer.cc +++ b/src/components/utils/src/timer.cc @@ -71,11 +71,22 @@ timer::Timer::~Timer() { LOG4CXX_DEBUG(logger_, "Timer " << name_ << " has been destroyed"); } -void timer::Timer::Start(const Milliseconds timeout, const bool single_shot) { +void timer::Timer::Start(const Milliseconds timeout, + const TimerType timer_type) { LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock auto_lock(state_lock_); StopThread(); - single_shot_ = single_shot; + switch (timer_type) { + case kSingleShot: { + single_shot_ = true; + break; + } + case kPeriodic: { + single_shot_ = false; + break; + } + default: { ASSERT("timer_type should be kSingleShot or kPeriodic"); } + }; StartDelegate(timeout); StartThread(); LOG4CXX_DEBUG(logger_, "Timer " << name_ << " has been started"); diff --git a/src/components/utils/test/test_generator/MOBILE_API.xml b/src/components/utils/test/test_generator/MOBILE_API.xml index 01ea48dce9..4de719bd7e 100644 --- a/src/components/utils/test/test_generator/MOBILE_API.xml +++ b/src/components/utils/test/test_generator/MOBILE_API.xml @@ -1517,6 +1517,26 @@ </struct> + <struct name="AppInfo"> + <description>Contains detailed information about the registered application.</description> + + <param name="appDisplayName" type="String" maxlength="100" mandatory="true"> + <description>The name displayed for the mobile application on the mobile device (can differ from the app name set in the initial RAI request).</description> + </param> + + <param name="appBundleID" type="String" maxlength="256" mandatory="true"> + <description>The AppBundleID of an iOS application or package name of the Android application. This supports App Launch strategies for each platform.</description> + </param> + + <param name="appVersion" type="String" maxlength="256" mandatory="true"> + <description>Represents the build version number of this particular mobile app.</description> + </param> + + <param name="appIcon" type="String" maxlength="500" mandatory="false"> + <description>A file reference to the icon utilized by this app (simplifies the process of setting an app icon during app registration).</description> + </param> + </struct> + <enum name="FileType"> <description>Enumeration listing possible file types.</description> <element name="GRAPHIC_BMP" /> @@ -2359,6 +2379,11 @@ <param name="appID" type="String" maxlength="100" mandatory="true"> <description>ID used to validate app with policy table entries</description> </param> + <param name="appInfo" type="AppInfo" mandatory="false"> + <description> + See AppInfo. + </description> + </param> </function> <function name="RegisterAppInterface" functionID="RegisterAppInterfaceID" messagetype="response"> diff --git a/src/components/utils/test/timer_test.cc b/src/components/utils/test/timer_test.cc index 63b3c663c3..ea5c9f0b84 100644 --- a/src/components/utils/test/timer_test.cc +++ b/src/components/utils/test/timer_test.cc @@ -47,12 +47,11 @@ sync_primitives::Lock shot_lock; sync_primitives::ConditionalVariable shot_condition; const std::string kTimerName = "TestTimer"; -const bool kSingleShot = true; /* * Default timeout used during timer testing. * Value should be greater than at least 30 ms - * to avoid timer firing beetwen two sequental Start/Stop calls + * to avoid timer firing between two sequental Start/Stop calls */ const uint32_t kDefaultTimeoutMs = 30u; const uint32_t kDefaultTimeoutRestartMs = 45u; @@ -87,7 +86,7 @@ class TestTaskWithStart : public TestTask { public: void PerformTimer() const OVERRIDE { if (timer_) { - timer_->Start(kDefaultTimeoutRestartMs, !kSingleShot); + timer_->Start(kDefaultTimeoutRestartMs, timer::kPeriodic); } } }; @@ -113,7 +112,7 @@ TEST(TimerTest, Start_Stop_NoLoop_NoCall) { EXPECT_FALSE(timer.is_running()); EXPECT_EQ(0u, timer.timeout()); - timer.Start(kDefaultTimeoutMs, kSingleShot); + timer.Start(kDefaultTimeoutMs, timer::kSingleShot); EXPECT_TRUE(timer.is_running()); EXPECT_EQ(kDefaultTimeoutMs, timer.timeout()); @@ -130,7 +129,7 @@ TEST(TimerTest, Start_Stop_Loop_NoCall) { EXPECT_FALSE(timer.is_running()); EXPECT_EQ(0u, timer.timeout()); - timer.Start(kDefaultTimeoutMs, !kSingleShot); + timer.Start(kDefaultTimeoutMs, timer::kPeriodic); EXPECT_TRUE(timer.is_running()); EXPECT_EQ(kDefaultTimeoutMs, timer.timeout()); @@ -147,7 +146,7 @@ TEST(TimerTest, Start_Stop_NoLoop_OneCall) { EXPECT_FALSE(timer.is_running()); EXPECT_EQ(0u, timer.timeout()); - timer.Start(kDefaultTimeoutMs, kSingleShot); + timer.Start(kDefaultTimeoutMs, timer::kSingleShot); EXPECT_TRUE(timer.is_running()); EXPECT_EQ(kDefaultTimeoutMs, timer.timeout()); @@ -172,7 +171,7 @@ TEST(TimerTest, Start_Stop_Loop_3Calls) { EXPECT_FALSE(timer.is_running()); EXPECT_EQ(0u, timer.timeout()); - timer.Start(kDefaultTimeoutMs, !kSingleShot); + timer.Start(kDefaultTimeoutMs, timer::kPeriodic); EXPECT_TRUE(timer.is_running()); EXPECT_EQ(kDefaultTimeoutMs, timer.timeout()); @@ -197,11 +196,11 @@ TEST(TimerTest, Restart_NoLoop_NoCall) { timer::Timer timer(kTimerName, mock_task); - timer.Start(kDefaultTimeoutMs, kSingleShot); + timer.Start(kDefaultTimeoutMs, timer::kSingleShot); EXPECT_TRUE(timer.is_running()); EXPECT_EQ(kDefaultTimeoutMs, timer.timeout()); - timer.Start(kDefaultTimeoutRestartMs, kSingleShot); + timer.Start(kDefaultTimeoutRestartMs, timer::kSingleShot); EXPECT_TRUE(timer.is_running()); EXPECT_EQ(kDefaultTimeoutRestartMs, timer.timeout()); } @@ -212,11 +211,11 @@ TEST(TimerTest, Restart_Loop_NoCall) { timer::Timer timer(kTimerName, mock_task); - timer.Start(kDefaultTimeoutMs, !kSingleShot); + timer.Start(kDefaultTimeoutMs, timer::kPeriodic); EXPECT_TRUE(timer.is_running()); EXPECT_EQ(kDefaultTimeoutMs, timer.timeout()); - timer.Start(kDefaultTimeoutRestartMs, !kSingleShot); + timer.Start(kDefaultTimeoutRestartMs, timer::kPeriodic); EXPECT_TRUE(timer.is_running()); EXPECT_EQ(kDefaultTimeoutRestartMs, timer.timeout()); } @@ -228,7 +227,7 @@ TEST(TimerTest, Restart_Loop_3Calls) { TestTask* task = new TestTask(); timer::Timer timer(kTimerName, task); - timer.Start(kDefaultTimeoutMs, !kSingleShot); + timer.Start(kDefaultTimeoutMs, timer::kPeriodic); EXPECT_TRUE(timer.is_running()); EXPECT_EQ(kDefaultTimeoutMs, timer.timeout()); @@ -236,7 +235,7 @@ TEST(TimerTest, Restart_Loop_3Calls) { for (size_t i = 0; i < loops_count; ++i) { shot_condition.Wait(shot_lock); } - timer.Start(kDefaultTimeoutRestartMs, !kSingleShot); + timer.Start(kDefaultTimeoutRestartMs, timer::kPeriodic); EXPECT_TRUE(timer.is_running()); EXPECT_EQ(kDefaultTimeoutRestartMs, timer.timeout()); @@ -251,7 +250,7 @@ TEST(TimerTest, Restart_NoLoop_FromCall) { timer::Timer timer(kTimerName, task); task->set_timer(&timer); - timer.Start(kDefaultTimeoutMs, kSingleShot); + timer.Start(kDefaultTimeoutMs, timer::kSingleShot); EXPECT_TRUE(timer.is_running()); EXPECT_EQ(kDefaultTimeoutMs, timer.timeout()); @@ -270,7 +269,7 @@ TEST(TimerTest, Restart_Loop_FromCall) { timer::Timer timer(kTimerName, task); task->set_timer(&timer); - timer.Start(kDefaultTimeoutMs, !kSingleShot); + timer.Start(kDefaultTimeoutMs, timer::kPeriodic); EXPECT_TRUE(timer.is_running()); EXPECT_EQ(kDefaultTimeoutMs, timer.timeout()); @@ -291,7 +290,7 @@ TEST(TimerTest, Stop_Loop_FromCall) { timer::Timer timer(kTimerName, task); task->set_timer(&timer); - timer.Start(kDefaultTimeoutMs, !kSingleShot); + timer.Start(kDefaultTimeoutMs, timer::kPeriodic); EXPECT_TRUE(timer.is_running()); EXPECT_EQ(kDefaultTimeoutMs, timer.timeout()); @@ -314,7 +313,7 @@ TEST(TimerTest, Delete_Running_NoLoop) { EXPECT_FALSE(timer->is_running()); EXPECT_EQ(0u, timer->timeout()); - timer->Start(kDefaultTimeoutMs, kSingleShot); + timer->Start(kDefaultTimeoutMs, timer::kSingleShot); EXPECT_TRUE(timer->is_running()); EXPECT_EQ(kDefaultTimeoutMs, timer->timeout()); |