summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Hrytsevich <AGritsevich@luxoft.com>2016-05-28 16:19:39 +0300
committerLevchenko <slevchenko@SLevchenko-lws-unq>2016-08-04 17:30:29 +0300
commit3d6ded95790263fb9c434703ab346bec18542ebe (patch)
treed492e3921ea0a1bf6fe39fcb0cf6b138ffc8c827
parentf0ab94ebeed8a82e355ca6838e4b427831789288 (diff)
downloadsdl_core-3d6ded95790263fb9c434703ab346bec18542ebe.tar.gz
AppLaunchData common implementation
Related issue : APPLINK-24892
-rw-r--r--src/components/application_manager/include/application_manager/app_launch/app_launch_data.h4
-rw-r--r--src/components/application_manager/include/application_manager/app_launch/app_launch_data_db.h168
-rw-r--r--src/components/application_manager/include/application_manager/app_launch/app_launch_data_impl.h136
-rw-r--r--src/components/application_manager/include/application_manager/app_launch/app_launch_data_json.h156
-rw-r--r--src/components/application_manager/include/application_manager/app_launch/app_launch_sql_queries.h51
-rw-r--r--src/components/application_manager/src/app_launch/app_launch_data_db.cc396
-rw-r--r--src/components/application_manager/src/app_launch/app_launch_data_impl.cc83
-rw-r--r--src/components/application_manager/src/app_launch/app_launch_data_json.cc284
-rw-r--r--src/components/application_manager/src/app_launch/app_launch_sql_queries.cc78
-rw-r--r--src/components/application_manager/test/app_launch/app_launch_data_db_test.cc334
-rw-r--r--src/components/application_manager/test/app_launch/app_launch_data_json_test.cc344
11 files changed, 2032 insertions, 2 deletions
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
index 7c875520aa..0d52384018 100644
--- 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
@@ -81,8 +81,8 @@ class AppLaunchData {
/**
* @brief select from DB all records with this dev_mac
* @param app_data - data to inserting
- * @param dev_apps - pointer to vector with result of select
- * @return true in success cases and false othrewise
+ * @param dev_apps -
+ * @return vector of pointers on results of select
*/
virtual std::vector<ApplicationDataPtr> GetApplicationDataByDevice(
const std::string& dev_mac) = 0;
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..d70af6bba4
--- /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_QUERY_H_
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_APP_LAUNCH_APP_LAUNCH_SQL_QUERY_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_QUERY_H_
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..dc5474e280
--- /dev/null
+++ b/src/components/application_manager/src/app_launch/app_launch_data_json.cc
@@ -0,0 +1,284 @@
+/*
+ * 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/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..25cd1adfe6
--- /dev/null
+++ b/src/components/application_manager/test/app_launch/app_launch_data_db_test.cc
@@ -0,0 +1,334 @@
+/*
+ * 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 "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 test_app_launch {
+
+using namespace file_system;
+using namespace app_launch;
+
+using ::testing::ReturnRef;
+using ::testing::Return;
+using ::testing::NiceMock;
+
+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("mobile_app_id", "bundle_id", "device_mac");
+ AddApplicationDataWithIncreaseTable(data);
+ ApplicationData recoveredData("", "", "");
+ GetApplicationData(data, recoveredData);
+ EXPECT_TRUE(data == recoveredData);
+}
+
+TEST_F(AppLaunchDataDBTest, 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_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("mobile_app_id", "bundle_id", "device_mac");
+ ApplicationData recoverData = data;
+ AddApplicationDataWithIncreaseTable(data);
+ recoverData.device_mac_ += "test";
+ GetApplicationData(recoverData, recoverData);
+ EXPECT_FALSE(data == recoverData);
+}
+
+TEST_F(AppLaunchDataDBTest, MaxCount) {
+ const uint32_t mac_ios_devs = res_db()->get_max_number_iOS_devs();
+ for (uint32_t i = 0; i < mac_ios_devs; i++) {
+ ApplicationData data(AddCounter("mobile_app_id_", i),
+ AddCounter("bundle_id_", i),
+ "device_mac");
+ AddApplicationDataWithIncreaseTable(data);
+ }
+
+ utils::dbms::SQLQuery query(test_db());
+ ApplicationData changedRecord("mobile_app_id_0", "bundle_id_0", "device_mac");
+ 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(mac_ios_devs, size_max);
+ EXPECT_TRUE(res_db()->AddApplicationData(ApplicationData(
+ "mobile_app_id_last", "bundle_id_last", "device_mac_last")));
+ 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_part = res_db()->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_db()->GetApplicationDataByDevice(device_mac_1);
+ output_data2 = res_db()->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]);
+ }
+}
+
+// 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("mobile_app_id_", i),
+ AddCounter("bundle_id_", i),
+ "device_mac");
+ 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 test_app_launch
+} // 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..aee8456d58
--- /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<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