diff options
author | Anton Hrytsevich <AGritsevich@luxoft.com> | 2016-05-28 16:19:39 +0300 |
---|---|---|
committer | Levchenko <slevchenko@SLevchenko-lws-unq> | 2016-08-04 17:30:29 +0300 |
commit | 3d6ded95790263fb9c434703ab346bec18542ebe (patch) | |
tree | d492e3921ea0a1bf6fe39fcb0cf6b138ffc8c827 /src/components/application_manager/src/app_launch | |
parent | f0ab94ebeed8a82e355ca6838e4b427831789288 (diff) | |
download | sdl_core-3d6ded95790263fb9c434703ab346bec18542ebe.tar.gz |
AppLaunchData common implementation
Related issue : APPLINK-24892
Diffstat (limited to 'src/components/application_manager/src/app_launch')
4 files changed, 841 insertions, 0 deletions
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 |