summaryrefslogtreecommitdiff
path: root/src/components/policy/policy_external/src
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/policy/policy_external/src')
-rw-r--r--src/components/policy/policy_external/src/cache_manager.cc2664
-rw-r--r--src/components/policy/policy_external/src/policy_helper.cc868
-rw-r--r--src/components/policy/policy_external/src/policy_manager_impl.cc1883
-rw-r--r--src/components/policy/policy_external/src/policy_table.cc52
-rw-r--r--src/components/policy/policy_external/src/policy_table/enums.cc723
-rw-r--r--src/components/policy/policy_external/src/policy_table/types.cc2134
-rw-r--r--src/components/policy/policy_external/src/policy_table/validation.cc256
-rw-r--r--src/components/policy/policy_external/src/sql_pt_ext_queries.cc299
-rw-r--r--src/components/policy/policy_external/src/sql_pt_ext_representation.cc1937
-rw-r--r--src/components/policy/policy_external/src/sql_pt_queries.cc972
-rw-r--r--src/components/policy/policy_external/src/sql_pt_representation.cc1879
-rw-r--r--src/components/policy/policy_external/src/status.cc139
-rw-r--r--src/components/policy/policy_external/src/update_status_manager.cc262
-rw-r--r--src/components/policy/policy_external/src/usage_statistics/counter.cc126
14 files changed, 14194 insertions, 0 deletions
diff --git a/src/components/policy/policy_external/src/cache_manager.cc b/src/components/policy/policy_external/src/cache_manager.cc
new file mode 100644
index 0000000000..22040c88b2
--- /dev/null
+++ b/src/components/policy/policy_external/src/cache_manager.cc
@@ -0,0 +1,2664 @@
+/*
+ * Copyright (c) 2014, 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 "policy/cache_manager.h"
+
+#include <algorithm>
+#include <functional>
+#include <ctime>
+#include <cmath>
+#include <utility>
+#include <string>
+#include <vector>
+
+#include "utils/file_system.h"
+#include "json/reader.h"
+#include "json/features.h"
+#include "json/writer.h"
+#include "utils/logger.h"
+#include "utils/date_time.h"
+#include "utils/gen_hash.h"
+#include "utils/threads/thread.h"
+#include "utils/threads/thread_delegate.h"
+#include "rpc_base/rpc_base.h"
+#include "policy/policy_table/enums.h"
+#include "policy/policy_helper.h"
+#include "policy/sql_pt_ext_representation.h"
+
+namespace policy_table = rpc::policy_table_interface_base;
+
+namespace {
+
+/**
+ * @brief Looks for ExternalConsent entity in the list of entities
+ * @param entities ExternalConsent entities list
+ * @param entity Entity to look for
+ * @return True if found in the list, otherwise - false
+ */
+bool IsEntityExists(
+ const policy_table::DisallowedByExternalConsentEntities& entities,
+ const policy_table::ExternalConsentEntity& entity) {
+ const policy_table::DisallowedByExternalConsentEntities::const_iterator
+ it_entity = std::find(entities.begin(), entities.end(), entity);
+
+ return entities.end() != it_entity;
+}
+
+/**
+ * @brief Looks for ExternalConsent entity in
+ * disallowed_by_external_consent_entities_on/off sections
+ * of each functional group
+ */
+struct GroupByEntityFinder
+ : public std::unary_function<
+ void,
+ const policy_table::FunctionalGroupings::value_type&> {
+ GroupByEntityFinder(
+ const policy::ExternalConsentStatusItem& external_consent_item,
+ policy::GroupsByExternalConsentStatus& out_groups_by_external_consent)
+ : external_consent_item_(external_consent_item)
+ , out_groups_by_external_consent_(out_groups_by_external_consent) {}
+
+ void operator()(
+ const policy_table::FunctionalGroupings::value_type& group) const {
+ if (!group.second.user_consent_prompt.is_initialized()) {
+ return;
+ }
+
+ policy_table::ExternalConsentEntity entity(
+ external_consent_item_.entity_type_, external_consent_item_.entity_id_);
+ const std::string group_name = group.first;
+
+ if (IsEntityExists(*group.second.disallowed_by_external_consent_entities_on,
+ entity)) {
+ const bool disallowed_by_external_consent_entities_on_marker = true;
+ out_groups_by_external_consent_[external_consent_item_].push_back(
+ std::make_pair(group_name,
+ disallowed_by_external_consent_entities_on_marker));
+ }
+
+ if (IsEntityExists(
+ *group.second.disallowed_by_external_consent_entities_off,
+ entity)) {
+ const bool disallowed_by_external_consent_entities_off_marker = false;
+ out_groups_by_external_consent_[external_consent_item_].push_back(
+ std::make_pair(group_name,
+ disallowed_by_external_consent_entities_off_marker));
+ }
+ }
+
+ private:
+ const policy::ExternalConsentStatusItem& external_consent_item_;
+ policy::GroupsByExternalConsentStatus& out_groups_by_external_consent_;
+};
+
+/**
+ * @brief Maps ExternalConsent status item to the list of functional groups
+ * names specifying
+ * container where item is found. If item is not found it won't be added.
+ */
+struct GroupByExternalConsentItemFinder
+ : public std::unary_function<
+ void,
+ const policy::ExternalConsentStatus::value_type&> {
+ GroupByExternalConsentItemFinder(
+ const policy_table::FunctionalGroupings& groups,
+ policy::GroupsByExternalConsentStatus& out_groups_by_external_consent)
+ : groups_(groups), out_groups_by_css_(out_groups_by_external_consent) {}
+
+ void operator()(const policy::ExternalConsentStatus::value_type&
+ external_consent_item) const {
+ GroupByEntityFinder group_finder(external_consent_item, out_groups_by_css_);
+ std::for_each(groups_.begin(), groups_.end(), group_finder);
+ }
+
+ private:
+ const policy_table::FunctionalGroupings& groups_;
+ policy::GroupsByExternalConsentStatus& out_groups_by_css_;
+};
+
+/**
+ * @brief Template for getting 'first' of std::pair to use with standard
+ * algorithm below
+ */
+template <typename T1, typename T2>
+const T1& pair_first(const std::pair<T1, T2>& item) {
+ return item.first;
+}
+
+/**
+ * @brief Collects known links device-to-application form
+ * device_data/user_consent_records is any record is present
+ */
+struct LinkCollector
+ : public std::unary_function<void,
+ const policy_table::DeviceData::value_type&> {
+ typedef std::vector<policy_table::UserConsentRecords::key_type>
+ ApplicationsIds;
+
+ LinkCollector(std::map<std::string, std::string>& links) : links_(links) {}
+
+ void operator()(const policy_table::DeviceData::value_type& value) {
+ using namespace policy_table;
+
+ device_id_ = value.first;
+
+ ApplicationsIds applications_ids;
+ std::transform(value.second.user_consent_records->begin(),
+ value.second.user_consent_records->end(),
+ std::back_inserter(applications_ids),
+ &pair_first<UserConsentRecords::key_type,
+ UserConsentRecords::mapped_type>);
+
+ std::for_each(applications_ids.begin(),
+ applications_ids.end(),
+ std::bind1st(std::mem_fun(&LinkCollector::FillLinks), this));
+ }
+
+ private:
+ void FillLinks(const ApplicationsIds::value_type app_id) const {
+ links_.insert(std::make_pair(device_id_, app_id));
+ }
+
+ std::string device_id_;
+ std::map<std::string, std::string>& links_;
+};
+
+/**
+ * @brief Returns group consent record constructed from input group permissions
+ */
+struct ExternalConsentConsentGroupAppender
+ : public std::unary_function<policy_table::ConsentGroups,
+ const policy::FunctionalGroupPermission&> {
+ policy_table::ConsentGroups::value_type operator()(
+ const policy::FunctionalGroupPermission& value) const {
+ return std::make_pair(value.group_name,
+ rpc::Boolean(value.state == policy::kGroupAllowed));
+ }
+};
+
+} // namespace
+
+namespace policy {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Policy")
+
+#define CACHE_MANAGER_CHECK(return_value) \
+ { \
+ if (!pt_) { \
+ LOG4CXX_WARN(logger_, "The cache manager is not initialized"); \
+ return return_value; \
+ } \
+ }
+
+#define CACHE_MANAGER_CHECK_VOID() \
+ { \
+ if (!pt_) { \
+ LOG4CXX_WARN(logger_, "The cache manager is not initialized"); \
+ return; \
+ } \
+ }
+
+struct LanguageFinder {
+ explicit LanguageFinder(const std::string& language) : language_(language) {}
+ bool operator()(const policy_table::Languages::value_type& lang) const {
+ return !strcasecmp(language_.c_str(), lang.first.c_str());
+ }
+
+ private:
+ const std::string& language_;
+};
+
+policy_table::MessageString FindLanguage(
+ const policy_table::MessageLanguages& msg_languages,
+ const std::string& lang) {
+ LanguageFinder finder(lang);
+ policy_table::Languages::const_iterator it = std::find_if(
+ msg_languages.languages.begin(), msg_languages.languages.end(), finder);
+ return (msg_languages.languages.end() == it) ? policy_table::MessageString()
+ : it->second;
+}
+
+CacheManager::CacheManager()
+ : CacheManagerInterface()
+ , pt_(new policy_table::Table)
+ , backup_(new SQLPTExtRepresentation())
+ , update_required(false) {
+ InitBackupThread();
+}
+
+CacheManager::CacheManager(bool in_memory)
+ : CacheManagerInterface()
+ , pt_(new policy_table::Table)
+ , backup_(new SQLPTExtRepresentation(in_memory))
+ , update_required(false) {
+ InitBackupThread();
+}
+
+CacheManager::~CacheManager() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(backuper_locker_);
+ backup_thread_->join();
+ delete backup_thread_->delegate();
+ threads::DeleteThread(backup_thread_);
+}
+
+ConsentPriorityType CacheManager::GetConsentsPriority(
+ const std::string& device_id, const std::string& application_id) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ ConsentPriorityType prio_type = ConsentPriorityType::kExternalConsentPrio;
+ CACHE_MANAGER_CHECK(prio_type);
+ policy_table::DeviceData::const_iterator dev_params_iter =
+ pt_->policy_table.device_data->find(device_id);
+
+ if (pt_->policy_table.device_data->end() == dev_params_iter) {
+ LOG4CXX_DEBUG(logger_, "Device id " << device_id << " not found.");
+ return prio_type;
+ }
+
+ const policy_table::DeviceParams& dev_par = (*dev_params_iter).second;
+
+ policy_table::UserConsentRecords::const_iterator app_consent_record =
+ dev_par.user_consent_records->find(application_id);
+
+ if (dev_par.user_consent_records->end() == app_consent_record) {
+ LOG4CXX_DEBUG(logger_,
+ "Application id " << application_id << " not found.");
+ return prio_type;
+ }
+
+ const policy_table::ConsentRecords& record = app_consent_record->second;
+
+ return record.consent_last_updated > record.ext_consent_last_updated
+ ? ConsentPriorityType::kUserConsentPrio
+ : ConsentPriorityType::kExternalConsentPrio;
+}
+
+const policy_table::Strings& CacheManager::GetGroups(const PTString& app_id) {
+ return pt_->policy_table.app_policies_section.apps[app_id].groups;
+}
+
+bool CacheManager::CanAppKeepContext(const std::string& app_id) const {
+ CACHE_MANAGER_CHECK(false);
+ bool result = false;
+ if (kDeviceId == app_id) {
+ result = pt_->policy_table.app_policies_section.device.keep_context;
+ } else if (IsApplicationRepresented(app_id)) {
+ result = pt_->policy_table.app_policies_section.apps[app_id].keep_context;
+ }
+ return result;
+}
+
+uint32_t CacheManager::HeartBeatTimeout(const std::string& app_id) const {
+ CACHE_MANAGER_CHECK(0);
+ uint32_t result = 0;
+ if (!IsApplicationRepresented(app_id)) {
+ return result;
+ }
+
+ const policy_table::ApplicationPolicies::mapped_type& app =
+ pt_->policy_table.app_policies_section.apps[app_id];
+ if (app.heart_beat_timeout_ms.is_initialized()) {
+ result = *(app.heart_beat_timeout_ms);
+ }
+
+ return result;
+}
+
+const policy_table::AppHMITypes* CacheManager::GetHMITypes(
+ const std::string& app_id) {
+ const policy_table::ApplicationPolicies& apps =
+ pt_->policy_table.app_policies_section.apps;
+ policy_table::ApplicationPolicies::const_iterator i = apps.find(app_id);
+ if (i != apps.end()) {
+ return &(*i->second.AppHMIType);
+ }
+ return NULL;
+}
+
+int32_t CacheManager::GenerateHash(const std::string& str_to_hash) {
+ uint32_t hash = 5381U;
+ std::string::const_iterator it = str_to_hash.begin();
+ std::string::const_iterator it_end = str_to_hash.end();
+
+ for (; it != it_end; ++it) {
+ hash = ((hash << 5) + hash) + (*it);
+ }
+
+ // Reset sign bit in case it has been set.
+ // This is needed to avoid overflow for signed int.
+ const int32_t result = hash & 0x7FFFFFFF;
+ return result;
+}
+
+bool CacheManager::CanAppStealFocus(const std::string& app_id) const {
+ CACHE_MANAGER_CHECK(false);
+ bool result = false;
+ if (kDeviceId == app_id) {
+ result = pt_->policy_table.app_policies_section.device.steal_focus;
+ } else if (IsApplicationRepresented(app_id)) {
+ result = pt_->policy_table.app_policies_section.apps[app_id].steal_focus;
+ }
+ return result;
+}
+
+bool CacheManager::GetDefaultHMI(const std::string& app_id,
+ std::string& default_hmi) const {
+ CACHE_MANAGER_CHECK(false);
+ bool result = false;
+ default_hmi.clear();
+ if (kDeviceId == app_id) {
+ default_hmi = EnumToJsonString(
+ pt_->policy_table.app_policies_section.device.default_hmi);
+ } else if (IsApplicationRepresented(app_id)) {
+ default_hmi = EnumToJsonString(
+ pt_->policy_table.app_policies_section.apps[app_id].default_hmi);
+ }
+ result = !default_hmi.empty();
+
+ return result;
+}
+
+bool CacheManager::ResetUserConsent() {
+ CACHE_MANAGER_CHECK(false);
+ sync_primitives::AutoLock lock(cache_lock_);
+ policy_table::DeviceData::iterator iter =
+ pt_->policy_table.device_data->begin();
+ policy_table::DeviceData::iterator iter_end =
+ pt_->policy_table.device_data->end();
+
+ for (; iter != iter_end; ++iter) {
+ iter->second.user_consent_records->clear();
+ }
+ Backup();
+ return true;
+}
+
+bool CacheManager::GetUserPermissionsForDevice(
+ const std::string& device_id,
+ StringArray& consented_groups,
+ StringArray& disallowed_groups) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ policy_table::DeviceData& device_data = *pt_->policy_table.device_data;
+ if (device_data.end() == device_data.find(device_id)) {
+ LOG4CXX_ERROR(logger_,
+ "Device with " << device_id << "was not found in PT");
+ return false;
+ }
+ const policy_table::DeviceParams& params = device_data[device_id];
+ const policy_table::UserConsentRecords& ucr = *(params.user_consent_records);
+ policy_table::UserConsentRecords::const_iterator iter = ucr.begin();
+ policy_table::UserConsentRecords::const_iterator iter_end = ucr.end();
+
+ for (; iter != iter_end; ++iter) {
+ policy_table::ConsentGroups::const_iterator con_iter;
+ policy_table::ConsentGroups::const_iterator con_iter_end;
+
+ con_iter = (*iter).second.consent_groups->begin();
+ con_iter_end = (*iter).second.consent_groups->end();
+ for (; con_iter != con_iter_end; ++con_iter) {
+ if (true == (*con_iter).second) {
+ consented_groups.push_back((*con_iter).first);
+ } else {
+ disallowed_groups.push_back((*con_iter).first);
+ }
+ }
+ }
+ return true;
+}
+
+void CacheManager::GetAllAppGroups(const std::string& app_id,
+ FunctionalGroupIDs& all_group_ids) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+ if (kDeviceId == app_id) {
+ policy_table::DevicePolicy& device =
+ pt_->policy_table.app_policies_section.device;
+
+ policy_table::Strings::const_iterator iter = device.groups.begin();
+ policy_table::Strings::const_iterator iter_end = device.groups.end();
+
+ for (; iter != iter_end; ++iter) {
+ const uint32_t group_id =
+ static_cast<uint32_t>((utils::Djb2HashFromString(*iter)));
+ all_group_ids.push_back(group_id);
+ }
+
+ return;
+ }
+
+ policy_table::ApplicationPolicies::const_iterator app_params_iter =
+ pt_->policy_table.app_policies_section.apps.find(app_id);
+
+ if (pt_->policy_table.app_policies_section.apps.end() != app_params_iter) {
+ policy_table::Strings::const_iterator iter =
+ (*app_params_iter).second.groups.begin();
+ policy_table::Strings::const_iterator iter_end =
+ (*app_params_iter).second.groups.end();
+
+ for (; iter != iter_end; ++iter) {
+ const uint32_t group_id =
+ static_cast<uint32_t>((utils::Djb2HashFromString(*iter)));
+ all_group_ids.push_back(group_id);
+ }
+ }
+}
+
+void CacheManager::GetPreConsentedGroups(
+ const std::string& app_id, FunctionalGroupIDs& preconsented_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+ if (kDeviceId == app_id) {
+ policy_table::DevicePolicy& device =
+ pt_->policy_table.app_policies_section.device;
+
+ policy_table::Strings::const_iterator iter =
+ device.preconsented_groups->begin();
+ policy_table::Strings::const_iterator iter_end =
+ device.preconsented_groups->end();
+
+ for (; iter != iter_end; ++iter) {
+ const uint32_t group_id =
+ static_cast<uint32_t>((utils::Djb2HashFromString(*iter)));
+ preconsented_groups.push_back(group_id);
+ }
+
+ return;
+ }
+
+ policy_table::ApplicationPolicies::const_iterator app_param_iter =
+ pt_->policy_table.app_policies_section.apps.find(app_id);
+ if (pt_->policy_table.app_policies_section.apps.end() != app_param_iter) {
+ policy_table::Strings::const_iterator iter =
+ (*app_param_iter).second.preconsented_groups->begin();
+ policy_table::Strings::const_iterator iter_end =
+ (*app_param_iter).second.preconsented_groups->end();
+ for (; iter != iter_end; ++iter) {
+ const int32_t group_id = utils::Djb2HashFromString(*iter);
+
+ preconsented_groups.push_back(group_id);
+ }
+ }
+}
+
+void CacheManager::GetConsentedGroups(const std::string& device_id,
+ const std::string& app_id,
+ FunctionalGroupIDs& allowed_groups,
+ FunctionalGroupIDs& disallowed_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+ policy_table::DeviceData::iterator dev_params_iter =
+ pt_->policy_table.device_data->find(device_id);
+
+ if (pt_->policy_table.device_data->end() != dev_params_iter) {
+ const policy_table::DeviceParams& dev_par = (*dev_params_iter).second;
+
+ policy_table::UserConsentRecords::const_iterator iter =
+ dev_par.user_consent_records->find(app_id);
+
+ if (dev_par.user_consent_records->end() != iter) {
+ policy_table::ConsentGroups::const_iterator consent_iter =
+ (*iter).second.consent_groups->begin();
+ policy_table::ConsentGroups::const_iterator consent_iter_end =
+ (*iter).second.consent_groups->end();
+
+ for (; consent_iter != consent_iter_end; ++consent_iter) {
+ const int32_t group_id =
+ utils::Djb2HashFromString((*consent_iter).first);
+
+ if (true == (*consent_iter).second) {
+ allowed_groups.push_back(group_id);
+ } else {
+ disallowed_groups.push_back(group_id);
+ }
+ }
+ }
+ }
+}
+
+void CacheManager::GetUnconsentedGroups(
+ const std::string& device_id,
+ const std::string& policy_app_id,
+ FunctionalGroupIDs& unconsented_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+
+ if (!IsApplicationRepresented(policy_app_id)) {
+ LOG4CXX_WARN(logger_,
+ "The application with app_id: " << policy_app_id
+ << " is not reresented");
+ return;
+ }
+
+ policy_table::Strings::iterator iter_groups;
+ policy_table::Strings::iterator iter_groups_end;
+ if (kDeviceId == policy_app_id) {
+ iter_groups = pt_->policy_table.app_policies_section.device.groups.begin();
+ iter_groups_end =
+ pt_->policy_table.app_policies_section.device.groups.end();
+ } else {
+ iter_groups = pt_->policy_table.app_policies_section.apps[policy_app_id]
+ .groups.begin();
+ iter_groups_end =
+ pt_->policy_table.app_policies_section.apps[policy_app_id].groups.end();
+ }
+
+ for (; iter_groups != iter_groups_end; ++iter_groups) {
+ // Try to find app-specific group in common groups list;
+ policy_table::FunctionalGroupings::const_iterator func_groups =
+ pt_->policy_table.functional_groupings.find(*iter_groups);
+ if (pt_->policy_table.functional_groupings.end() != func_groups) {
+ // Check if groups have user consents field.
+ if (func_groups->second.user_consent_prompt.is_initialized()) {
+ // Try to find certain group among already consented groups.
+ policy_table::DeviceData::const_iterator device_iter =
+ pt_->policy_table.device_data->find(device_id);
+ if (pt_->policy_table.device_data->end() != device_iter) {
+ policy_table::UserConsentRecords::const_iterator ucr_iter =
+ device_iter->second.user_consent_records->find(policy_app_id);
+ if (device_iter->second.user_consent_records->end() != ucr_iter) {
+ if ((*ucr_iter).second.consent_groups->end() ==
+ (*ucr_iter).second.consent_groups->find(*iter_groups)) {
+ unconsented_groups.push_back(
+ utils::Djb2HashFromString(*iter_groups));
+ }
+ } else {
+ unconsented_groups.push_back(
+ utils::Djb2HashFromString(*iter_groups));
+ }
+ }
+ }
+ }
+ }
+}
+
+void CacheManager::RemoveAppConsentForGroup(const std::string& app_id,
+ const std::string& group_name) {
+ CACHE_MANAGER_CHECK_VOID();
+ policy_table::DeviceData::iterator device_iter =
+ pt_->policy_table.device_data->begin();
+ policy_table::DeviceData::iterator device_iter_end =
+ pt_->policy_table.device_data->end();
+
+ policy_table::UserConsentRecords::iterator ucr_iter;
+ for (; device_iter != device_iter_end; ++device_iter) {
+ ucr_iter = device_iter->second.user_consent_records->find(app_id);
+ if (device_iter->second.user_consent_records->end() != ucr_iter) {
+ ucr_iter->second.consent_groups->erase(group_name);
+ }
+ }
+}
+
+using rpc::policy_table_interface_base::RequestTypes;
+using rpc::policy_table_interface_base::RequestType;
+
+void CacheManager::ProcessUpdate(
+ const policy_table::ApplicationPolicies::const_iterator
+ initial_policy_iter) {
+ using namespace policy;
+ const RequestTypes& new_request_types =
+ *(initial_policy_iter->second.RequestType);
+
+ const std::string& app_id = initial_policy_iter->first;
+ RequestTypes merged_pt_request_types;
+
+ if (app_id == kDefaultId || app_id == kPreDataConsentId) {
+ if (new_request_types.is_omitted()) {
+ LOG4CXX_INFO(logger_,
+ "Application " << app_id
+ << " has omitted RequestTypes."
+ " Previous values will be kept.");
+ return;
+ }
+ if (new_request_types.empty()) {
+ if (new_request_types.is_cleaned_up()) {
+ LOG4CXX_INFO(logger_,
+ "Application " << app_id
+ << " has cleaned up all values."
+ " Previous values will be kept.");
+ return;
+ }
+ LOG4CXX_INFO(logger_,
+ "Application " << app_id
+ << " has empty RequestTypes."
+ " Any parameter will be allowed.");
+ }
+ merged_pt_request_types = new_request_types;
+ } else {
+ merged_pt_request_types = new_request_types;
+ }
+ pt_->policy_table.app_policies_section.apps[app_id] =
+ initial_policy_iter->second;
+ *(pt_->policy_table.app_policies_section.apps[app_id].RequestType) =
+ merged_pt_request_types;
+}
+
+bool CacheManager::ApplyUpdate(const policy_table::Table& update_pt) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ pt_->policy_table.functional_groupings =
+ update_pt.policy_table.functional_groupings;
+
+ policy_table::ApplicationPolicies::const_iterator iter =
+ update_pt.policy_table.app_policies_section.apps.begin();
+ policy_table::ApplicationPolicies::const_iterator iter_end =
+ update_pt.policy_table.app_policies_section.apps.end();
+
+ for (; iter != iter_end; ++iter) {
+ if (iter->second.is_null()) {
+ pt_->policy_table.app_policies_section.apps[iter->first] =
+ policy_table::ApplicationParams();
+ pt_->policy_table.app_policies_section.apps[iter->first].set_to_null();
+ pt_->policy_table.app_policies_section.apps[iter->first].set_to_string(
+ "");
+ } else if (policy::kDefaultId == (iter->second).get_string()) {
+ policy_table::ApplicationPolicies::const_iterator iter_default =
+ update_pt.policy_table.app_policies_section.apps.find(kDefaultId);
+ if (update_pt.policy_table.app_policies_section.apps.end() ==
+ iter_default) {
+ LOG4CXX_ERROR(logger_, "The default section was not found in PTU");
+ continue;
+ }
+ ProcessUpdate(iter_default);
+ } else {
+ ProcessUpdate(iter);
+ }
+ }
+
+ pt_->policy_table.app_policies_section.device =
+ update_pt.policy_table.app_policies_section.device;
+
+ pt_->policy_table.module_config.SafeCopyFrom(
+ update_pt.policy_table.module_config);
+
+ pt_->policy_table.consumer_friendly_messages.assign_if_valid(
+ update_pt.policy_table.consumer_friendly_messages);
+
+ ResetCalculatedPermissions();
+ Backup();
+
+ if (*pt_->policy_table.module_config.preloaded_pt && update_pt.is_valid()) {
+ *pt_->policy_table.module_config.preloaded_pt = false;
+ }
+
+ return true;
+}
+
+void CacheManager::GetHMIAppTypeAfterUpdate(
+ std::map<std::string, StringArray>& app_hmi_types) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+ policy_table::ApplicationPolicies::const_iterator policy_iter_begin =
+ pt_->policy_table.app_policies_section.apps.begin();
+ policy_table::ApplicationPolicies::const_iterator policy_iter_end =
+ pt_->policy_table.app_policies_section.apps.end();
+ std::vector<std::string> transform_app_hmi_types;
+ for (; policy_iter_begin != policy_iter_end; ++policy_iter_begin) {
+ const policy_table::ApplicationParams& app_params =
+ (*policy_iter_begin).second;
+ if (app_params.AppHMIType.is_initialized()) {
+ if (!(transform_app_hmi_types.empty())) {
+ transform_app_hmi_types.clear();
+ }
+ std::transform(app_params.AppHMIType->begin(),
+ app_params.AppHMIType->end(),
+ std::back_inserter(transform_app_hmi_types),
+ AppHMITypeToString());
+ app_hmi_types[(*policy_iter_begin).first] = transform_app_hmi_types;
+ }
+ }
+}
+
+bool CacheManager::AppHasHMIType(const std::string& application_id,
+ policy_table::AppHMIType hmi_type) const {
+ const policy_table::ApplicationPolicies& policies =
+ pt_->policy_table.app_policies_section.apps;
+
+ policy_table::ApplicationPolicies::const_iterator policy_iter =
+ policies.find(application_id);
+
+ if (policy_iter == policies.end()) {
+ return false;
+ }
+
+ if (policy_iter->second.AppHMIType.is_initialized()) {
+ return helpers::in_range(*(policy_iter->second.AppHMIType),
+ rpc::Enum<policy_table::AppHMIType>(hmi_type));
+ }
+
+ return false;
+}
+
+void CacheManager::Backup() {
+ sync_primitives::AutoLock lock(backuper_locker_);
+ DCHECK(backuper_);
+ backuper_->DoBackup();
+}
+
+std::string CacheManager::currentDateTime() {
+ time_t now = time(0);
+ struct tm tstruct;
+ char buf[80];
+ tstruct = *localtime(&now);
+ // ISO_8601 format is expected, e.g. “2000-01-01T12:18:53Z”
+ strftime(buf, sizeof(buf), "%Y-%m-%dT%XZ", &tstruct);
+ return buf;
+}
+
+bool CacheManager::GetPermissionsForApp(const std::string& device_id,
+ const std::string& app_id,
+ FunctionalIdType& group_types) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ GetAllAppGroups(app_id, group_types[kTypeGeneral]);
+ GetAllAppGroups(kDefaultId, group_types[kTypeDefault]);
+ GetAllAppGroups(kPreDataConsentId, group_types[kTypePreDataConsented]);
+ GetPreConsentedGroups(app_id, group_types[kTypePreconsented]);
+
+ GetConsentedGroups(device_id,
+ app_id,
+ group_types[kTypeAllowed],
+ group_types[kTypeDisallowed]);
+
+ GetUnconsentedGroups(device_id, app_id, group_types[kTypeUnconsented]);
+
+ GetAllAppGroups(kDeviceId, group_types[kTypeDevice]);
+ return true;
+}
+
+bool CacheManager::GetDeviceGroupsFromPolicies(
+ policy_table::Strings& groups,
+ policy_table::Strings& preconsented_groups) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ groups = pt_->policy_table.app_policies_section.device.groups;
+ preconsented_groups =
+ *(pt_->policy_table.app_policies_section.device).preconsented_groups;
+ return true;
+}
+
+bool CacheManager::IsDeviceConsentCached(const std::string& device_id) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ sync_primitives::AutoLock lock(cached_device_permissions_lock_);
+ CachedDevicePermissions::const_iterator cached_dev_consent_iter;
+ cached_dev_consent_iter = cached_device_permissions_.find(device_id);
+ return cached_dev_consent_iter != cached_device_permissions_.end();
+}
+
+DeviceConsent CacheManager::GetCachedDeviceConsent(
+ const std::string& device_id) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(cached_device_permissions_lock_);
+ DeviceConsent result = kDeviceHasNoConsent;
+ CACHE_MANAGER_CHECK(result);
+ CachedDevicePermissions::const_iterator cached_dev_consent_iter;
+ cached_dev_consent_iter = cached_device_permissions_.find(device_id);
+ if (cached_dev_consent_iter != cached_device_permissions_.end()) {
+ return cached_dev_consent_iter->second;
+ }
+ return result;
+}
+
+void CacheManager::SaveDeviceConsentToCache(const std::string& device_id,
+ const bool is_allowed) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+ sync_primitives::AutoLock lock(cached_device_permissions_lock_);
+ DeviceConsent result = is_allowed ? kDeviceAllowed : kDeviceDisallowed;
+ cached_device_permissions_[device_id] = result;
+}
+
+bool CacheManager::GetPermissionsList(StringArray& perm_list) const {
+ // Get device permission groups from app_policies section, which hadn't been
+ // preconsented
+ policy_table::Strings groups;
+ policy_table::Strings preconsented_groups;
+ if (!GetDeviceGroupsFromPolicies(groups, preconsented_groups)) {
+ LOG4CXX_WARN(logger_, "Can't get device groups from policies.");
+ return false;
+ }
+
+ std::for_each(groups.begin(),
+ groups.end(),
+ FunctionalGroupInserter(preconsented_groups, perm_list));
+ return true;
+}
+
+bool CacheManager::HasDeviceSpecifiedConsent(const std::string& device_id,
+ const bool is_allowed) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Device :" << device_id);
+ const DeviceConsent current_consent = GetDeviceConsent(device_id);
+ const bool is_current_device_allowed =
+ DeviceConsent::kDeviceAllowed == current_consent ? true : false;
+
+ if (DeviceConsent::kDeviceHasNoConsent == current_consent ||
+ is_current_device_allowed != is_allowed) {
+ return false;
+ }
+ const std::string consent = is_allowed ? "allowed" : "disallowed";
+ LOG4CXX_INFO(logger_,
+ "DeviceGetDeviceGroupsFromPolicies is already " << consent
+ << ".");
+ return true;
+}
+
+void CacheManager::SetDeviceConsent(const std::string& device_id,
+ const bool is_allowed) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+ if (HasDeviceSpecifiedConsent(device_id, is_allowed)) {
+ return;
+ }
+ ResetCalculatedPermissionsForDevice(device_id);
+ // Remove unpaired mark, if device re-paired and re-consented again
+ if (is_allowed) {
+ SetUnpairedDevice(device_id, false);
+ }
+
+ StringArray list_of_permissions;
+ if (!GetPermissionsList(list_of_permissions) || list_of_permissions.empty()) {
+ LOG4CXX_WARN(logger_, "List of permissions can't be received or empty");
+ return;
+ }
+
+ StringArray consented_groups;
+ StringArray disallowed_groups;
+
+ // Supposed only one group for device date consent
+ if (is_allowed) {
+ consented_groups = list_of_permissions;
+ } else {
+ disallowed_groups = list_of_permissions;
+ }
+
+ if (!SetUserPermissionsForDevice(
+ device_id, consented_groups, disallowed_groups)) {
+ LOG4CXX_WARN(logger_, "Can't set user consent for device");
+ return;
+ }
+ SaveDeviceConsentToCache(device_id, is_allowed);
+}
+
+DeviceConsent CacheManager::GetDeviceConsent(
+ const std::string& device_id) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(kDeviceHasNoConsent);
+ if (IsDeviceConsentCached(device_id)) {
+ return GetCachedDeviceConsent(device_id);
+ }
+ StringArray list_of_permissions;
+ if (!GetPermissionsList(list_of_permissions)) {
+ return kDeviceDisallowed;
+ }
+
+ // Check device permission groups for user consent in device_data
+ // section
+ if (list_of_permissions.empty()) {
+ return kDeviceAllowed;
+ }
+ StringArray consented_groups;
+ StringArray disallowed_groups;
+ if (!GetUserPermissionsForDevice(
+ device_id, consented_groups, disallowed_groups)) {
+ return kDeviceDisallowed;
+ }
+
+ if (consented_groups.empty() && disallowed_groups.empty()) {
+ return kDeviceHasNoConsent;
+ }
+
+ std::sort(list_of_permissions.begin(), list_of_permissions.end());
+ std::sort(consented_groups.begin(), consented_groups.end());
+
+ StringArray to_be_consented_by_user;
+ std::set_difference(list_of_permissions.begin(),
+ list_of_permissions.end(),
+ consented_groups.begin(),
+ consented_groups.end(),
+ std::back_inserter(to_be_consented_by_user));
+ if (to_be_consented_by_user.empty()) {
+ return kDeviceAllowed;
+ }
+ return kDeviceDisallowed;
+}
+
+bool CacheManager::AddDevice(const std::string& device_id,
+ const std::string& connection_type) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ CACHE_MANAGER_CHECK(false);
+ policy_table::DeviceParams& params =
+ (*(pt_->policy_table.device_data))[device_id];
+ *params.connection_type = connection_type;
+
+ // We have to set preloaded flag as false in policy table on adding new
+ // information (SDLAQ-CRS-2365). It can happens only after device addition.
+ *pt_->policy_table.module_config.preloaded_pt = false;
+
+ Backup();
+ return true;
+}
+
+bool CacheManager::SetDeviceData(const std::string& device_id,
+ const std::string& hardware,
+ const std::string& firmware,
+ const std::string& os,
+ const std::string& os_version,
+ const std::string& carrier,
+ const uint32_t number_of_ports,
+ const std::string& connection_type) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ CACHE_MANAGER_CHECK(false);
+
+ if (pt_->policy_table.device_data->end() ==
+ pt_->policy_table.device_data->find(device_id)) {
+ LOG4CXX_ERROR(logger_, "Unable to find mobile device: " << device_id);
+ return false;
+ }
+
+ policy_table::DeviceParams& params =
+ (*(pt_->policy_table.device_data))[device_id];
+ *params.hardware = hardware;
+ *params.firmware_rev = firmware;
+ *params.os = os;
+ *params.os_version = os_version;
+ *params.carrier = carrier;
+ *params.max_number_rfcom_ports = number_of_ports;
+ *params.connection_type = connection_type;
+
+ Backup();
+ return true;
+}
+
+bool CacheManager::SetUserPermissionsForDevice(
+ const std::string& device_id,
+ const StringArray& consented_groups,
+ const StringArray& disallowed_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ CACHE_MANAGER_CHECK(false);
+ policy_table::DeviceParams& params =
+ (*pt_->policy_table.device_data)[device_id];
+ policy_table::UserConsentRecords& ucr = *(params.user_consent_records);
+
+ StringArray::const_iterator consent_iter_end = consented_groups.end();
+ StringArray::const_iterator consent_iter = consented_groups.begin();
+ StringArray::const_iterator un_consent_iter_end = disallowed_groups.end();
+ StringArray::const_iterator un_consent_iter = disallowed_groups.begin();
+
+ for (; consent_iter != consent_iter_end; ++consent_iter) {
+ (*ucr[kDeviceId].consent_groups)[*consent_iter] = true;
+ }
+
+ for (; un_consent_iter != un_consent_iter_end; ++un_consent_iter) {
+ (*ucr[kDeviceId].consent_groups)[*un_consent_iter] = false;
+ }
+
+ policy_table::UserConsentRecords::iterator ucr_iter = ucr.begin();
+ policy_table::UserConsentRecords::iterator ucr_iter_end = ucr.end();
+ // TODO(AGaliuzov): Get this info from external data
+ for (; ucr_iter != ucr_iter_end; ++ucr_iter) {
+ *ucr_iter->second.input = policy_table::Input::I_GUI;
+ *ucr_iter->second.time_stamp = currentDateTime();
+ }
+ Backup();
+ return true;
+}
+
+bool CacheManager::ReactOnUserDevConsentForApp(const std::string& app_id,
+ bool is_device_allowed) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ bool result = true;
+ if (is_device_allowed) {
+ // If app has pre_DataConsented groups it should be 'promoted' to default
+ if (IsPredataPolicy(app_id)) {
+ result = SetDefaultPolicy(app_id);
+ }
+ } else {
+ SetIsPredata(app_id);
+ }
+ Backup();
+ return result;
+}
+
+void CacheManager::GetGroupNameByHashID(const int32_t group_id,
+ std::string& group_name) {
+ CACHE_MANAGER_CHECK_VOID();
+ policy_table::FunctionalGroupings::const_iterator fg_iter =
+ pt_->policy_table.functional_groupings.begin();
+ policy_table::FunctionalGroupings::const_iterator fg_iter_end =
+ pt_->policy_table.functional_groupings.end();
+
+ for (; fg_iter != fg_iter_end; ++fg_iter) {
+ const int32_t id = utils::Djb2HashFromString((*fg_iter).first);
+ if (group_id == id) {
+ group_name = (*fg_iter).first;
+ }
+ }
+}
+
+bool CacheManager::SetUserPermissionsForApp(
+ const PermissionConsent& permissions, bool* out_app_permissions_changed) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ CACHE_MANAGER_CHECK(false);
+ std::vector<FunctionalGroupPermission>::const_iterator iter =
+ permissions.group_permissions.begin();
+ std::vector<FunctionalGroupPermission>::const_iterator iter_end =
+ permissions.group_permissions.end();
+ *out_app_permissions_changed = false;
+
+ std::string group_name;
+ for (; iter != iter_end; ++iter) {
+ if (policy::kGroupUndefined != (*iter).state) {
+ policy_table::DeviceParams& params =
+ (*pt_->policy_table.device_data)[permissions.device_id];
+ rpc::policy_table_interface_base::ConsentRecords& ucr =
+ (*params.user_consent_records)[permissions.policy_app_id];
+
+ GetGroupNameByHashID((*iter).group_id, group_name);
+
+ policy_table::ConsentGroups::const_iterator it_group =
+ ucr.consent_groups->find(group_name);
+
+ const bool is_allowed = (*iter).state == policy::kGroupAllowed;
+ if (ucr.consent_groups->end() == it_group ||
+ it_group->second != is_allowed) {
+ *out_app_permissions_changed = true;
+
+ const TimevalStruct tm = date_time::DateTime::getCurrentTime();
+ int64_t current_time_msec = date_time::DateTime::getmSecs(tm);
+ ucr.consent_last_updated = current_time_msec;
+ LOG4CXX_DEBUG(logger_, "Updating consents time " << current_time_msec);
+ }
+
+ (*ucr.consent_groups)[group_name] = is_allowed;
+ *ucr.input = policy_table::Input::I_GUI;
+ *ucr.time_stamp = currentDateTime();
+ }
+ }
+ Backup();
+ return true;
+}
+
+bool CacheManager::UpdateRequired() const {
+ return update_required;
+}
+
+void CacheManager::SaveUpdateRequired(bool status) {
+ update_required = status;
+ Backup();
+}
+
+bool CacheManager::IsApplicationRevoked(const std::string& app_id) const {
+ CACHE_MANAGER_CHECK(false);
+ if (!IsApplicationRepresented(app_id)) {
+ return false;
+ }
+ const bool is_revoked =
+ pt_->policy_table.app_policies_section.apps[app_id].is_null();
+ return is_revoked;
+}
+
+void CacheManager::CheckPermissions(const PTString& app_id,
+ const PTString& hmi_level,
+ const PTString& rpc,
+ CheckPermissionResult& result) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+
+ if (!IsApplicationRepresented(app_id)) {
+ LOG4CXX_ERROR(
+ logger_, "Application id " << app_id << " was not found in policy DB.");
+ return;
+ }
+
+ policy_table::Strings::const_iterator app_groups_iter =
+ pt_->policy_table.app_policies_section.apps[app_id].groups.begin();
+
+ policy_table::Strings::const_iterator app_groups_iter_end =
+ pt_->policy_table.app_policies_section.apps[app_id].groups.end();
+
+ policy_table::FunctionalGroupings::const_iterator concrete_group;
+
+ for (; app_groups_iter != app_groups_iter_end; ++app_groups_iter) {
+ concrete_group =
+ pt_->policy_table.functional_groupings.find(*app_groups_iter);
+ if (pt_->policy_table.functional_groupings.end() != concrete_group) {
+ const policy_table::Rpcs& rpcs = concrete_group->second;
+
+ policy_table::Rpc::const_iterator rpc_iter = rpcs.rpcs.find(rpc);
+ if (rpcs.rpcs.end() != rpc_iter) {
+ policy_table::RpcParameters rpc_param = rpc_iter->second;
+
+ policy_table::HmiLevel hmi_level_e;
+ policy_table::EnumFromJsonString(hmi_level, &hmi_level_e);
+
+ policy_table::HmiLevels::const_iterator hmi_iter =
+ std::find(rpc_param.hmi_levels.begin(),
+ rpc_param.hmi_levels.end(),
+ hmi_level_e);
+
+ if (rpc_param.hmi_levels.end() != hmi_iter) {
+ result.hmi_level_permitted = PermitResult::kRpcAllowed;
+
+ policy_table::Parameters::const_iterator params_iter =
+ rpc_param.parameters->begin();
+ policy_table::Parameters::const_iterator params_iter_end =
+ rpc_param.parameters->end();
+
+ for (; params_iter != params_iter_end; ++params_iter) {
+ result.list_of_allowed_params.insert(
+ policy_table::EnumToJsonString(*params_iter));
+ }
+ }
+ }
+ }
+ }
+}
+
+bool CacheManager::IsPTPreloaded() {
+ CACHE_MANAGER_CHECK(false);
+ return *pt_->policy_table.module_config.preloaded_pt;
+}
+
+int CacheManager::IgnitionCyclesBeforeExchange() {
+ CACHE_MANAGER_CHECK(0);
+ const uint8_t limit = std::max(
+ static_cast<int>(
+ pt_->policy_table.module_config.exchange_after_x_ignition_cycles),
+ 0);
+ LOG4CXX_DEBUG(
+ logger_,
+ "IgnitionCyclesBeforeExchange limit:" << static_cast<int>(limit));
+ uint8_t current = 0;
+
+ const int last_exch = static_cast<int>(
+ *pt_->policy_table.module_meta->ignition_cycles_since_last_exchange);
+ current = std::max(last_exch, 0);
+ LOG4CXX_DEBUG(
+ logger_,
+ "IgnitionCyclesBeforeExchange current:" << static_cast<int>(current));
+
+ return std::max(limit - current, 0);
+}
+
+int CacheManager::KilometersBeforeExchange(int current) {
+ CACHE_MANAGER_CHECK(0);
+ const int limit =
+ std::max(static_cast<int>(
+ pt_->policy_table.module_config.exchange_after_x_kilometers),
+ 0);
+ LOG4CXX_DEBUG(logger_, "KilometersBeforeExchange limit:" << limit);
+ int last = 0;
+
+ const int odo_val = static_cast<int>(
+ *pt_->policy_table.module_meta->pt_exchanged_at_odometer_x);
+ last = std::max(odo_val, 0);
+ LOG4CXX_DEBUG(logger_, "KilometersBeforeExchange last:" << last);
+
+ const int actual = std::max((current - last), 0);
+ LOG4CXX_DEBUG(logger_, "KilometersBeforeExchange actual:" << actual);
+ return std::max(limit - actual, 0);
+}
+
+bool CacheManager::SetCountersPassedForSuccessfulUpdate(
+ policy::Counters counter, int value) {
+ CACHE_MANAGER_CHECK(false);
+ switch (counter) {
+ case KILOMETERS:
+ *pt_->policy_table.module_meta->pt_exchanged_at_odometer_x = value;
+ LOG4CXX_DEBUG(logger_,
+ "SetCountersPassedForSuccessfulUpdate km:" << value);
+ break;
+ case DAYS_AFTER_EPOCH:
+ *pt_->policy_table.module_meta->pt_exchanged_x_days_after_epoch = value;
+ LOG4CXX_DEBUG(
+ logger_,
+ "SetCountersPassedForSuccessfulUpdate days after epoch:" << value);
+ break;
+ default:
+ LOG4CXX_ERROR(logger_,
+ "Unknown counter was requested to set: " << counter);
+ return false;
+ }
+
+ Backup();
+ return true;
+}
+
+int CacheManager::DaysBeforeExchange(uint16_t current) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(0);
+
+ const rpc::Optional<rpc::Integer<uint16_t, 0, 65535> >& days_after_epoch =
+ (pt_->policy_table.module_meta->pt_exchanged_x_days_after_epoch);
+
+ if (!days_after_epoch->is_initialized()) {
+ return -1;
+ }
+
+ const uint8_t limit = pt_->policy_table.module_config.exchange_after_x_days;
+ LOG4CXX_DEBUG(logger_,
+ "Exchange after: " << static_cast<int>(limit) << " days");
+
+ LOG4CXX_DEBUG(logger_, "Epoch since last update: " << *days_after_epoch);
+
+ const uint16_t actual =
+ std::max(static_cast<uint16_t>(current - *days_after_epoch), uint16_t(0));
+ LOG4CXX_DEBUG(logger_, "The days since last update: " << actual);
+
+ return std::max(limit - actual, 0);
+}
+
+void CacheManager::IncrementIgnitionCycles() {
+ CACHE_MANAGER_CHECK_VOID();
+ const int ign_val = static_cast<int>(
+ *pt_->policy_table.module_meta->ignition_cycles_since_last_exchange);
+ (*pt_->policy_table.module_meta->ignition_cycles_since_last_exchange) =
+ ign_val + 1;
+ LOG4CXX_DEBUG(logger_, "IncrementIgnitionCycles ignitions:" << ign_val);
+ Backup();
+}
+
+void CacheManager::ResetIgnitionCycles() {
+ CACHE_MANAGER_CHECK_VOID();
+ (*pt_->policy_table.module_meta->ignition_cycles_since_last_exchange) = 0;
+ Backup();
+}
+
+int CacheManager::TimeoutResponse() {
+ CACHE_MANAGER_CHECK(0);
+ return pt_->policy_table.module_config.timeout_after_x_seconds *
+ date_time::DateTime::MILLISECONDS_IN_SECOND;
+}
+
+bool CacheManager::SecondsBetweenRetries(std::vector<int>& seconds) {
+ CACHE_MANAGER_CHECK(false);
+ rpc::policy_table_interface_base::SecondsBetweenRetries::iterator iter =
+ pt_->policy_table.module_config.seconds_between_retries.begin();
+ rpc::policy_table_interface_base::SecondsBetweenRetries::iterator iter_end =
+ pt_->policy_table.module_config.seconds_between_retries.end();
+
+ const std::size_t size =
+ pt_->policy_table.module_config.seconds_between_retries.size();
+ seconds.reserve(size);
+ for (; iter != iter_end; ++iter) {
+ seconds.push_back(*iter);
+ }
+ return true;
+}
+
+const policy::VehicleInfo CacheManager::GetVehicleInfo() const {
+ CACHE_MANAGER_CHECK(VehicleInfo());
+ policy_table::ModuleConfig& module_config = pt_->policy_table.module_config;
+ VehicleInfo vehicle_info;
+ vehicle_info.vehicle_make = *module_config.vehicle_make;
+ vehicle_info.vehicle_model = *module_config.vehicle_model;
+ vehicle_info.vehicle_year = *module_config.vehicle_year;
+ LOG4CXX_DEBUG(
+ logger_,
+ "Vehicle info (make, model, year):" << vehicle_info.vehicle_make << ","
+ << vehicle_info.vehicle_model << ","
+ << vehicle_info.vehicle_year);
+ return vehicle_info;
+}
+
+std::vector<UserFriendlyMessage> CacheManager::GetUserFriendlyMsg(
+ const std::vector<std::string>& msg_codes,
+ const std::string& language,
+ const std::string& active_hmi_language) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ std::vector<UserFriendlyMessage> result;
+ CACHE_MANAGER_CHECK(result);
+
+ std::vector<std::string>::const_iterator it = msg_codes.begin();
+ std::vector<std::string>::const_iterator it_end = msg_codes.end();
+ for (; it != it_end; ++it) {
+ policy_table::MessageLanguages msg_languages =
+ (*pt_->policy_table.consumer_friendly_messages->messages)[*it];
+
+ // If message has no records with required language, fallback language
+ // should be used instead.
+ policy_table::MessageString message_string =
+ FindLanguage(msg_languages, language);
+
+ if (!message_string.is_valid()) {
+ LOG4CXX_WARN(logger_,
+ "Language "
+ << language
+ << " haven't been found for message code: " << *it);
+ policy_table::MessageString active_hmi_language_message_string =
+ FindLanguage(msg_languages, active_hmi_language);
+ if (!active_hmi_language_message_string.is_valid()) {
+ LOG4CXX_WARN(logger_,
+ "Active hmi language "
+ << active_hmi_language
+ << " haven't been found for message code: " << *it);
+
+ policy_table::MessageString fallback_message_string =
+ FindLanguage(msg_languages, "en-us");
+ if (!fallback_message_string.is_valid()) {
+ LOG4CXX_ERROR(logger_,
+ "No fallback language found for message code: " << *it);
+ continue;
+ }
+ message_string = fallback_message_string;
+ }
+ message_string = active_hmi_language_message_string;
+ }
+
+ UserFriendlyMessage msg;
+ msg.message_code = *it;
+ msg.tts = *message_string.tts;
+ msg.label = *message_string.label;
+ msg.line1 = *message_string.line1;
+ msg.line2 = *message_string.line2;
+ msg.text_body = *message_string.textBody;
+
+ result.push_back(msg);
+ }
+ return result;
+}
+
+void CacheManager::GetUpdateUrls(const uint32_t service_type,
+ EndpointUrls& out_end_points) {
+ std::stringstream service_type_stream;
+ service_type_stream << (service_type <= 9 ? "0x0" : "0x") << service_type;
+
+ const std::string service_type_str = service_type_stream.str();
+ GetUpdateUrls(service_type_str, out_end_points);
+}
+
+void CacheManager::GetUpdateUrls(const std::string& service_type,
+ EndpointUrls& out_end_points) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+
+ LOG4CXX_DEBUG(logger_, "Search service value is: " << service_type);
+
+ policy_table::ServiceEndpoints::const_iterator iter =
+ pt_->policy_table.module_config.endpoints.find(service_type);
+
+ if (pt_->policy_table.module_config.endpoints.end() != iter) {
+ policy_table::URLList::const_iterator url_list_iter =
+ (*iter).second.begin();
+ policy_table::URLList::const_iterator url_list_iter_end =
+ (*iter).second.end();
+ for (; url_list_iter != url_list_iter_end; ++url_list_iter) {
+ EndpointData data;
+ data.app_id = (*url_list_iter).first;
+ std::copy((*url_list_iter).second.begin(),
+ (*url_list_iter).second.end(),
+ std::back_inserter(data.url));
+
+ out_end_points.push_back(data);
+ }
+ }
+}
+
+std::string CacheManager::GetLockScreenIconUrl() const {
+ if (backup_) {
+ return backup_->GetLockScreenIconUrl();
+ }
+ return std::string("");
+}
+
+rpc::policy_table_interface_base::NumberOfNotificationsType
+CacheManager::GetNotificationsNumber(const std::string& priority) {
+ CACHE_MANAGER_CHECK(0);
+ typedef rpc::policy_table_interface_base::NumberOfNotificationsPerMinute NNPM;
+
+ const NNPM& nnpm =
+ pt_->policy_table.module_config.notifications_per_minute_by_priority;
+
+ NNPM::const_iterator priority_iter = nnpm.find(priority);
+
+ const uint32_t result =
+ (nnpm.end() != priority_iter ? (*priority_iter).second : 0);
+ return result;
+}
+
+bool CacheManager::GetPriority(const std::string& policy_app_id,
+ std::string& priority) const {
+ CACHE_MANAGER_CHECK(false);
+ if (kDeviceId == policy_app_id) {
+ priority = EnumToJsonString(
+ pt_->policy_table.app_policies_section.device.priority);
+ return true;
+ }
+
+ const policy_table::ApplicationPolicies& policies =
+ pt_->policy_table.app_policies_section.apps;
+
+ policy_table::ApplicationPolicies::const_iterator policy_iter =
+ policies.find(policy_app_id);
+ const bool app_id_exists = policies.end() != policy_iter;
+ if (app_id_exists) {
+ priority = EnumToJsonString((*policy_iter).second.priority);
+ }
+
+ return app_id_exists;
+}
+
+void CacheManager::CheckSnapshotInitialization() {
+ CACHE_MANAGER_CHECK_VOID();
+ if (!snapshot_) {
+ LOG4CXX_ERROR(logger_, "Snapshot pointer is not initialized");
+ return;
+ }
+
+ *(snapshot_->policy_table.module_config.preloaded_pt) = false;
+
+ // SDL must not send certificate in snapshot
+ snapshot_->policy_table.module_config.certificate =
+ rpc::Optional<rpc::String<0, 65535> >();
+
+ snapshot_->policy_table.consumer_friendly_messages->messages =
+ rpc::Optional<policy_table::Messages>();
+
+ rpc::Optional<policy_table::ModuleMeta>& module_meta =
+ snapshot_->policy_table.module_meta;
+ if (!module_meta->pt_exchanged_at_odometer_x->is_initialized()) {
+ *(module_meta->pt_exchanged_at_odometer_x) = 0;
+ }
+ if (!module_meta->ignition_cycles_since_last_exchange->is_initialized()) {
+ *(module_meta->ignition_cycles_since_last_exchange) = 0;
+ }
+
+ if (!module_meta->pt_exchanged_x_days_after_epoch->is_initialized()) {
+ *(module_meta->pt_exchanged_x_days_after_epoch) = 0;
+ }
+
+ rpc::Optional<policy_table::UsageAndErrorCounts>& usage_and_error_counts =
+ snapshot_->policy_table.usage_and_error_counts;
+ if (!usage_and_error_counts->count_of_iap_buffer_full->is_initialized()) {
+ *(usage_and_error_counts->count_of_iap_buffer_full) = 0;
+ }
+
+ if (!usage_and_error_counts->count_of_sync_reboots->is_initialized()) {
+ *(usage_and_error_counts->count_of_sync_reboots) = 0;
+ }
+
+ if (!usage_and_error_counts->count_sync_out_of_memory->is_initialized()) {
+ *(usage_and_error_counts->count_sync_out_of_memory) = 0;
+ }
+
+ if (usage_and_error_counts->app_level->is_initialized()) {
+ policy_table::AppLevels::iterator it =
+ usage_and_error_counts->app_level->begin();
+ policy_table::AppLevels::const_iterator it_end =
+ usage_and_error_counts->app_level->end();
+ for (; it != it_end; ++it) {
+ if (!(*it).second.minutes_in_hmi_full.is_initialized()) {
+ (*it).second.minutes_in_hmi_full = 0;
+ }
+
+ if (!(*it).second.app_registration_language_gui.is_initialized()) {
+ (*it).second.app_registration_language_gui = "unknown";
+ }
+
+ if (!(*it).second.app_registration_language_vui.is_initialized()) {
+ (*it).second.app_registration_language_vui = "unknown";
+ }
+
+ if (!(*it).second.minutes_in_hmi_limited.is_initialized()) {
+ (*it).second.minutes_in_hmi_limited = 0;
+ }
+
+ if (!(*it).second.minutes_in_hmi_background.is_initialized()) {
+ (*it).second.minutes_in_hmi_background = 0;
+ }
+
+ if (!(*it).second.minutes_in_hmi_none.is_initialized()) {
+ (*it).second.minutes_in_hmi_none = 0;
+ }
+
+ if (!(*it).second.count_of_user_selections.is_initialized()) {
+ (*it).second.count_of_user_selections = 0;
+ }
+
+ if (!(*it)
+ .second.count_of_rejections_sync_out_of_memory
+ .is_initialized()) {
+ (*it).second.count_of_rejections_sync_out_of_memory = 0;
+ }
+
+ if (!(*it)
+ .second.count_of_rejections_nickname_mismatch.is_initialized()) {
+ (*it).second.count_of_rejections_nickname_mismatch = 0;
+ }
+
+ if (!(*it).second.count_of_rejections_duplicate_name.is_initialized()) {
+ (*it).second.count_of_rejections_duplicate_name = 0;
+ }
+
+ if (!(*it).second.count_of_rejected_rpc_calls.is_initialized()) {
+ (*it).second.count_of_rejected_rpc_calls = 0;
+ }
+
+ if (!(*it).second.count_of_rpcs_sent_in_hmi_none.is_initialized()) {
+ (*it).second.count_of_rpcs_sent_in_hmi_none = 0;
+ }
+
+ if (!(*it).second.count_of_removals_for_bad_behavior.is_initialized()) {
+ (*it).second.count_of_removals_for_bad_behavior = 0;
+ }
+
+ if (!(*it).second.count_of_tls_errors.is_initialized()) {
+ (*it).second.count_of_tls_errors = 0;
+ }
+
+ if (!(*it).second.count_of_run_attempts_while_revoked.is_initialized()) {
+ (*it).second.count_of_run_attempts_while_revoked = 0;
+ }
+ }
+ }
+}
+
+void CacheManager::PersistData() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (backup_.valid()) {
+ if (pt_.valid()) {
+ cache_lock_.Acquire();
+ policy_table::Table copy_pt(*pt_);
+ cache_lock_.Release();
+
+ backup_->Save(copy_pt);
+ backup_->SaveUpdateRequired(update_required);
+
+ policy_table::ApplicationPolicies::const_iterator app_policy_iter =
+ copy_pt.policy_table.app_policies_section.apps.begin();
+ policy_table::ApplicationPolicies::const_iterator app_policy_iter_end =
+ copy_pt.policy_table.app_policies_section.apps.end();
+
+ bool is_revoked = false;
+
+ for (; app_policy_iter != app_policy_iter_end; ++app_policy_iter) {
+ const std::string app_id = (*app_policy_iter).first;
+
+ if (IsApplicationRepresented(app_id)) {
+ is_revoked =
+ copy_pt.policy_table.app_policies_section.apps[app_id].is_null();
+ }
+
+ const bool kIsDefaultPolicy =
+ IsApplicationRepresented(app_id) &&
+ policy::kDefaultId ==
+ copy_pt.policy_table.app_policies_section.apps[app_id]
+ .get_string();
+
+ // TODO(AOleynik): Remove this field from DB
+ const bool kIsPredataPolicy =
+ IsApplicationRepresented(app_id) &&
+ policy::kPreDataConsentId ==
+ copy_pt.policy_table.app_policies_section.apps[app_id]
+ .get_string();
+
+ backup_->SaveApplicationCustomData(
+ app_id, is_revoked, kIsDefaultPolicy, kIsPredataPolicy);
+ is_revoked = false;
+ }
+
+ // In case of extended policy the meta info should be backuped as well.
+ if (ex_backup_.valid()) {
+ ex_backup_->SetMetaInfo(
+ *(*copy_pt.policy_table.module_meta).ccpu_version,
+ *(*copy_pt.policy_table.module_meta).wers_country_code,
+ *(*copy_pt.policy_table.module_meta).language);
+ ex_backup_->SetVINValue(*(*copy_pt.policy_table.module_meta).vin);
+
+ // Save unpaired flag for devices
+ policy_table::DeviceData::const_iterator it_device =
+ copy_pt.policy_table.device_data->begin();
+ policy_table::DeviceData::const_iterator it_end_device =
+ copy_pt.policy_table.device_data->end();
+
+#ifdef ENABLE_LOG
+ policy_table::DeviceData& device_data =
+ *copy_pt.policy_table.device_data;
+ LOG4CXX_DEBUG(logger_, "Device_data size is: " << device_data.size());
+#endif // ENABLE_LOG
+ for (; it_device != it_end_device; ++it_device) {
+ if (is_unpaired_.end() != is_unpaired_.find(it_device->first)) {
+ ex_backup_->SetUnpairedDevice(it_device->first, true);
+ } else {
+ ex_backup_->SetUnpairedDevice(it_device->first, false);
+ }
+ }
+ LOG4CXX_DEBUG(logger_, "Device_data size is: " << device_data.size());
+ }
+ backup_->WriteDb();
+ }
+ }
+}
+
+void CacheManager::ResetCalculatedPermissions() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(calculated_permissions_lock_);
+ calculated_permissions_.clear();
+}
+
+void CacheManager::ResetCalculatedPermissionsForDevice(
+ const std::string& device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(calculated_permissions_lock_);
+ calculated_permissions_.erase(device_id);
+}
+
+void CacheManager::AddCalculatedPermissions(const std::string& device_id,
+ const std::string& policy_app_id,
+ const Permissions& permissions) {
+ LOG4CXX_DEBUG(logger_,
+ "AddCalculatedPermissions for device: "
+ << device_id << " and app: " << policy_app_id);
+ sync_primitives::AutoLock lock(calculated_permissions_lock_);
+ calculated_permissions_[device_id][policy_app_id] = permissions;
+}
+
+bool CacheManager::IsPermissionsCalculated(const std::string& device_id,
+ const std::string& policy_app_id,
+ Permissions& permission) {
+ LOG4CXX_DEBUG(logger_,
+ "IsPermissionsCalculated for device: "
+ << device_id << " and app: " << policy_app_id);
+ sync_primitives::AutoLock lock(calculated_permissions_lock_);
+ CalculatedPermissions::const_iterator it =
+ calculated_permissions_.find(device_id);
+
+ if (calculated_permissions_.end() == it) {
+ return false;
+ }
+
+ AppCalculatedPermissions::const_iterator app_it =
+ (*it).second.find(policy_app_id);
+ if ((*it).second.end() == app_it) {
+ return false;
+ } else {
+ permission = (*app_it).second;
+ return true;
+ }
+ return false;
+}
+
+utils::SharedPtr<policy_table::Table> CacheManager::GenerateSnapshot() {
+ CACHE_MANAGER_CHECK(snapshot_);
+ sync_primitives::AutoLock lock(cache_lock_);
+ snapshot_ = new policy_table::Table();
+ snapshot_->policy_table = pt_->policy_table;
+
+ snapshot_->SetPolicyTableType(policy_table::PT_SNAPSHOT);
+
+ CheckSnapshotInitialization();
+ return snapshot_;
+}
+
+bool CacheManager::GetInitialAppData(const std::string& app_id,
+ StringArray& nicknames,
+ StringArray& app_hmi_types) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ policy_table::ApplicationPolicies::const_iterator policy_iter =
+ pt_->policy_table.app_policies_section.apps.find(app_id);
+
+ if (pt_->policy_table.app_policies_section.apps.end() != policy_iter) {
+ const policy_table::ApplicationParams& app_params = (*policy_iter).second;
+
+ std::copy(app_params.nicknames->begin(),
+ app_params.nicknames->end(),
+ std::back_inserter(nicknames));
+
+ std::transform(app_params.AppHMIType->begin(),
+ app_params.AppHMIType->end(),
+ std::back_inserter(app_hmi_types),
+ AppHMITypeToString());
+ }
+ return true;
+}
+
+bool CacheManager::GetFunctionalGroupings(
+ policy_table::FunctionalGroupings& groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ const policy_table::FunctionalGroupings& f_groupings =
+ pt_->policy_table.functional_groupings;
+
+ groups.insert(f_groupings.begin(), f_groupings.end());
+ return true;
+}
+
+int CacheManager::CountUnconsentedGroups(const std::string& policy_app_id,
+ const std::string& device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ LOG4CXX_DEBUG(logger_, "Application id: " << policy_app_id);
+ int result = 0;
+ if (kDeviceId != policy_app_id && !IsApplicationRepresented(policy_app_id)) {
+ return 0;
+ } else if (IsDefaultPolicy(policy_app_id)) {
+ return 0;
+ } else if (IsPredataPolicy(policy_app_id)) {
+ return 0;
+ }
+
+ policy_table::FunctionalGroupings::const_iterator groups_iter_end =
+ pt_->policy_table.functional_groupings.end();
+
+ policy_table::ApplicationPoliciesSection& app_policies_section =
+ pt_->policy_table.app_policies_section;
+
+ policy_table::Strings::iterator app_groups;
+ policy_table::Strings::iterator app_groups_end = app_groups;
+ policy_table::Strings::iterator app_pre_groups;
+ policy_table::Strings::iterator app_pre_groups_end = app_pre_groups;
+
+ if (kDeviceId == policy_app_id) {
+ app_groups = app_policies_section.device.groups.begin();
+
+ app_groups_end = app_policies_section.device.groups.end();
+
+ app_pre_groups = app_policies_section.device.preconsented_groups->begin();
+
+ app_pre_groups_end = app_policies_section.device.preconsented_groups->end();
+ } else {
+ app_groups = app_policies_section.apps[policy_app_id].groups.begin();
+
+ app_groups_end = app_policies_section.apps[policy_app_id].groups.end();
+
+ app_pre_groups =
+ app_policies_section.apps[policy_app_id].preconsented_groups->begin();
+
+ app_pre_groups_end =
+ app_policies_section.apps[policy_app_id].preconsented_groups->end();
+ }
+
+ policy_table::Strings groups_to_be_consented;
+ policy_table::FunctionalGroupings::iterator current_groups_iter;
+ for (; app_groups != app_groups_end; ++app_groups) {
+ current_groups_iter =
+ pt_->policy_table.functional_groupings.find(*app_groups);
+
+ if (groups_iter_end != current_groups_iter) {
+ if (current_groups_iter->second.user_consent_prompt.is_initialized()) {
+ // Check if groups which requires user consent prompt
+ // not included in "preconsented_groups" section
+ if (app_pre_groups_end ==
+ std::find(app_pre_groups, app_pre_groups_end, *app_groups)) {
+ groups_to_be_consented.push_back(*app_groups);
+ }
+ }
+ }
+ }
+
+ if (groups_to_be_consented.empty()) {
+ return 0;
+ }
+
+ // If there is no device record, all groups with consents should be consented
+ if (pt_->policy_table.device_data->end() ==
+ pt_->policy_table.device_data->find(device_id)) {
+ return groups_to_be_consented.size();
+ }
+
+ policy_table::DeviceParams& params =
+ (*pt_->policy_table.device_data)[device_id];
+
+ policy_table::UserConsentRecords& ucr = *(params.user_consent_records);
+
+ // If there is no application record, all groups with consents should be
+ // consented
+ if (ucr.end() == ucr.find(policy_app_id)) {
+ return groups_to_be_consented.size();
+ }
+
+ policy_table::ConsentRecords& cgr = ucr[policy_app_id];
+
+ policy_table::Strings::const_iterator to_consent_it =
+ groups_to_be_consented.begin();
+
+ for (; to_consent_it != groups_to_be_consented.end(); ++to_consent_it) {
+ policy_table::ConsentGroups::const_iterator already_consented_iter =
+ cgr.consent_groups->find(*to_consent_it);
+ if (already_consented_iter == cgr.consent_groups->end()) {
+ ++result;
+ }
+ }
+
+ return result;
+}
+
+bool CacheManager::SetMetaInfo(const std::string& ccpu_version,
+ const std::string& wers_country_code,
+ const std::string& language) {
+ CACHE_MANAGER_CHECK(false);
+ *pt_->policy_table.module_meta->ccpu_version = ccpu_version;
+ *pt_->policy_table.module_meta->wers_country_code = wers_country_code;
+ *pt_->policy_table.module_meta->language = language;
+
+ // We have to set preloaded flag as false in policy table on any response
+ // of GetSystemInfo (SDLAQ-CRS-2365)
+ *pt_->policy_table.module_config.preloaded_pt = false;
+
+ Backup();
+ return true;
+}
+
+bool CacheManager::IsMetaInfoPresent() const {
+ CACHE_MANAGER_CHECK(false);
+ bool result = true;
+ result = NULL != pt_->policy_table.module_meta->ccpu_version &&
+ NULL != pt_->policy_table.module_meta->wers_country_code &&
+ NULL != pt_->policy_table.module_meta->language;
+ return result;
+}
+
+bool CacheManager::SetSystemLanguage(const std::string& language) {
+ CACHE_MANAGER_CHECK(false);
+ *pt_->policy_table.module_meta->language = language;
+ Backup();
+ return true;
+}
+
+bool CacheManager::GetFunctionalGroupNames(FunctionalGroupNames& names) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ rpc::policy_table_interface_base::FunctionalGroupings::iterator iter =
+ pt_->policy_table.functional_groupings.begin();
+ rpc::policy_table_interface_base::FunctionalGroupings::iterator iter_end =
+ pt_->policy_table.functional_groupings.end();
+
+ for (; iter != iter_end; ++iter) {
+ const int32_t id = utils::Djb2HashFromString((*iter).first);
+ std::pair<std::string, std::string> value =
+ std::make_pair(*(*iter).second.user_consent_prompt, (*iter).first);
+
+ names.insert(
+ std::pair<uint32_t, std::pair<std::string, std::string> >(id, value));
+ }
+ return true;
+}
+
+bool CacheManager::CleanupUnpairedDevices() {
+ CACHE_MANAGER_CHECK(false);
+ sync_primitives::AutoLock lock(cache_lock_);
+ sync_primitives::AutoLock lock_unpaired(unpaired_lock_);
+ UnpairedDevices::iterator iter = is_unpaired_.begin();
+ UnpairedDevices::const_iterator iter_end = is_unpaired_.end();
+ LOG4CXX_DEBUG(logger_, "Is_unpaired size is: " << is_unpaired_.size());
+ for (; iter != iter_end; ++iter) {
+ // Delete device
+ if (!pt_->policy_table.device_data.is_initialized()) {
+ LOG4CXX_ERROR(logger_, "Device_data section is not initialized.");
+ return false;
+ }
+ policy_table::DeviceData& device_data = *pt_->policy_table.device_data;
+ policy_table::DeviceData::iterator it_device = device_data.find(*iter);
+ if (device_data.end() == it_device) {
+ LOG4CXX_INFO(logger_,
+ "No device id "
+ << *iter << " had been found in device_data section.");
+ return false;
+ }
+
+ LOG4CXX_DEBUG(logger_, "Device_data size is: " << device_data.size());
+ device_data.erase(it_device);
+ LOG4CXX_INFO(logger_,
+ "Device id " << *iter
+ << " had been deleted from device_data section.");
+ LOG4CXX_DEBUG(logger_, "Device_data size is: " << device_data.size());
+ }
+ is_unpaired_.clear();
+ Backup();
+ return true;
+}
+
+void CacheManager::Increment(usage_statistics::GlobalCounterId type) {
+ CACHE_MANAGER_CHECK_VOID();
+ sync_primitives::AutoLock lock(cache_lock_);
+ switch (type) {
+ case usage_statistics::IAP_BUFFER_FULL:
+ ++(*pt_->policy_table.usage_and_error_counts->count_of_iap_buffer_full);
+ break;
+ case usage_statistics::SYNC_OUT_OF_MEMORY:
+ ++(*pt_->policy_table.usage_and_error_counts->count_sync_out_of_memory);
+ break;
+ case usage_statistics::SYNC_REBOOTS:
+ ++(*pt_->policy_table.usage_and_error_counts->count_of_sync_reboots);
+ break;
+ default:
+ LOG4CXX_WARN(logger_, "Type global counter is unknown");
+ return;
+ }
+ Backup();
+}
+
+void CacheManager::Increment(const std::string& app_id,
+ usage_statistics::AppCounterId type) {
+ CACHE_MANAGER_CHECK_VOID();
+ sync_primitives::AutoLock lock(cache_lock_);
+ switch (type) {
+ case usage_statistics::USER_SELECTIONS:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_user_selections;
+ break;
+ case usage_statistics::REJECTIONS_SYNC_OUT_OF_MEMORY:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_rejections_sync_out_of_memory;
+ break;
+ case usage_statistics::REJECTIONS_NICKNAME_MISMATCH:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_rejections_nickname_mismatch;
+ break;
+ case usage_statistics::REJECTIONS_DUPLICATE_NAME:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_rejections_duplicate_name;
+ break;
+ case usage_statistics::REJECTED_RPC_CALLS:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_rejected_rpc_calls;
+ break;
+ case usage_statistics::RPCS_IN_HMI_NONE:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_rpcs_sent_in_hmi_none;
+ break;
+ case usage_statistics::REMOVALS_MISBEHAVED:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_removals_for_bad_behavior;
+ break;
+ case usage_statistics::RUN_ATTEMPTS_WHILE_REVOKED:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_run_attempts_while_revoked;
+ break;
+ case usage_statistics::COUNT_OF_TLS_ERRORS:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_tls_errors;
+ break;
+ default:
+ LOG4CXX_WARN(logger_, "Type app counter is unknown");
+ return;
+ }
+ Backup();
+}
+
+void CacheManager::Set(const std::string& app_id,
+ usage_statistics::AppInfoId type,
+ const std::string& value) {
+ CACHE_MANAGER_CHECK_VOID();
+ sync_primitives::AutoLock lock(cache_lock_);
+ switch (type) {
+ case usage_statistics::LANGUAGE_GUI:
+ (*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .app_registration_language_gui = value;
+ break;
+ case usage_statistics::LANGUAGE_VUI:
+ (*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .app_registration_language_vui = value;
+ break;
+ default:
+ LOG4CXX_WARN(logger_, "Type app info is unknown");
+ return;
+ }
+ Backup();
+}
+
+void CacheManager::Add(const std::string& app_id,
+ usage_statistics::AppStopwatchId type,
+ int seconds) {
+ CACHE_MANAGER_CHECK_VOID();
+ sync_primitives::AutoLock lock(cache_lock_);
+ const int minutes = ConvertSecondsToMinute(seconds);
+ switch (type) {
+ case usage_statistics::SECONDS_HMI_FULL:
+ (*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .minutes_in_hmi_full += minutes;
+ break;
+ case usage_statistics::SECONDS_HMI_LIMITED:
+ (*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .minutes_in_hmi_limited += minutes;
+ break;
+ case usage_statistics::SECONDS_HMI_BACKGROUND:
+ (*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .minutes_in_hmi_background += minutes;
+ break;
+ case usage_statistics::SECONDS_HMI_NONE:
+ (*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .minutes_in_hmi_none += minutes;
+ break;
+ default:
+ LOG4CXX_WARN(logger_, "Type app stopwatch is unknown");
+ return;
+ }
+ Backup();
+}
+
+long CacheManager::ConvertSecondsToMinute(int seconds) {
+ const float seconds_in_minute = 60.0;
+ return std::round(seconds / seconds_in_minute);
+}
+
+bool CacheManager::SetDefaultPolicy(const std::string& app_id) {
+ CACHE_MANAGER_CHECK(false);
+ sync_primitives::AutoLock lock(cache_lock_);
+ auto& apps = pt_->policy_table.app_policies_section.apps;
+
+ DCHECK_OR_RETURN(IsApplicationRepresented(kDefaultId), false);
+
+ apps[app_id] = apps[kDefaultId];
+ apps[app_id].set_to_string(kDefaultId);
+ Backup();
+ return true;
+}
+
+bool CacheManager::IsDefaultPolicy(const std::string& app_id) const {
+ CACHE_MANAGER_CHECK(false);
+ const bool result =
+ IsApplicationRepresented(app_id) &&
+ policy::kDefaultId ==
+ pt_->policy_table.app_policies_section.apps[app_id].get_string();
+
+ return result;
+}
+
+bool CacheManager::SetIsDefault(const std::string& app_id) {
+ CACHE_MANAGER_CHECK(false);
+
+ if (IsApplicationRepresented(app_id)) {
+ pt_->policy_table.app_policies_section.apps[app_id].set_to_string(
+ kDefaultId);
+ }
+ return true;
+}
+
+bool policy::CacheManager::SetIsPredata(const std::string& app_id) {
+ CACHE_MANAGER_CHECK(false);
+ sync_primitives::AutoLock lock(cache_lock_);
+ if (IsApplicationRepresented(app_id)) {
+ pt_->policy_table.app_policies_section.apps[app_id].set_to_string(
+ kPreDataConsentId);
+ }
+
+ return true;
+}
+
+bool CacheManager::SetPredataPolicy(const std::string& app_id) {
+ CACHE_MANAGER_CHECK(false);
+ sync_primitives::AutoLock lock(cache_lock_);
+ policy_table::ApplicationPolicies::const_iterator iter =
+ pt_->policy_table.app_policies_section.apps.find(kPreDataConsentId);
+
+ if (pt_->policy_table.app_policies_section.apps.end() == iter) {
+ LOG4CXX_ERROR(logger_,
+ "Could not set " << kPreDataConsentId
+ << " permissions for app " << app_id);
+ return false;
+ }
+
+ pt_->policy_table.app_policies_section.apps[app_id] =
+ pt_->policy_table.app_policies_section.apps[kPreDataConsentId];
+
+ pt_->policy_table.app_policies_section.apps[app_id].set_to_string(
+ kPreDataConsentId);
+
+ Backup();
+ return true;
+}
+
+bool CacheManager::IsPredataPolicy(const std::string& app_id) const {
+ if (!IsApplicationRepresented(app_id)) {
+ return false;
+ }
+ return kPreDataConsentId ==
+ pt_->policy_table.app_policies_section.apps[app_id].get_string();
+}
+
+bool CacheManager::SetUnpairedDevice(const std::string& device_id,
+ bool unpaired) {
+ const bool result = pt_->policy_table.device_data->end() !=
+ pt_->policy_table.device_data->find(device_id);
+ if (!result) {
+ LOG4CXX_DEBUG(logger_,
+ "Couldn't set unpaired flag for device id "
+ << device_id << " , since it wasn't found.");
+ return false;
+ }
+
+ sync_primitives::AutoLock lock(unpaired_lock_);
+ if (unpaired) {
+ is_unpaired_.insert(device_id);
+ LOG4CXX_DEBUG(logger_, "Unpaired flag was set for device id " << device_id);
+ } else {
+ is_unpaired_.erase(device_id);
+ LOG4CXX_DEBUG(logger_,
+ "Unpaired flag was removed for device id " << device_id);
+ }
+ return result;
+}
+
+bool CacheManager::SetVINValue(const std::string& value) {
+ CACHE_MANAGER_CHECK(false);
+ cache_lock_.Acquire();
+ *pt_->policy_table.module_meta->vin = value;
+ cache_lock_.Release();
+ Backup();
+ return true;
+}
+
+bool CacheManager::IsApplicationRepresented(const std::string& app_id) const {
+ CACHE_MANAGER_CHECK(false);
+ policy_table::ApplicationPolicies::const_iterator iter =
+ pt_->policy_table.app_policies_section.apps.find(app_id);
+ return pt_->policy_table.app_policies_section.apps.end() != iter;
+}
+
+bool CacheManager::Init(const std::string& file_name,
+ const PolicySettings* settings) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ settings_ = settings;
+ InitResult init_result = backup_->Init(settings);
+ ex_backup_ = utils::SharedPtr<PTRepresentation>::dynamic_pointer_cast<
+ PTExtRepresentation>(backup_);
+
+ bool result = true;
+ switch (init_result) {
+ case InitResult::EXISTS: {
+ LOG4CXX_INFO(logger_, "Policy Table exists, was loaded correctly.");
+ result = LoadFromBackup();
+ if (result) {
+ if (!backup_->IsDBVersionActual()) {
+ if (!backup_->RefreshDB()) {
+ return false;
+ }
+ backup_->UpdateDBVersion();
+ Backup();
+ }
+ if (!MergePreloadPT(file_name)) {
+ result = false;
+ }
+ }
+ } break;
+ case InitResult::SUCCESS: {
+ LOG4CXX_INFO(logger_, "Policy Table was inited successfully");
+ result = LoadFromFile(file_name, *pt_);
+ utils::SharedPtr<policy_table::Table> snapshot = GenerateSnapshot();
+
+ result &= snapshot->is_valid();
+ LOG4CXX_DEBUG(logger_,
+ "Check if snapshot valid: " << std::boolalpha << result);
+
+ if (result) {
+ backup_->UpdateDBVersion();
+ Backup();
+ *pt_->policy_table.module_config.preloaded_pt = true;
+ } else {
+ rpc::ValidationReport report("policy_table");
+ snapshot->ReportErrors(&report);
+ ex_backup_->RemoveDB();
+ }
+ } break;
+ default: {
+ result = false;
+ LOG4CXX_ERROR(logger_, "Failed to init policy table.");
+ } break;
+ }
+
+ return result;
+}
+
+void CacheManager::FillDeviceSpecificData() {
+ DeviceIds unpaired_ids;
+ ex_backup_->UnpairedDevicesList(&unpaired_ids);
+ sync_primitives::AutoLock lock(unpaired_lock_);
+ is_unpaired_.clear();
+ for (DeviceIds::const_iterator ids_iter = unpaired_ids.begin();
+ ids_iter != unpaired_ids.end();
+ ++ids_iter) {
+ is_unpaired_.insert(*ids_iter);
+ }
+}
+
+bool CacheManager::LoadFromBackup() {
+ sync_primitives::AutoLock lock(cache_lock_);
+ pt_ = backup_->GenerateSnapshot();
+ update_required = backup_->UpdateRequired();
+
+ FillDeviceSpecificData();
+
+ return true;
+}
+
+bool CacheManager::LoadFromFile(const std::string& file_name,
+ policy_table::Table& table) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Loading policy table from file " << file_name);
+ BinaryMessage json_string;
+ if (!file_system::ReadBinaryFile(file_name, json_string)) {
+ LOG4CXX_FATAL(logger_, "Failed to read policy table source file.");
+ return false;
+ }
+
+ Json::Value value;
+ Json::Reader reader(Json::Features::strictMode());
+ std::string json(json_string.begin(), json_string.end());
+ if (!reader.parse(json.c_str(), value)) {
+ LOG4CXX_FATAL(
+ logger_,
+ "Preloaded PT is corrupted: " << reader.getFormattedErrorMessages());
+ return false;
+ }
+
+ LOG4CXX_DEBUG(logger_,
+ "Start verification of policy table loaded from file.");
+
+ table = policy_table::Table(&value);
+
+#ifdef ENABLE_LOG
+ Json::StyledWriter s_writer;
+ LOG4CXX_DEBUG(
+ logger_,
+ "Policy table content loaded:" << s_writer.write(table.ToJsonValue()));
+#endif // ENABLE_LOG
+
+ if (!table.is_valid()) {
+ rpc::ValidationReport report("policy_table");
+ table.ReportErrors(&report);
+ LOG4CXX_FATAL(logger_,
+ "Parsed table is not valid " << rpc::PrettyFormat(report));
+ return false;
+ }
+ return true;
+}
+
+bool CacheManager::ResetPT(const std::string& file_name) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ is_unpaired_.clear();
+ if (!backup_->RefreshDB()) {
+ LOG4CXX_ERROR(logger_, "Can't re-create policy database. Reset failed.");
+ return false;
+ }
+ sync_primitives::AutoLock lock(cache_lock_);
+ pt_.reset(new policy_table::Table());
+ const bool result = LoadFromFile(file_name, *pt_);
+ if (result) {
+ Backup();
+ *pt_->policy_table.module_config.preloaded_pt = true;
+ }
+ return result;
+}
+
+void CacheManager::GetAppRequestTypes(
+ const std::string& policy_app_id,
+ std::vector<std::string>& request_types) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+ if (kDeviceId == policy_app_id) {
+ LOG4CXX_DEBUG(logger_,
+ "Request types not applicable for app_id " << kDeviceId);
+ return;
+ }
+ policy_table::ApplicationPolicies::iterator policy_iter =
+ pt_->policy_table.app_policies_section.apps.find(policy_app_id);
+ if (pt_->policy_table.app_policies_section.apps.end() == policy_iter) {
+ LOG4CXX_DEBUG(logger_,
+ "Can't find request types for app_id " << policy_app_id);
+ return;
+ }
+ if (policy_iter->second.RequestType.is_initialized()) {
+ policy_table::RequestTypes::iterator it_request_type =
+ policy_iter->second.RequestType->begin();
+ for (; it_request_type != policy_iter->second.RequestType->end();
+ ++it_request_type) {
+ request_types.push_back(EnumToJsonString(*it_request_type));
+ }
+ }
+ return;
+}
+
+const MetaInfo CacheManager::GetMetaInfo() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ MetaInfo meta_info;
+ meta_info.ccpu_version = *pt_->policy_table.module_meta->ccpu_version;
+ meta_info.wers_country_code =
+ *pt_->policy_table.module_meta->wers_country_code;
+ meta_info.language = *pt_->policy_table.module_meta->language;
+ return meta_info;
+}
+
+std::string CacheManager::GetCertificate() const {
+ CACHE_MANAGER_CHECK(std::string(""));
+ if (pt_->policy_table.module_config.certificate.is_initialized()) {
+ return *pt_->policy_table.module_config.certificate;
+ }
+ return std::string("");
+}
+
+void CacheManager::SetDecryptedCertificate(const std::string& certificate) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ *pt_->policy_table.module_config.certificate = certificate;
+ Backup();
+}
+
+bool CacheManager::SetExternalConsentStatus(
+ const ExternalConsentStatus& status) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ if (status.empty()) {
+ LOG4CXX_INFO(logger_, "No ExternalConsent status update.");
+ return false;
+ }
+
+ return ex_backup_->SaveExternalConsentStatus(status);
+}
+
+ExternalConsentStatus CacheManager::GetExternalConsentStatus() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ return ex_backup_->GetExternalConsentStatus();
+}
+
+ExternalConsentStatus CacheManager::GetExternalConsentEntities() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ ExternalConsentStatus items;
+ for (policy_table::FunctionalGroupings::const_iterator it =
+ pt_->policy_table.functional_groupings.begin();
+ it != pt_->policy_table.functional_groupings.end();
+ ++it) {
+ policy_table::DisallowedByExternalConsentEntities::const_iterator it_1 =
+ (*it->second.disallowed_by_external_consent_entities_on).begin();
+ for (;
+ it_1 != (*it->second.disallowed_by_external_consent_entities_on).end();
+ ++it_1) {
+ items.insert(ExternalConsentStatusItem(
+ it_1->entity_type, it_1->entity_id, EntityStatus::kStatusOn));
+ }
+ policy_table::DisallowedByExternalConsentEntities::const_iterator it_2 =
+ (*it->second.disallowed_by_external_consent_entities_off).begin();
+ for (; it_2 !=
+ (*it->second.disallowed_by_external_consent_entities_off).end();
+ ++it_2) {
+ items.insert(ExternalConsentStatusItem(
+ it_2->entity_type, it_2->entity_id, EntityStatus::kStatusOff));
+ }
+ }
+ return items;
+}
+
+GroupsByExternalConsentStatus CacheManager::GetGroupsWithSameEntities(
+ const ExternalConsentStatus& status) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(policy::GroupsByExternalConsentStatus());
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ GroupsByExternalConsentStatus groups_by_external_consent;
+
+ GroupByExternalConsentItemFinder groups_by_external_consent_finder(
+ pt_->policy_table.functional_groupings, groups_by_external_consent);
+ std::for_each(
+ status.begin(), status.end(), groups_by_external_consent_finder);
+
+ return groups_by_external_consent;
+}
+
+std::map<std::string, std::string> CacheManager::GetKnownLinksFromPT() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK((std::map<std::string, std::string>()));
+ std::map<std::string, std::string> links;
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+
+ LinkCollector collector(links);
+ std::for_each(pt_->policy_table.device_data->begin(),
+ pt_->policy_table.device_data->end(),
+ collector);
+
+ return links;
+}
+
+bool CacheManager::ConsentsSame(
+ const policy_table::ConsentGroups& external_consent_groups,
+ const PermissionConsent& permissions) const {
+ const std::vector<FunctionalGroupPermission>& group_permissions =
+ permissions.group_permissions;
+
+ std::vector<FunctionalGroupPermission>::const_iterator it_gp =
+ group_permissions.begin();
+
+ for (; group_permissions.end() != it_gp; ++it_gp) {
+ const policy_table::ConsentGroups::value_type value = std::make_pair(
+ it_gp->group_name, rpc::Boolean(it_gp->state == kGroupAllowed));
+
+ const bool is_found = external_consent_groups.end() !=
+ std::find(external_consent_groups.begin(),
+ external_consent_groups.end(),
+ value);
+
+ if (!is_found) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void CacheManager::SetExternalConsentForApp(
+ const PermissionConsent& permissions) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ policy_table::ConsentGroups& external_consent_groups =
+ *(*(*pt_->policy_table.device_data)[permissions.device_id]
+ .user_consent_records)[permissions.policy_app_id]
+ .external_consent_status_groups;
+
+ if (ConsentsSame(external_consent_groups, permissions)) {
+ LOG4CXX_DEBUG(logger_, "External consents already have same values.");
+ return;
+ }
+
+ external_consent_groups.clear();
+
+ ExternalConsentConsentGroupAppender appender;
+ std::transform(
+ permissions.group_permissions.begin(),
+ permissions.group_permissions.end(),
+ std::inserter(external_consent_groups, external_consent_groups.begin()),
+ appender);
+
+ policy_table::ConsentRecords& app_consent_records =
+ (*(*pt_->policy_table.device_data)[permissions.device_id]
+ .user_consent_records)[permissions.policy_app_id];
+
+ const TimevalStruct tm = date_time::DateTime::getCurrentTime();
+ int64_t current_time_msec = date_time::DateTime::getmSecs(tm);
+ app_consent_records.ext_consent_last_updated = current_time_msec;
+ LOG4CXX_DEBUG(logger_, "Updating consents time " << current_time_msec);
+
+ Backup();
+}
+
+bool CacheManager::MergePreloadPT(const std::string& file_name) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ policy_table::Table table;
+ if (!LoadFromFile(file_name, table)) {
+ LOG4CXX_DEBUG(logger_, "Unable to load preloaded PT.");
+ return false;
+ }
+
+ sync_primitives::AutoLock lock(cache_lock_);
+ policy_table::PolicyTable& current = pt_->policy_table;
+ policy_table::PolicyTable& new_table = table.policy_table;
+ const std::string date_current = *current.module_config.preloaded_date;
+ const std::string date_new = *new_table.module_config.preloaded_date;
+ if (date_current != date_new) {
+ MergeMC(new_table, current);
+ MergeFG(new_table, current);
+ MergeAP(new_table, current);
+ MergeCFM(new_table, current);
+ Backup();
+ }
+ return true;
+}
+
+void CacheManager::MergeMC(const policy_table::PolicyTable& new_pt,
+ policy_table::PolicyTable& pt) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ policy_table::ModuleConfig copy(pt.module_config);
+
+ pt.module_config = new_pt.module_config;
+ pt.module_config.vehicle_make = copy.vehicle_make;
+ pt.module_config.vehicle_year = copy.vehicle_year;
+ pt.module_config.vehicle_model = copy.vehicle_model;
+}
+
+void CacheManager::MergeFG(const policy_table::PolicyTable& new_pt,
+ policy_table::PolicyTable& pt) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ policy_table::FunctionalGroupings::const_iterator it =
+ new_pt.functional_groupings.begin();
+
+ for (; it != new_pt.functional_groupings.end(); ++it) {
+ LOG4CXX_DEBUG(logger_, "Merge functional group: " << it->first);
+ pt.functional_groupings[it->first] = it->second;
+ }
+}
+
+void CacheManager::MergeAP(const policy_table::PolicyTable& new_pt,
+ policy_table::PolicyTable& pt) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ pt.app_policies_section.device = const_cast<policy_table::PolicyTable&>(
+ new_pt).app_policies_section.device;
+
+ pt.app_policies_section.apps[kDefaultId] =
+ const_cast<policy_table::PolicyTable&>(new_pt)
+ .app_policies_section.apps[kDefaultId];
+
+ pt.app_policies_section.apps[kPreDataConsentId] =
+ const_cast<policy_table::PolicyTable&>(new_pt)
+ .app_policies_section.apps[kPreDataConsentId];
+}
+
+void CacheManager::MergeCFM(const policy_table::PolicyTable& new_pt,
+ policy_table::PolicyTable& pt) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (new_pt.consumer_friendly_messages.is_initialized()) {
+ if (!pt.consumer_friendly_messages.is_initialized()) {
+ pt.consumer_friendly_messages = new_pt.consumer_friendly_messages;
+ } else {
+ policy_table::Messages::const_iterator it =
+ new_pt.consumer_friendly_messages->messages->begin();
+
+ pt.consumer_friendly_messages->version =
+ new_pt.consumer_friendly_messages->version;
+ for (; it != new_pt.consumer_friendly_messages->messages->end(); ++it) {
+ LOG4CXX_DEBUG(logger_, "Merge CFM: " << it->first);
+ if (!(pt.consumer_friendly_messages->messages.is_initialized())) {
+ LOG4CXX_DEBUG(logger_, "CFM not initialized.");
+ }
+ (*pt.consumer_friendly_messages->messages)[it->first] = it->second;
+ }
+ }
+ }
+}
+
+void CacheManager::InitBackupThread() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ backuper_ = new BackgroundBackuper(this);
+ backup_thread_ = threads::CreateThread("Backup thread", backuper_);
+ backup_thread_->start();
+}
+
+const PolicySettings& CacheManager::get_settings() const {
+ DCHECK(settings_);
+
+ return *settings_;
+}
+
+CacheManager::BackgroundBackuper::BackgroundBackuper(
+ CacheManager* cache_manager)
+ : cache_manager_(cache_manager)
+ , stop_flag_(false)
+ , new_data_available_(false) {
+ LOG4CXX_AUTO_TRACE(logger_);
+}
+
+CacheManager::BackgroundBackuper::~BackgroundBackuper() {
+ LOG4CXX_AUTO_TRACE(logger_);
+}
+
+void CacheManager::BackgroundBackuper::InternalBackup() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ DCHECK(cache_manager_);
+
+ while (new_data_available_) {
+ new_data_available_ = false;
+ LOG4CXX_DEBUG(logger_, "DoBackup");
+ cache_manager_->PersistData();
+ }
+}
+
+void CacheManager::BackgroundBackuper::threadMain() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(need_backup_lock_);
+ while (!stop_flag_) {
+ need_backup_lock_.Release();
+ InternalBackup();
+ need_backup_lock_.Acquire();
+ if (new_data_available_ || stop_flag_) {
+ continue;
+ }
+ LOG4CXX_DEBUG(logger_, "Wait for a next backup");
+ backup_notifier_.Wait(need_backup_lock_);
+ }
+}
+
+void CacheManager::BackgroundBackuper::exitThreadMain() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(need_backup_lock_);
+ stop_flag_ = true;
+ backup_notifier_.NotifyOne();
+}
+
+void CacheManager::BackgroundBackuper::DoBackup() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(need_backup_lock_);
+ new_data_available_ = true;
+ backup_notifier_.NotifyOne();
+}
+
+} // namespace policy
diff --git a/src/components/policy/policy_external/src/policy_helper.cc b/src/components/policy/policy_external/src/policy_helper.cc
new file mode 100644
index 0000000000..cb27e7f0b3
--- /dev/null
+++ b/src/components/policy/policy_external/src/policy_helper.cc
@@ -0,0 +1,868 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include "utils/logger.h"
+#include "utils/custom_string.h"
+#include "policy/policy_helper.h"
+#include "policy/policy_manager_impl.h"
+
+namespace policy {
+
+namespace custom_str = utils::custom_string;
+
+namespace {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Policy")
+
+bool Compare(const StringsValueType& first, const StringsValueType& second) {
+ const std::string& first_str = first;
+ const std::string& second_str = second;
+ return (strcasecmp(first_str.c_str(), second_str.c_str()) < 0);
+}
+
+struct CheckGroupName {
+ explicit CheckGroupName(const policy::StringsValueType& value)
+ : value_(value) {}
+
+ bool operator()(const FunctionalGroupNames::value_type& value) const {
+ return value.second.second == std::string(value_);
+ }
+
+ private:
+ const policy::StringsValueType& value_;
+};
+
+struct CopyAttributes {
+ CopyAttributes(const FunctionalGroupNames& groups_attributes,
+ std::vector<FunctionalGroupPermission>& groups_permissions)
+ : groups_attributes_(groups_attributes)
+ , groups_permissions_(groups_permissions) {}
+
+ bool operator()(const policy::StringsValueType& value) {
+ CheckGroupName checker(value);
+ FunctionalGroupNames::const_iterator it = std::find_if(
+ groups_attributes_.begin(), groups_attributes_.end(), checker);
+ if (groups_attributes_.end() == it) {
+ return false;
+ }
+ FunctionalGroupPermission group;
+ group.group_name = it->second.second;
+ group.group_alias = it->second.first;
+ group.group_id = it->first;
+ groups_permissions_.push_back(group);
+ return true;
+ }
+
+ private:
+ const FunctionalGroupNames& groups_attributes_;
+ std::vector<FunctionalGroupPermission>& groups_permissions_;
+};
+} // namespace
+
+CompareGroupName::CompareGroupName(const StringsValueType& group_name)
+ : group_name_(group_name) {}
+
+bool CompareGroupName::operator()(
+ const StringsValueType& group_name_to_compare) const {
+ const std::string gn_ = group_name_;
+ const std::string gn_compare = group_name_to_compare;
+ return !(strcasecmp(gn_.c_str(), gn_compare.c_str()));
+}
+
+bool operator!=(const policy_table::ApplicationParams& first,
+ const policy_table::ApplicationParams& second) {
+ if (first.groups.size() != second.groups.size()) {
+ return true;
+ }
+ StringsConstItr it_first = first.groups.begin();
+ StringsConstItr it_first_end = first.groups.end();
+ StringsConstItr it_second = second.groups.begin();
+ StringsConstItr it_second_end = second.groups.end();
+ for (; it_first != it_first_end; ++it_first) {
+ CompareGroupName gp(*it_first);
+ StringsConstItr it = std::find_if(it_second, it_second_end, gp);
+ if (it_first_end == it) {
+ return true;
+ }
+ }
+ return false;
+}
+
+CheckAppPolicy::CheckAppPolicy(
+ PolicyManagerImpl* pm,
+ const utils::SharedPtr<policy_table::Table> update,
+ const utils::SharedPtr<policy_table::Table> snapshot,
+ CheckAppPolicyResults& out_results)
+ : pm_(pm)
+ , update_(update)
+ , snapshot_(snapshot)
+ , out_results_(out_results) {}
+
+bool policy::CheckAppPolicy::HasRevokedGroups(
+ const policy::AppPoliciesValueType& app_policy,
+ policy_table::Strings* revoked_groups) const {
+ AppPoliciesConstItr it =
+ snapshot_->policy_table.app_policies_section.apps.find(app_policy.first);
+
+ policy_table::Strings groups_new = app_policy.second.groups;
+ std::sort(groups_new.begin(), groups_new.end(), Compare);
+
+ policy_table::Strings groups_curr = (*it).second.groups;
+ std::sort(groups_curr.begin(), groups_curr.end(), Compare);
+
+ StringsConstItr it_groups_new = groups_new.begin();
+ StringsConstItr it_groups_new_end = groups_new.end();
+
+ StringsConstItr it_groups_curr = groups_curr.begin();
+ StringsConstItr it_groups_curr_end = groups_curr.end();
+
+ policy_table::Strings revoked_group_list;
+ std::set_difference(it_groups_curr,
+ it_groups_curr_end,
+ it_groups_new,
+ it_groups_new_end,
+ std::back_inserter(revoked_group_list),
+ Compare);
+
+ // Remove groups which are not required user consent
+ policy_table::Strings::iterator it_revoked = revoked_group_list.begin();
+ for (; revoked_group_list.end() != it_revoked;) {
+ if (!IsConsentRequired(app_policy.first, std::string(*it_revoked))) {
+ revoked_group_list.erase(it_revoked);
+ it_revoked = revoked_group_list.begin();
+ } else {
+ ++it_revoked;
+ }
+ }
+
+ if (revoked_groups) {
+ *revoked_groups = revoked_group_list;
+ }
+
+ return !revoked_group_list.empty();
+}
+
+bool policy::CheckAppPolicy::HasNewGroups(
+ const policy::AppPoliciesValueType& app_policy,
+ policy_table::Strings* new_groups) const {
+ AppPoliciesConstItr it =
+ snapshot_->policy_table.app_policies_section.apps.find(app_policy.first);
+
+ policy_table::Strings groups_new = app_policy.second.groups;
+ std::sort(groups_new.begin(), groups_new.end(), Compare);
+
+ policy_table::Strings groups_curr = (*it).second.groups;
+ std::sort(groups_curr.begin(), groups_curr.end(), Compare);
+
+ StringsConstItr it_groups_new = groups_new.begin();
+ StringsConstItr it_groups_new_end = groups_new.end();
+
+ StringsConstItr it_groups_curr = groups_curr.begin();
+ StringsConstItr it_groups_curr_end = groups_curr.end();
+
+ policy_table::Strings new_group_list;
+ std::set_difference(it_groups_new,
+ it_groups_new_end,
+ it_groups_curr,
+ it_groups_curr_end,
+ std::back_inserter(new_group_list),
+ Compare);
+
+ if (new_groups) {
+ *new_groups = new_group_list;
+ }
+
+ return !new_group_list.empty();
+}
+
+bool policy::CheckAppPolicy::HasConsentNeededGroups(
+ const policy::AppPoliciesValueType& app_policy) const {
+ policy_table::Strings new_groups;
+ if (!HasNewGroups(app_policy, &new_groups)) {
+ return false;
+ }
+
+ StringsConstItr it_new = new_groups.begin();
+ StringsConstItr it_new_end = new_groups.end();
+ for (; it_new != it_new_end; ++it_new) {
+ if (IsConsentRequired(app_policy.first, *it_new)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+std::vector<FunctionalGroupPermission> policy::CheckAppPolicy::GetRevokedGroups(
+ const policy::AppPoliciesValueType& app_policy) const {
+ policy_table::Strings revoked_groups_names;
+ if (!HasRevokedGroups(app_policy, &revoked_groups_names)) {
+ return std::vector<FunctionalGroupPermission>();
+ }
+
+ FunctionalGroupNames groups_attributes;
+ if (!pm_->cache_->GetFunctionalGroupNames(groups_attributes)) {
+ LOG4CXX_WARN(logger_, "Can't get functional group names");
+ return std::vector<FunctionalGroupPermission>();
+ }
+
+ std::vector<FunctionalGroupPermission> revoked_groups_permissions;
+ CopyAttributes copier(groups_attributes, revoked_groups_permissions);
+ std::for_each(
+ revoked_groups_names.begin(), revoked_groups_names.end(), copier);
+
+ return revoked_groups_permissions;
+}
+
+void policy::CheckAppPolicy::RemoveRevokedConsents(
+ const AppPoliciesValueType& app_policy,
+ const std::vector<FunctionalGroupPermission>& revoked_groups) const {
+ std::vector<policy::FunctionalGroupPermission>::const_iterator it =
+ revoked_groups.begin();
+ std::vector<policy::FunctionalGroupPermission>::const_iterator it_end =
+ revoked_groups.end();
+ for (; it != it_end; ++it) {
+ pm_->RemoveAppConsentForGroup(app_policy.first, it->group_name);
+ }
+}
+
+bool CheckAppPolicy::IsKnownAppication(
+ const std::string& application_id) const {
+ const policy_table::ApplicationPolicies& current_policies =
+ snapshot_->policy_table.app_policies_section.apps;
+
+ return !(current_policies.end() == current_policies.find(application_id));
+}
+
+bool CheckAppPolicy::IsAppRevoked(
+ const AppPoliciesValueType& app_policy) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ // Application params are not initialized = application revoked
+ // i.e. "123":null
+ return app_policy.second.is_null();
+}
+
+bool CheckAppPolicy::NicknamesMatch(
+ const AppPoliciesValueType& app_policy) const {
+ const std::string& app_id = app_policy.first;
+ const custom_str::CustomString app_name = pm_->listener()->GetAppName(app_id);
+ if (!app_name.empty() && app_policy.second.nicknames &&
+ !app_policy.second.nicknames->empty()) {
+ for (policy_table::Strings::const_iterator it =
+ app_policy.second.nicknames->begin();
+ app_policy.second.nicknames->end() != it;
+ ++it) {
+ std::string temp = *it;
+ if (app_name.CompareIgnoreCase(temp.c_str())) {
+ return true;
+ }
+ }
+ return false;
+ }
+ return true;
+}
+
+void CheckAppPolicy::AddResult(const std::string& app_id,
+ PermissionsCheckResult result) {
+ out_results_.insert(std::make_pair(app_id, result));
+}
+
+bool CheckAppPolicy::operator()(const AppPoliciesValueType& app_policy) {
+ const std::string app_id = app_policy.first;
+
+ if (!IsKnownAppication(app_id)) {
+ LOG4CXX_WARN(logger_,
+ "Application:" << app_id << " is not present in snapshot.");
+ return true;
+ }
+
+ if (!IsPredefinedApp(app_policy) && IsAppRevoked(app_policy)) {
+ SetPendingPermissions(app_policy, RESULT_APP_REVOKED);
+ AddResult(app_id, RESULT_APP_REVOKED);
+ return true;
+ }
+
+ if (!IsPredefinedApp(app_policy) && !NicknamesMatch(app_policy)) {
+ SetPendingPermissions(app_policy, RESULT_NICKNAME_MISMATCH);
+ AddResult(app_id, RESULT_NICKNAME_MISMATCH);
+ return true;
+ }
+
+ PermissionsCheckResult result = CheckPermissionsChanges(app_policy);
+
+ if (!IsPredefinedApp(app_policy) && IsRequestTypeChanged(app_policy)) {
+ SetPendingPermissions(app_policy, RESULT_REQUEST_TYPE_CHANGED);
+ AddResult(app_id, RESULT_REQUEST_TYPE_CHANGED);
+ }
+
+ if (RESULT_NO_CHANGES == result) {
+ LOG4CXX_INFO(logger_,
+ "Permissions for application:" << app_id
+ << " wasn't changed.");
+ AddResult(app_id, result);
+ return true;
+ }
+
+ LOG4CXX_INFO(logger_,
+ "Permissions for application:" << app_id
+ << " have been changed.");
+
+ if (!IsPredefinedApp(app_policy)) {
+ SetPendingPermissions(app_policy, result);
+ AddResult(app_id, result);
+ }
+
+ return true;
+}
+
+void policy::CheckAppPolicy::SetPendingPermissions(
+ const AppPoliciesValueType& app_policy,
+ PermissionsCheckResult result) const {
+ using namespace rpc::policy_table_interface_base;
+ const std::string app_id = app_policy.first;
+ AppPermissions permissions_diff(app_id);
+
+ const std::string priority =
+ policy_table::EnumToJsonString(app_policy.second.priority);
+ const std::string current_prio = EnumToJsonString(
+ snapshot_->policy_table.app_policies_section.apps[app_id].priority);
+
+ bool need_send_priority = (current_prio != priority);
+
+ switch (result) {
+ case RESULT_APP_REVOKED:
+ need_send_priority = false;
+ permissions_diff.appRevoked = true;
+ break;
+ case RESULT_NICKNAME_MISMATCH:
+ need_send_priority = false;
+ permissions_diff.appUnauthorized = true;
+ break;
+ case RESULT_PERMISSIONS_REVOKED:
+ permissions_diff.priority = priority;
+ permissions_diff.isAppPermissionsRevoked = true;
+ permissions_diff.appRevokedPermissions = GetRevokedGroups(app_policy);
+ RemoveRevokedConsents(app_policy, permissions_diff.appRevokedPermissions);
+ break;
+ case RESULT_CONSENT_NEEDED:
+ permissions_diff.priority = priority;
+ permissions_diff.appPermissionsConsentNeeded = true;
+ break;
+ case RESULT_PERMISSIONS_REVOKED_AND_CONSENT_NEEDED:
+ permissions_diff.priority = priority;
+ permissions_diff.isAppPermissionsRevoked = true;
+ permissions_diff.appPermissionsConsentNeeded = true;
+ permissions_diff.appRevokedPermissions = GetRevokedGroups(app_policy);
+ RemoveRevokedConsents(app_policy, permissions_diff.appRevokedPermissions);
+ break;
+ case RESULT_REQUEST_TYPE_CHANGED:
+ permissions_diff.requestTypeChanged = true;
+ {
+ // Getting RequestTypes from PTU (not from cache)
+ policy_table::RequestTypes::const_iterator it_request_type =
+ app_policy.second.RequestType->begin();
+ for (; app_policy.second.RequestType->end() != it_request_type;
+ ++it_request_type) {
+ permissions_diff.requestType.push_back(
+ EnumToJsonString(*it_request_type));
+ }
+ }
+
+ break;
+ default:
+ return;
+ }
+
+ if (need_send_priority) {
+ permissions_diff.priority = priority;
+ }
+
+ pm_->app_permissions_diff_lock_.Acquire();
+ pm_->app_permissions_diff_.insert(std::make_pair(app_id, permissions_diff));
+ pm_->app_permissions_diff_lock_.Release();
+}
+
+PermissionsCheckResult CheckAppPolicy::CheckPermissionsChanges(
+ const policy::AppPoliciesValueType& app_policy) const {
+ bool has_revoked_groups = HasRevokedGroups(app_policy);
+
+ bool has_consent_needed_groups = HasConsentNeededGroups(app_policy);
+
+ bool has_new_groups = HasNewGroups(app_policy);
+
+ if (has_revoked_groups && has_consent_needed_groups) {
+ return RESULT_PERMISSIONS_REVOKED_AND_CONSENT_NEEDED;
+ } else if (has_revoked_groups) {
+ return RESULT_PERMISSIONS_REVOKED;
+ } else if (has_consent_needed_groups) {
+ return RESULT_CONSENT_NEEDED;
+ } else if (has_new_groups) {
+ return RESULT_CONSENT_NOT_REQIURED;
+ }
+
+ return RESULT_NO_CHANGES;
+}
+
+bool CheckAppPolicy::IsConsentRequired(const std::string& app_id,
+ const std::string& group_name) const {
+ const policy_table::FunctionalGroupings& functional_groupings =
+ snapshot_->policy_table.functional_groupings;
+
+ FuncGroupConstItr it = functional_groupings.find(group_name);
+
+ if (functional_groupings.end() == it) {
+ return false;
+ }
+
+ bool is_preconsented = false;
+ policy_table::Strings::value_type str(group_name);
+ policy_table::Strings::iterator pre_begin =
+ update_->policy_table.app_policies_section.apps[app_id]
+ .preconsented_groups->begin();
+ policy_table::Strings::iterator pre_end =
+ update_->policy_table.app_policies_section.apps[app_id]
+ .preconsented_groups->end();
+
+ policy_table::Strings::iterator it2 = std::find(pre_begin, pre_end, str);
+
+ is_preconsented = pre_end != it2;
+
+ return it->second.user_consent_prompt.is_initialized() && !is_preconsented;
+}
+
+bool CheckAppPolicy::IsRequestTypeChanged(
+ const AppPoliciesValueType& app_policy) const {
+ policy::AppPoliciesConstItr it =
+ snapshot_->policy_table.app_policies_section.apps.find(app_policy.first);
+ if (it == snapshot_->policy_table.app_policies_section.apps.end()) {
+ if (!app_policy.second.RequestType->empty()) {
+ return true;
+ }
+ return false;
+ }
+ if (it->second.RequestType->size() != app_policy.second.RequestType->size()) {
+ return true;
+ }
+ policy_table::RequestTypes diff;
+ std::set_difference(it->second.RequestType->begin(),
+ it->second.RequestType->end(),
+ app_policy.second.RequestType->begin(),
+ app_policy.second.RequestType->end(),
+ std::back_inserter(diff));
+ return diff.size();
+}
+
+FillNotificationData::FillNotificationData(Permissions& data,
+ GroupConsent group_state,
+ GroupConsent undefined_group_consent,
+ bool does_require_user_consent)
+ : data_(data), does_require_user_consent_(does_require_user_consent) {
+ switch (group_state) {
+ case kGroupAllowed:
+ current_key_ = kAllowedKey;
+ break;
+ case kGroupUndefined:
+ if (kGroupUndefined == undefined_group_consent) {
+ current_key_ = kUndefinedKey;
+ break;
+ }
+ current_key_ = kGroupAllowed == undefined_group_consent
+ ? kAllowedKey
+ : kUserDisallowedKey;
+ break;
+ default:
+ current_key_ = kUserDisallowedKey;
+ break;
+ }
+}
+
+bool FillNotificationData::operator()(const RpcValueType& rpc) {
+ Permissions::iterator it = data_.find(rpc.first);
+ // If rpc is present already - update its permissions
+ if (data_.end() != it) {
+ UpdateHMILevels(rpc.second.hmi_levels, (*it).second.hmi_permissions);
+ UpdateParameters(*rpc.second.parameters,
+ (*it).second.parameter_permissions);
+ ExcludeSame(it->second);
+ } else {
+ // Init mandatory keys, since they should be present irrespectively of
+ // values presence
+ InitRpcKeys(rpc.first);
+ // If rpc is not present - add its permissions
+ UpdateHMILevels(rpc.second.hmi_levels, data_[rpc.first].hmi_permissions);
+ UpdateParameters(*rpc.second.parameters,
+ data_[rpc.first].parameter_permissions);
+ }
+ return true;
+}
+
+void FillNotificationData::UpdateHMILevels(
+ const policy_table::HmiLevels& in_hmi, HMIPermissions& out_hmi) {
+ HMILevelsConstItr it_hmi_levels = in_hmi.begin();
+ HMILevelsConstItr it_hmi_levels_end = in_hmi.end();
+
+ for (; it_hmi_levels != it_hmi_levels_end; ++it_hmi_levels) {
+ out_hmi[current_key_].insert(
+ policy_table::EnumToJsonString(*it_hmi_levels));
+ }
+}
+
+void FillNotificationData::UpdateParameters(
+ const policy_table::Parameters& in_parameters,
+ ParameterPermissions& out_parameter) {
+ ParametersConstItr it_parameters = in_parameters.begin();
+ ParametersConstItr it_parameters_end = in_parameters.end();
+
+ // Due to APPLINK-24201 SDL must consider cases when 'parameters' section is
+ // not present for RPC or present, but is empty.
+
+ // If 'parameters' section is like: 'parameters' : []
+ if (in_parameters.is_initialized() && in_parameters.empty()) {
+ if (!does_require_user_consent_) {
+ out_parameter.any_parameter_disallowed_by_policy = true;
+ }
+ if (does_require_user_consent_ && kAllowedKey == current_key_) {
+ out_parameter.any_parameter_disallowed_by_user = true;
+ }
+ }
+
+ // If 'parameters' section is omitted
+ if (!in_parameters.is_initialized()) {
+ if (!does_require_user_consent_) {
+ out_parameter.any_parameter_allowed = true;
+ }
+ if (does_require_user_consent_ && kAllowedKey == current_key_) {
+ out_parameter.any_parameter_allowed = true;
+ }
+ }
+
+ for (; it_parameters != it_parameters_end; ++it_parameters) {
+ out_parameter[current_key_].insert(
+ policy_table::EnumToJsonString(*it_parameters));
+ }
+}
+
+void FillNotificationData::ExcludeSame(RpcPermissions& rpc) {
+ HMIPermissions::const_iterator it_hmi_allowed =
+ rpc.hmi_permissions.find(kAllowedKey);
+ HMIPermissions::const_iterator it_hmi_undefined =
+ rpc.hmi_permissions.find(kUndefinedKey);
+ HMIPermissions::const_iterator it_hmi_user_disallowed =
+ rpc.hmi_permissions.find(kUserDisallowedKey);
+
+ // There is different logic of processing RPCs with and w/o 'parameters'
+ if (RpcParametersEmpty(rpc)) {
+ // First, remove disallowed from other types
+ if (rpc.hmi_permissions.end() != it_hmi_user_disallowed) {
+ if (rpc.hmi_permissions.end() != it_hmi_allowed) {
+ ExcludeSameHMILevels(rpc.hmi_permissions[kAllowedKey],
+ rpc.hmi_permissions[kUserDisallowedKey]);
+ }
+ if (rpc.hmi_permissions.end() != it_hmi_undefined) {
+ ExcludeSameHMILevels(rpc.hmi_permissions[kUndefinedKey],
+ rpc.hmi_permissions[kUserDisallowedKey]);
+ }
+ }
+
+ // Then, remove undefined from allowed
+ if (rpc.hmi_permissions.end() != it_hmi_undefined) {
+ if (rpc.hmi_permissions.end() != it_hmi_allowed) {
+ ExcludeSameHMILevels(rpc.hmi_permissions[kAllowedKey],
+ rpc.hmi_permissions[kUndefinedKey]);
+ }
+ }
+
+ return;
+ }
+
+ ParameterPermissions::const_iterator it_parameter_allowed =
+ rpc.parameter_permissions.find(kAllowedKey);
+ ParameterPermissions::const_iterator it_parameter_undefined =
+ rpc.parameter_permissions.find(kUndefinedKey);
+ ParameterPermissions::const_iterator it_parameter_user_disallowed =
+ rpc.parameter_permissions.find(kUserDisallowedKey);
+
+ // First, removing allowed HMI levels from other types, permissions will be
+ // dependent on parameters instead of HMI levels since w/o parameters RPC
+ // won't passed to HMI
+ if (rpc.hmi_permissions.end() != it_hmi_allowed) {
+ if (rpc.hmi_permissions.end() != it_hmi_user_disallowed) {
+ ExcludeSameHMILevels(rpc.hmi_permissions[kUserDisallowedKey],
+ rpc.hmi_permissions[kAllowedKey]);
+ }
+ if (rpc.hmi_permissions.end() != it_hmi_undefined) {
+ ExcludeSameHMILevels(rpc.hmi_permissions[kUndefinedKey],
+ rpc.hmi_permissions[kAllowedKey]);
+ }
+ }
+
+ // Removing disallowed parameters from allowed and undefined (by user consent)
+ if (rpc.parameter_permissions.end() != it_parameter_user_disallowed) {
+ if (rpc.parameter_permissions.end() != it_parameter_allowed) {
+ ExcludeSameParameters(rpc.parameter_permissions[kAllowedKey],
+ rpc.parameter_permissions[kUserDisallowedKey]);
+ }
+ if (rpc.parameter_permissions.end() != it_parameter_undefined) {
+ ExcludeSameParameters(rpc.parameter_permissions[kUndefinedKey],
+ rpc.parameter_permissions[kUserDisallowedKey]);
+ }
+ }
+
+ // Removing undefined (by user consent) parameters from allowed
+ if (rpc.parameter_permissions.end() != it_parameter_undefined) {
+ if (rpc.parameter_permissions.end() != it_parameter_allowed) {
+ ExcludeSameParameters(rpc.parameter_permissions[kAllowedKey],
+ rpc.parameter_permissions[kUndefinedKey]);
+ }
+ }
+}
+
+void FillNotificationData::ExcludeSameHMILevels(
+ std::set<HMILevel>& source, const std::set<HMILevel>& target) {
+ std::set<HMILevel> diff_hmi;
+
+ std::set_difference(source.begin(),
+ source.end(),
+ target.begin(),
+ target.end(),
+ std::inserter(diff_hmi, diff_hmi.begin()));
+
+ source = diff_hmi;
+}
+
+void FillNotificationData::ExcludeSameParameters(
+ std::set<Parameter>& source, const std::set<Parameter>& target) {
+ std::set<Parameter> diff_parameter;
+
+ std::set_difference(source.begin(),
+ source.end(),
+ target.begin(),
+ target.end(),
+ std::inserter(diff_parameter, diff_parameter.begin()));
+
+ source = diff_parameter;
+}
+
+void FillNotificationData::InitRpcKeys(const std::string& rpc_name) {
+ data_[rpc_name].hmi_permissions[kAllowedKey];
+ data_[rpc_name].hmi_permissions[kUserDisallowedKey];
+ data_[rpc_name].parameter_permissions[kAllowedKey];
+ data_[rpc_name].parameter_permissions[kUserDisallowedKey];
+}
+
+bool FillNotificationData::RpcParametersEmpty(RpcPermissions& rpc) {
+ const bool no_allowed_parameters =
+ IsSectionEmpty(rpc.parameter_permissions, kAllowedKey);
+ const bool no_user_disallowed_parameters =
+ IsSectionEmpty(rpc.parameter_permissions, kUserDisallowedKey);
+ const bool no_undefined_parameters =
+ IsSectionEmpty(rpc.parameter_permissions, kUndefinedKey);
+
+ return no_allowed_parameters && no_undefined_parameters &&
+ no_user_disallowed_parameters;
+}
+
+bool FillNotificationData::IsSectionEmpty(ParameterPermissions& permissions,
+ const std::string& section) {
+ ParameterPermissions::const_iterator it_section = permissions.find(section);
+ ParameterPermissions::const_iterator end = permissions.end();
+ if (end != it_section) {
+ return permissions[section].empty();
+ }
+ return true;
+}
+
+ProcessFunctionalGroup::ProcessFunctionalGroup(
+ const policy_table::FunctionalGroupings& fg,
+ const std::vector<FunctionalGroupPermission>& group_permissions,
+ Permissions& data,
+ GroupConsent undefined_group_consent)
+ : fg_(fg)
+ , group_permissions_(group_permissions)
+ , data_(data)
+ , undefined_group_consent_(undefined_group_consent) {}
+
+bool ProcessFunctionalGroup::operator()(const StringsValueType& group_name) {
+ const std::string group_name_str = group_name;
+ FuncGroupConstItr it = fg_.find(group_name_str);
+ const bool does_require_user_consent =
+ it->second.user_consent_prompt.is_initialized();
+
+ if (fg_.end() != it) {
+ const policy_table::Rpc& rpcs = (*it).second.rpcs;
+ FillNotificationData filler(data_,
+ GetGroupState(group_name_str),
+ undefined_group_consent_,
+ does_require_user_consent);
+ std::for_each(rpcs.begin(), rpcs.end(), filler);
+ }
+ return true;
+}
+
+GroupConsent ProcessFunctionalGroup::GetGroupState(
+ const std::string& group_name) {
+ std::vector<FunctionalGroupPermission>::const_iterator it =
+ group_permissions_.begin();
+ std::vector<FunctionalGroupPermission>::const_iterator it_end =
+ group_permissions_.end();
+ for (; it != it_end; ++it) {
+ if (group_name == (*it).group_name) {
+ return (*it).state;
+ }
+ }
+ return kGroupUndefined;
+}
+
+FunctionalGroupInserter::FunctionalGroupInserter(
+ const policy_table::Strings& preconsented_groups, PermissionsList& list)
+ : list_(list), preconsented_(preconsented_groups) {}
+
+void FunctionalGroupInserter::operator()(const StringsValueType& group_name) {
+ CompareGroupName name(group_name);
+ if (std::find_if(preconsented_.begin(), preconsented_.end(), name) ==
+ preconsented_.end()) {
+ list_.push_back(group_name);
+ }
+}
+
+void FillFunctionalGroupPermissions(
+ FunctionalGroupIDs& ids,
+ FunctionalGroupNames& names,
+ GroupConsent state,
+ std::vector<FunctionalGroupPermission>& permissions) {
+ LOG4CXX_INFO(logger_, "FillFunctionalGroupPermissions");
+ FunctionalGroupIDs::const_iterator it = ids.begin();
+ FunctionalGroupIDs::const_iterator it_end = ids.end();
+ for (; it != it_end; ++it) {
+ FunctionalGroupPermission current_group;
+ current_group.group_id = *it;
+ current_group.group_alias = names[*it].first;
+ current_group.group_name = names[*it].second;
+ current_group.state = state;
+ permissions.push_back(current_group);
+ }
+}
+
+bool IsPredefinedApp(const AppPoliciesValueType& app) {
+ return app.first == kDefaultId || app.first == kPreDataConsentId ||
+ app.first == kDeviceId;
+}
+
+FunctionalGroupIDs ExcludeSame(const FunctionalGroupIDs& from,
+ const FunctionalGroupIDs& what) {
+ LOG4CXX_INFO(logger_, "Exclude same groups");
+ FunctionalGroupIDs from_copy(from);
+ FunctionalGroupIDs what_copy(what);
+
+ std::sort(from_copy.begin(), from_copy.end());
+ std::sort(what_copy.begin(), what_copy.end());
+
+ FunctionalGroupIDs no_same;
+ std::set_difference(from_copy.begin(),
+ from_copy.end(),
+ what_copy.begin(),
+ what_copy.end(),
+ std::back_inserter(no_same));
+
+ no_same.resize(std::distance(no_same.begin(),
+ std::unique(no_same.begin(), no_same.end())));
+
+ return no_same;
+}
+
+FunctionalGroupIDs Merge(const FunctionalGroupIDs& first,
+ const FunctionalGroupIDs& second) {
+ LOG4CXX_INFO(logger_, "Merge groups");
+ FunctionalGroupIDs first_copy(first);
+ FunctionalGroupIDs second_copy(second);
+
+ std::sort(first_copy.begin(), first_copy.end());
+ std::sort(second_copy.begin(), second_copy.end());
+
+ FunctionalGroupIDs merged;
+ std::set_union(first_copy.begin(),
+ first_copy.end(),
+ second_copy.begin(),
+ second_copy.end(),
+ std::back_inserter(merged));
+
+ merged.resize(
+ std::distance(merged.begin(), std::unique(merged.begin(), merged.end())));
+
+ return merged;
+}
+
+FunctionalGroupIDs FindSame(const FunctionalGroupIDs& first,
+ const FunctionalGroupIDs& second) {
+ LOG4CXX_INFO(logger_, "Find same groups");
+ FunctionalGroupIDs first_copy(first);
+ FunctionalGroupIDs second_copy(second);
+
+ std::sort(first_copy.begin(), first_copy.end());
+ std::sort(second_copy.begin(), second_copy.end());
+
+ FunctionalGroupIDs same;
+ std::set_intersection(first_copy.begin(),
+ first_copy.end(),
+ second_copy.begin(),
+ second_copy.end(),
+ std::back_inserter(same));
+
+ same.resize(
+ std::distance(same.begin(), std::unique(same.begin(), same.end())));
+
+ return same;
+}
+
+bool UnwrapAppPolicies(policy_table::ApplicationPolicies& app_policies) {
+ policy_table::ApplicationPolicies::iterator it_default =
+ app_policies.find(kDefaultId);
+ if (app_policies.end() == it_default) {
+ LOG4CXX_ERROR(logger_, "No default application policy found in PTU.");
+ return false;
+ }
+
+ policy_table::ApplicationPolicies::iterator it = app_policies.begin();
+ for (; app_policies.end() != it; ++it) {
+ // Set default policies for app, if there is record like "123":"default"
+ if (kDefaultId.compare((*it).second.get_string()) == 0) {
+ (*it).second = (*it_default).second;
+ it->second.set_to_string(kDefaultId);
+ }
+ }
+
+ return true;
+}
+}
diff --git a/src/components/policy/policy_external/src/policy_manager_impl.cc b/src/components/policy/policy_external/src/policy_manager_impl.cc
new file mode 100644
index 0000000000..0a774f6b79
--- /dev/null
+++ b/src/components/policy/policy_external/src/policy_manager_impl.cc
@@ -0,0 +1,1883 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "policy/policy_manager_impl.h"
+
+#include <algorithm>
+#include <set>
+#include <queue>
+#include <iterator>
+#include <limits>
+#include <vector>
+#include <functional>
+#include "json/reader.h"
+#include "json/writer.h"
+#include "policy/policy_table.h"
+#include "policy/pt_representation.h"
+#include "policy/policy_helper.h"
+#include "utils/file_system.h"
+#include "utils/logger.h"
+#include "utils/date_time.h"
+#include "policy/cache_manager.h"
+#include "policy/update_status_manager.h"
+#include "config_profile/profile.h"
+#include "utils/make_shared.h"
+
+policy::PolicyManager* CreateManager() {
+ return new policy::PolicyManagerImpl();
+}
+void DeleteManager(policy::PolicyManager* pm) {
+ delete pm;
+}
+namespace {
+
+/**
+ * @brief Extracts group name from group permission structure
+ */
+struct GroupNamesAppender
+ : public std::unary_function<void,
+ const policy::FunctionalGroupPermission&> {
+ GroupNamesAppender(policy_table::Strings& names) : names_(names) {}
+
+ void operator()(const policy::FunctionalGroupPermission& value) {
+ names_.push_back(value.group_name);
+ }
+
+ private:
+ policy_table::Strings& names_;
+};
+
+/**
+ * @brief Updates permission state of input group permission value in case
+ * group name is found within allowed or disallowed groups lists considering
+ * current priorities of consents
+ * Also collects matched groups names to separate collection for futher
+ * processing
+ */
+struct ConsentsUpdater
+ : public std::unary_function<void, policy::FunctionalGroupPermission&> {
+ ConsentsUpdater(const policy::GroupsNames& allowed,
+ const policy::GroupsNames& disallowed,
+ std::vector<policy::FunctionalGroupPermission>&
+ out_external_consent_matches,
+ const policy::ConsentPriorityType prio)
+ : allowed_(allowed)
+ , disallowed_(disallowed)
+ , out_external_consent_matches_(out_external_consent_matches)
+ , prio_(prio) {}
+
+ void operator()(policy::FunctionalGroupPermission& value) {
+ if (helpers::in_range(disallowed_, value.group_name)) {
+ policy::FunctionalGroupPermission external_consent = value;
+ external_consent.state = policy::kGroupDisallowed;
+ out_external_consent_matches_.push_back(external_consent);
+
+ if (IsAllowedToChangedUserConsent(value.state)) {
+ value.state = policy::kGroupDisallowed;
+ }
+ return;
+ }
+
+ if (helpers::in_range(allowed_, value.group_name)) {
+ policy::FunctionalGroupPermission external_consent = value;
+ external_consent.state = policy::kGroupAllowed;
+ out_external_consent_matches_.push_back(external_consent);
+
+ if (IsAllowedToChangedUserConsent(value.state)) {
+ value.state = policy::kGroupAllowed;
+ }
+ }
+ }
+
+ private:
+ bool IsAllowedToChangedUserConsent(
+ policy::GroupConsent current_consent) const {
+ if (policy::GroupConsent::kGroupUndefined == current_consent) {
+ return true;
+ }
+
+ return policy::ConsentPriorityType::kUserConsentPrio != prio_;
+ }
+
+ const policy::GroupsNames& allowed_;
+ const policy::GroupsNames& disallowed_;
+ std::vector<policy::FunctionalGroupPermission>& out_external_consent_matches_;
+ const policy::ConsentPriorityType prio_;
+};
+
+/**
+ * @brief Checks whether ExternalConsent entity status is the same as name of
+ * group
+ * container where entity has been found in. In case of match group is added to
+ * 'disallowed' list, otherwise - to 'allowed' one.
+ * E.g. if entity has "ON" status and is found in
+ * 'disallowed_by_external_consent_entities_on' it will be added to
+ * 'disallowed'. If it has
+ * been found in 'disallowed_by_external_consent_entities_off' than group is
+ * added to
+ * 'allowed' list.
+ */
+struct GroupChecker
+ : std::unary_function<
+ void,
+ policy::GroupsByExternalConsentStatus::mapped_type::value_type> {
+ GroupChecker(const policy::EntityStatus entity_status,
+ policy::GroupsNames& out_allowed,
+ policy::GroupsNames& out_disallowed)
+ : entity_status_(entity_status)
+ , out_allowed_(out_allowed)
+ , out_disallowed_(out_disallowed) {}
+
+ void operator()(
+ const policy::GroupsByExternalConsentStatus::mapped_type::value_type
+ value) {
+ using namespace policy;
+
+ const std::string group_name = value.first;
+
+ if ((value.second && (kStatusOn == entity_status_)) ||
+ (!value.second && (kStatusOff == entity_status_))) {
+ out_disallowed_.insert(group_name);
+ } else {
+ out_allowed_.insert(group_name);
+ }
+ }
+
+ private:
+ const policy::EntityStatus entity_status_;
+ policy::GroupsNames& out_allowed_;
+ policy::GroupsNames& out_disallowed_;
+};
+
+/**
+ * @brief Sorts groups for 'allowed' and 'disallowed' by ExternalConsent
+ * entities statuses.
+ * Wraps GroupChecker logic.
+ */
+struct GroupSorter
+ : std::unary_function<
+ void,
+ const policy::GroupsByExternalConsentStatus::value_type&> {
+ GroupSorter(policy::GroupsNames& out_allowed,
+ policy::GroupsNames& out_disallowed)
+ : out_allowed_(out_allowed), out_disallowed_(out_disallowed) {}
+
+ void operator()(
+ const policy::GroupsByExternalConsentStatus::value_type& value) {
+ GroupChecker checker(value.first.status_, out_allowed_, out_disallowed_);
+ std::for_each(value.second.begin(), value.second.end(), checker);
+ }
+
+ private:
+ policy::GroupsNames& out_allowed_;
+ policy::GroupsNames& out_disallowed_;
+};
+
+} // namespace
+
+namespace policy {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Policy")
+
+PolicyManagerImpl::PolicyManagerImpl()
+ : PolicyManager()
+ , listener_(NULL)
+ , cache_(new CacheManager)
+ , retry_sequence_timeout_(60)
+ , retry_sequence_index_(0)
+ , ignition_check(true)
+ , retry_sequence_url_(0, 0, "") {}
+
+PolicyManagerImpl::PolicyManagerImpl(bool in_memory)
+ : PolicyManager()
+ , listener_(NULL)
+ , cache_(new CacheManager(in_memory))
+ , retry_sequence_timeout_(60)
+ , retry_sequence_index_(0)
+ , ignition_check(true)
+ , retry_sequence_url_(0, 0, "")
+ , wrong_ptu_update_received_(false)
+ , send_on_update_sent_out_(false)
+ , trigger_ptu_(false) {}
+
+void PolicyManagerImpl::set_listener(PolicyListener* listener) {
+ listener_ = listener;
+ update_status_manager_.set_listener(listener);
+}
+
+utils::SharedPtr<policy_table::Table> PolicyManagerImpl::Parse(
+ const BinaryMessage& pt_content) {
+ std::string json(pt_content.begin(), pt_content.end());
+ Json::Value value;
+ Json::Reader reader;
+ if (reader.parse(json.c_str(), value)) {
+ return new policy_table::Table(&value);
+ } else {
+ return utils::SharedPtr<policy_table::Table>();
+ }
+}
+
+void PolicyManagerImpl::CheckTriggers() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const bool exceed_ignition_cycles = ExceededIgnitionCycles();
+ const bool exceed_days = ExceededDays();
+
+ LOG4CXX_DEBUG(
+ logger_,
+ "\nDays exceeded: " << std::boolalpha << exceed_days
+ << "\nIgnition cycles exceeded: " << std::boolalpha
+ << exceed_ignition_cycles);
+
+ if (exceed_ignition_cycles || exceed_days) {
+ update_status_manager_.ScheduleUpdate();
+ }
+}
+
+std::string PolicyManagerImpl::GetLockScreenIconUrl() const {
+ return cache_->GetLockScreenIconUrl();
+}
+
+bool PolicyManagerImpl::LoadPT(const std::string& file,
+ const BinaryMessage& pt_content) {
+ LOG4CXX_INFO(logger_, "LoadPT of size " << pt_content.size());
+
+ // Parse message into table struct
+ utils::SharedPtr<policy_table::Table> pt_update = Parse(pt_content);
+ if (!pt_update) {
+ LOG4CXX_WARN(logger_, "Parsed table pointer is NULL.");
+ update_status_manager_.OnWrongUpdateReceived();
+ return false;
+ }
+
+ file_system::DeleteFile(file);
+
+ if (!IsPTValid(pt_update, policy_table::PT_UPDATE)) {
+ wrong_ptu_update_received_ = true;
+ update_status_manager_.OnWrongUpdateReceived();
+ return false;
+ }
+
+ update_status_manager_.OnValidUpdateReceived();
+ cache_->SaveUpdateRequired(false);
+
+ {
+ sync_primitives::AutoLock lock(apps_registration_lock_);
+
+ // Get current DB data, since it could be updated during awaiting of PTU
+ utils::SharedPtr<policy_table::Table> policy_table_snapshot =
+ cache_->GenerateSnapshot();
+ if (!policy_table_snapshot) {
+ LOG4CXX_ERROR(logger_, "Failed to create snapshot of policy table");
+ return false;
+ }
+
+ // Checking of difference between PTU and current policy state
+ // Must to be done before PTU applying since it is possible, that functional
+ // groups, which had been present before are absent in PTU and will be
+ // removed after update. So in case of revoked groups system has to know
+ // names and ids of revoked groups before they will be removed.
+ CheckAppPolicyResults results =
+ CheckPermissionsChanges(pt_update, policy_table_snapshot);
+
+ // Replace current data with updated
+ if (!cache_->ApplyUpdate(*pt_update)) {
+ LOG4CXX_WARN(logger_, "Unsuccessful save of updated policy table.");
+ return false;
+ }
+
+ ExternalConsentStatus status = cache_->GetExternalConsentStatus();
+ GroupsByExternalConsentStatus groups_by_status =
+ cache_->GetGroupsWithSameEntities(status);
+
+ ProcessExternalConsentStatusUpdate(
+ groups_by_status, ConsentProcessingPolicy::kExternalConsentBased);
+
+ ProcessAppPolicyCheckResults(
+ results, pt_update->policy_table.app_policies_section.apps);
+
+ listener_->OnCertificateUpdated(
+ *(pt_update->policy_table.module_config.certificate));
+
+ std::map<std::string, StringArray> app_hmi_types;
+ cache_->GetHMIAppTypeAfterUpdate(app_hmi_types);
+ if (!app_hmi_types.empty()) {
+ LOG4CXX_INFO(logger_, "app_hmi_types is full calling OnUpdateHMIAppType");
+ listener_->OnUpdateHMIAppType(app_hmi_types);
+ } else {
+ LOG4CXX_INFO(logger_, "app_hmi_types empty");
+ }
+ }
+
+ // If there was a user request for policy table update, it should be started
+ // right after current update is finished
+ if (update_status_manager_.IsUpdateRequired()) {
+ StartPTExchange();
+ return true;
+ }
+
+ RefreshRetrySequence();
+ return true;
+}
+
+CheckAppPolicyResults PolicyManagerImpl::CheckPermissionsChanges(
+ const utils::SharedPtr<policy_table::Table> pt_update,
+ const utils::SharedPtr<policy_table::Table> snapshot) {
+ LOG4CXX_INFO(logger_, "Checking incoming permissions.");
+
+ // Replace predefined policies with its actual setting, e.g. "123":"default"
+ // to actual values of default section
+ UnwrapAppPolicies(pt_update->policy_table.app_policies_section.apps);
+
+ CheckAppPolicyResults out_results;
+ std::for_each(pt_update->policy_table.app_policies_section.apps.begin(),
+ pt_update->policy_table.app_policies_section.apps.end(),
+ CheckAppPolicy(this, pt_update, snapshot, out_results));
+
+ return out_results;
+}
+
+void PolicyManagerImpl::ProcessAppPolicyCheckResults(
+ const CheckAppPolicyResults& results,
+ const policy_table::ApplicationPolicies& app_policies) {
+ CheckAppPolicyResults::const_iterator it_results = results.begin();
+
+ for (; results.end() != it_results; ++it_results) {
+ const policy_table::ApplicationPolicies::const_iterator app_policy =
+ app_policies.find(it_results->first);
+
+ if (app_policies.end() == app_policy) {
+ continue;
+ }
+
+ if (IsPredefinedApp(*app_policy)) {
+ continue;
+ }
+
+ switch (it_results->second) {
+ case RESULT_NO_CHANGES:
+ continue;
+ case RESULT_APP_REVOKED:
+ NotifySystem(*app_policy);
+ continue;
+ case RESULT_NICKNAME_MISMATCH:
+ NotifySystem(*app_policy);
+ continue;
+ case RESULT_CONSENT_NEEDED:
+ case RESULT_PERMISSIONS_REVOKED_AND_CONSENT_NEEDED: {
+ // Post-check after ExternalConsent consent changes
+ const std::string policy_app_id = app_policy->first;
+ if (!IsConsentNeeded(policy_app_id)) {
+ sync_primitives::AutoLock lock(app_permissions_diff_lock_);
+
+ PendingPermissions::iterator app_id_diff =
+ app_permissions_diff_.find(policy_app_id);
+
+ if (app_permissions_diff_.end() != app_id_diff) {
+ app_id_diff->second.appPermissionsConsentNeeded = false;
+ }
+ }
+ } break;
+ case RESULT_CONSENT_NOT_REQIURED:
+ case RESULT_PERMISSIONS_REVOKED:
+ case RESULT_REQUEST_TYPE_CHANGED:
+ break;
+ default:
+ continue;
+ }
+ NotifySystem(*app_policy);
+ SendPermissionsToApp(*app_policy);
+ }
+}
+
+void PolicyManagerImpl::PrepareNotificationData(
+ const policy_table::FunctionalGroupings& groups,
+ const policy_table::Strings& group_names,
+ const std::vector<FunctionalGroupPermission>& group_permission,
+ Permissions& notification_data) {
+ LOG4CXX_INFO(logger_, "Preparing data for notification.");
+ ProcessFunctionalGroup processor(groups, group_permission, notification_data);
+ std::for_each(group_names.begin(), group_names.end(), processor);
+}
+
+std::string PolicyManagerImpl::GetUpdateUrl(int service_type) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ EndpointUrls urls;
+ GetUpdateUrls(service_type, urls);
+
+ std::string url;
+ if (!urls.empty()) {
+ static uint32_t index = 0;
+
+ if (index >= urls.size()) {
+ index = 0;
+ }
+ url = urls[index].url.empty() ? "" : urls[index].url[0];
+
+ ++index;
+ } else {
+ LOG4CXX_ERROR(logger_, "The endpoint entry is empty");
+ }
+ return url;
+}
+
+void PolicyManagerImpl::GetUpdateUrls(const std::string& service_type,
+ EndpointUrls& out_end_points) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ cache_->GetUpdateUrls(service_type, out_end_points);
+}
+void PolicyManagerImpl::GetUpdateUrls(const uint32_t service_type,
+ EndpointUrls& out_end_points) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ cache_->GetUpdateUrls(service_type, out_end_points);
+}
+
+void PolicyManagerImpl::RequestPTUpdate() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::SharedPtr<policy_table::Table> policy_table_snapshot =
+ cache_->GenerateSnapshot();
+ if (!policy_table_snapshot) {
+ LOG4CXX_ERROR(logger_, "Failed to create snapshot of policy table");
+ return;
+ }
+
+ if (IsPTValid(policy_table_snapshot, policy_table::PT_SNAPSHOT)) {
+ Json::Value value = policy_table_snapshot->ToJsonValue();
+ Json::FastWriter writer;
+ std::string message_string = writer.write(value);
+
+ LOG4CXX_DEBUG(logger_, "Snapshot contents is : " << message_string);
+
+ BinaryMessage update(message_string.begin(), message_string.end());
+
+ listener_->OnSnapshotCreated(
+ update, RetrySequenceDelaysSeconds(), TimeoutExchangeMSec());
+ } else {
+ LOG4CXX_ERROR(logger_, "Invalid Policy table snapshot - PTUpdate failed");
+ }
+}
+
+void PolicyManagerImpl::StartPTExchange() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (ignition_check) {
+ CheckTriggers();
+ ignition_check = false;
+ }
+
+ if (update_status_manager_.IsAppsSearchInProgress() &&
+ update_status_manager_.IsUpdateRequired()) {
+ LOG4CXX_INFO(logger_,
+ "Starting exchange skipped, since applications "
+ "search is in progress.");
+ return;
+ }
+
+ if (update_status_manager_.IsUpdatePending()) {
+ if (trigger_ptu_) {
+ update_status_manager_.ScheduleUpdate();
+ }
+ LOG4CXX_INFO(logger_,
+ "Starting exchange skipped, since another exchange "
+ "is in progress.");
+ return;
+ }
+ LOG4CXX_INFO(logger_, "Policy want to call RequestPTUpdate");
+ if (listener_ && listener_->CanUpdate()) {
+ LOG4CXX_INFO(logger_, "Listener CanUpdate");
+ if (update_status_manager_.IsUpdateRequired()) {
+ LOG4CXX_INFO(logger_, "IsUpdateRequired");
+ RequestPTUpdate();
+ }
+ }
+}
+
+void PolicyManagerImpl::OnAppsSearchStarted() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ update_status_manager_.OnAppsSearchStarted();
+}
+
+void PolicyManagerImpl::OnAppsSearchCompleted(const bool trigger_ptu) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ update_status_manager_.OnAppsSearchCompleted();
+
+ trigger_ptu_ = trigger_ptu;
+
+ if (update_status_manager_.IsUpdateRequired()) {
+ StartPTExchange();
+ }
+}
+
+const std::vector<std::string> PolicyManagerImpl::GetAppRequestTypes(
+ const std::string policy_app_id) const {
+ std::vector<std::string> request_types;
+ if (kDeviceDisallowed ==
+ cache_->GetDeviceConsent(GetCurrentDeviceId(policy_app_id))) {
+ cache_->GetAppRequestTypes(kPreDataConsentId, request_types);
+ } else {
+ cache_->GetAppRequestTypes(policy_app_id, request_types);
+ }
+ return request_types;
+}
+
+const VehicleInfo PolicyManagerImpl::GetVehicleInfo() const {
+ return cache_->GetVehicleInfo();
+}
+
+void PolicyManagerImpl::CheckPermissions(const PTString& app_id,
+ const PTString& hmi_level,
+ const PTString& rpc,
+ const RPCParams& rpc_params,
+ CheckPermissionResult& result) {
+ LOG4CXX_INFO(logger_,
+ "CheckPermissions for " << app_id << " and rpc " << rpc
+ << " for " << hmi_level << " level.");
+
+ const std::string device_id = GetCurrentDeviceId(app_id);
+
+ Permissions rpc_permissions;
+
+ // Check, if there are calculated permission present in cache
+ if (!cache_->IsPermissionsCalculated(device_id, app_id, rpc_permissions)) {
+ LOG4CXX_DEBUG(logger_,
+ "IsPermissionsCalculated for device: "
+ << device_id << " and app: " << app_id
+ << " returns false");
+ // Get actual application group permission according to user consents
+ std::vector<FunctionalGroupPermission> app_group_permissions;
+ GetPermissionsForApp(device_id, app_id, app_group_permissions);
+
+ // Fill struct with known groups RPCs
+ policy_table::FunctionalGroupings functional_groupings;
+ cache_->GetFunctionalGroupings(functional_groupings);
+
+ policy_table::Strings app_groups = GetGroupsNames(app_group_permissions);
+
+ // Undefined groups (without user consent) disallowed by default, since
+ // OnPermissionsChange notification has no "undefined" section
+ // For RPC permission checking undefinded group will be treated as separate
+ // type
+ ProcessFunctionalGroup processor(functional_groupings,
+ app_group_permissions,
+ rpc_permissions,
+ GroupConsent::kGroupUndefined);
+ std::for_each(app_groups.begin(), app_groups.end(), processor);
+
+ cache_->AddCalculatedPermissions(device_id, app_id, rpc_permissions);
+ } else {
+ LOG4CXX_DEBUG(logger_,
+ "IsPermissionsCalculated for device: "
+ << device_id << " and app: " << app_id
+ << " returns true");
+ }
+
+ const bool known_rpc = rpc_permissions.end() != rpc_permissions.find(rpc);
+ LOG4CXX_INFO(logger_, "Is known rpc " << known_rpc);
+ if (!known_rpc) {
+ // RPC not found in list == disallowed by backend
+ result.hmi_level_permitted = kRpcDisallowed;
+ return;
+ }
+
+ // Check HMI level
+ if (rpc_permissions[rpc].hmi_permissions[kAllowedKey].end() !=
+ rpc_permissions[rpc].hmi_permissions[kAllowedKey].find(hmi_level)) {
+ // RPC found in allowed == allowed by backend and user
+ result.hmi_level_permitted = kRpcAllowed;
+ } else if (rpc_permissions[rpc].hmi_permissions[kUndefinedKey].end() !=
+ rpc_permissions[rpc].hmi_permissions[kUndefinedKey].find(
+ hmi_level)) {
+ // RPC found in undefined == allowed by backend, but not consented yet by
+ // user
+ result.hmi_level_permitted = kRpcDisallowed;
+ } else if (rpc_permissions[rpc].hmi_permissions[kUserDisallowedKey].end() !=
+ rpc_permissions[rpc].hmi_permissions[kUserDisallowedKey].find(
+ hmi_level)) {
+ // RPC found in allowed == allowed by backend, but disallowed by user
+ result.hmi_level_permitted = kRpcUserDisallowed;
+ } else {
+ LOG4CXX_DEBUG(logger_,
+ "HMI level " << hmi_level << " wasn't found "
+ << " for rpc " << rpc << " and appID "
+ << app_id);
+ return;
+ }
+
+ if (kRpcAllowed != result.hmi_level_permitted) {
+ LOG4CXX_DEBUG(logger_, "RPC is not allowed. Stop parameters processing.");
+ result.list_of_allowed_params =
+ rpc_permissions[rpc].parameter_permissions[kAllowedKey];
+
+ result.list_of_disallowed_params =
+ rpc_permissions[rpc].parameter_permissions[kUserDisallowedKey];
+
+ result.list_of_undefined_params =
+ rpc_permissions[rpc].parameter_permissions[kUndefinedKey];
+ return;
+ }
+
+ // Considered that items disallowed by user take priority over system (policy)
+ // permissions, so that flag is processed first
+ if (rpc_permissions[rpc]
+ .parameter_permissions.any_parameter_disallowed_by_user) {
+ LOG4CXX_DEBUG(logger_, "All parameters are disallowed by user.");
+ result.list_of_disallowed_params = rpc_params;
+ result.hmi_level_permitted = kRpcUserDisallowed;
+ return;
+ }
+
+ if (rpc_permissions[rpc]
+ .parameter_permissions.any_parameter_disallowed_by_policy) {
+ LOG4CXX_DEBUG(logger_, "All parameters are disallowed by policy.");
+ result.list_of_undefined_params = rpc_params;
+ result.hmi_level_permitted = kRpcDisallowed;
+ return;
+ }
+
+ if (rpc_permissions[rpc].parameter_permissions.any_parameter_allowed) {
+ LOG4CXX_DEBUG(logger_, "All parameters are allowed.");
+ result.list_of_allowed_params = rpc_params;
+ return;
+ }
+
+ result.list_of_allowed_params =
+ rpc_permissions[rpc].parameter_permissions[kAllowedKey];
+
+ result.list_of_disallowed_params =
+ rpc_permissions[rpc].parameter_permissions[kUserDisallowedKey];
+
+ result.list_of_undefined_params =
+ rpc_permissions[rpc].parameter_permissions[kUndefinedKey];
+
+ // In case of some parameters of RPC are missing in current policy table
+ // they will be considered as disallowed by policy itself, not by user.
+ // Undefined parameters contain parameters present in policy table, but which
+ // have not been allowed or disallowed explicitly by user, so missing params
+ // are being added to undefined.
+ RPCParams::const_iterator parameter = rpc_params.begin();
+ RPCParams::const_iterator end = rpc_params.end();
+ for (; end != parameter; ++parameter) {
+ if (!result.HasParameter(*parameter)) {
+ LOG4CXX_DEBUG(logger_,
+ "Parameter " << *parameter << " is unknown."
+ " Adding to undefined list.");
+ result.list_of_undefined_params.insert(*parameter);
+ }
+ }
+
+ if (result.DisallowedInclude(rpc_params)) {
+ LOG4CXX_DEBUG(logger_, "All parameters are disallowed.");
+ result.hmi_level_permitted = kRpcUserDisallowed;
+ } else if (!result.IsAnyAllowed(rpc_params)) {
+ LOG4CXX_DEBUG(logger_, "There are no parameters allowed.");
+ result.hmi_level_permitted = kRpcDisallowed;
+ }
+
+ if (cache_->IsApplicationRevoked(app_id)) {
+ // SDL must be able to notify mobile side with its status after app has
+ // been revoked by backend
+ if ("OnHMIStatus" == rpc && "NONE" == hmi_level) {
+ result.hmi_level_permitted = kRpcAllowed;
+ } else {
+ result.hmi_level_permitted = kRpcDisallowed;
+ }
+ return;
+ }
+}
+
+bool PolicyManagerImpl::ResetUserConsent() {
+ bool result = true;
+ result = cache_->ResetUserConsent();
+
+ return result;
+}
+
+policy_table::Strings PolicyManagerImpl::GetGroupsNames(
+ const std::vector<FunctionalGroupPermission>& app_group_permissions) const {
+ policy_table::Strings app_groups;
+ GroupNamesAppender appender(app_groups);
+ std::for_each(
+ app_group_permissions.begin(), app_group_permissions.end(), appender);
+
+ return app_groups;
+}
+
+void PolicyManagerImpl::SendNotificationOnPermissionsUpdated(
+ const std::string& application_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const std::string device_id = GetCurrentDeviceId(application_id);
+ if (device_id.empty()) {
+ LOG4CXX_WARN(logger_,
+ "Couldn't find device info for application id "
+ "'" << application_id << "'");
+ return;
+ }
+
+ std::vector<FunctionalGroupPermission> app_group_permissions;
+ GetPermissionsForApp(device_id, application_id, app_group_permissions);
+
+ policy_table::FunctionalGroupings functional_groupings;
+ cache_->GetFunctionalGroupings(functional_groupings);
+
+ policy_table::Strings app_groups = GetGroupsNames(app_group_permissions);
+
+ Permissions notification_data;
+ PrepareNotificationData(functional_groupings,
+ app_groups,
+ app_group_permissions,
+ notification_data);
+
+ LOG4CXX_INFO(logger_,
+ "Send notification for application_id:" << application_id);
+
+ std::string default_hmi;
+ GetDefaultHmi(application_id, &default_hmi);
+
+ listener()->OnPermissionsUpdated(
+ application_id, notification_data, default_hmi);
+}
+
+bool PolicyManagerImpl::CleanupUnpairedDevices() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return cache_->CleanupUnpairedDevices();
+}
+
+DeviceConsent PolicyManagerImpl::GetUserConsentForDevice(
+ const std::string& device_id) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return cache_->GetDeviceConsent(device_id);
+}
+
+void PolicyManagerImpl::SetUserConsentForDevice(const std::string& device_id,
+ const bool is_allowed) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Device :" << device_id);
+ cache_->SetDeviceConsent(device_id, is_allowed);
+ if (listener_) {
+ listener_->OnDeviceConsentChanged(device_id, is_allowed);
+ } else {
+ LOG4CXX_WARN(logger_,
+ "Event listener is not initialized. "
+ "Can't call OnDeviceConsentChanged");
+ }
+ if (is_allowed) {
+ update_status_manager_.OnDeviceConsented();
+ }
+ StartPTExchange();
+}
+
+bool PolicyManagerImpl::ReactOnUserDevConsentForApp(
+ const std::string& app_id, const bool is_device_allowed) {
+ std::vector<std::string> current_request_types = GetAppRequestTypes(app_id);
+ std::string current_priority, new_priority;
+ GetPriority(app_id, &current_priority);
+
+ bool result = cache_->ReactOnUserDevConsentForApp(app_id, is_device_allowed);
+
+ std::vector<std::string> new_request_types = GetAppRequestTypes(app_id);
+ GetPriority(app_id, &new_priority);
+ std::sort(current_request_types.begin(), current_request_types.end());
+ std::sort(new_request_types.begin(), new_request_types.end());
+
+ std::vector<std::string> diff;
+ std::set_symmetric_difference(current_request_types.begin(),
+ current_request_types.end(),
+ new_request_types.begin(),
+ new_request_types.end(),
+ std::back_inserter(diff));
+
+ AppPermissions permissions(app_id);
+
+ if (!diff.empty()) {
+ permissions.requestType = new_request_types;
+ permissions.requestTypeChanged = true;
+ }
+
+ if ((!current_priority.empty()) && (!new_priority.empty()) &&
+ (current_priority != new_priority)) {
+ permissions.priority = new_priority;
+ }
+
+ if (permissions.requestTypeChanged || (!permissions.priority.empty())) {
+ listener_->SendOnAppPermissionsChanged(permissions, app_id);
+ }
+ return result;
+}
+
+bool PolicyManagerImpl::GetInitialAppData(const std::string& application_id,
+ StringArray* nicknames,
+ StringArray* app_hmi_types) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const bool result = nicknames && app_hmi_types;
+ if (result) {
+ cache_->GetInitialAppData(application_id, *nicknames, *app_hmi_types);
+ }
+ return result;
+}
+
+void PolicyManagerImpl::AddDevice(const std::string& device_id,
+ const std::string& connection_type) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Device: " << device_id);
+ if (!cache_->AddDevice(device_id, connection_type)) {
+ LOG4CXX_WARN(logger_, "Can't add device.");
+ }
+}
+
+void PolicyManagerImpl::SetDeviceInfo(const std::string& device_id,
+ const DeviceInfo& device_info) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Device :" << device_id);
+ if (!cache_->SetDeviceData(device_id,
+ device_info.hardware,
+ device_info.firmware_rev,
+ device_info.os,
+ device_info.os_ver,
+ device_info.carrier,
+ device_info.max_number_rfcom_ports,
+ device_info.connection_type)) {
+ LOG4CXX_WARN(logger_, "Can't set device data.");
+ }
+}
+
+PermissionConsent PolicyManagerImpl::EnsureCorrectPermissionConsent(
+ const PermissionConsent& permissions_to_check) {
+ std::vector<FunctionalGroupPermission> current_user_consents;
+ GetUserConsentForApp(permissions_to_check.device_id,
+ permissions_to_check.policy_app_id,
+ current_user_consents);
+
+ PermissionConsent permissions_to_set;
+ permissions_to_set.device_id = permissions_to_check.device_id;
+ permissions_to_set.policy_app_id = permissions_to_check.policy_app_id;
+ permissions_to_set.consent_source = permissions_to_check.consent_source;
+
+ std::vector<FunctionalGroupPermission>::const_iterator it =
+ permissions_to_check.group_permissions.begin();
+ std::vector<FunctionalGroupPermission>::const_iterator it_end =
+ permissions_to_check.group_permissions.end();
+
+ for (; it != it_end; ++it) {
+ std::vector<FunctionalGroupPermission>::const_iterator it_curr =
+ current_user_consents.begin();
+ std::vector<FunctionalGroupPermission>::const_iterator it_curr_end =
+ current_user_consents.end();
+
+ for (; it_curr != it_curr_end; ++it_curr) {
+ if (it->group_alias == it_curr->group_alias &&
+ it->group_id == it_curr->group_id) {
+ permissions_to_set.group_permissions.push_back(*it);
+ }
+ }
+ }
+
+ return permissions_to_set;
+}
+
+void PolicyManagerImpl::CheckPendingPermissionsChanges(
+ const std::string& policy_app_id,
+ const std::vector<FunctionalGroupPermission>& current_permissions) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(app_permissions_diff_lock_);
+ PendingPermissions::iterator it_pending =
+ app_permissions_diff_.find(policy_app_id);
+ if (app_permissions_diff_.end() == it_pending) {
+ LOG4CXX_WARN(
+ logger_,
+ "No pending permissions had been found for appID: " << policy_app_id);
+ return;
+ }
+
+ LOG4CXX_DEBUG(
+ logger_,
+ "Pending permissions had been found for appID: " << policy_app_id);
+
+ // Change appPermissionsConsentNeeded depending on unconsented groups
+ // presence
+ std::vector<policy::FunctionalGroupPermission>::const_iterator it_groups =
+ current_permissions.begin();
+ std::vector<policy::FunctionalGroupPermission>::const_iterator it_end_groups =
+ current_permissions.end();
+
+ for (; it_groups != it_end_groups; ++it_groups) {
+ if (policy::kGroupUndefined == it_groups->state) {
+ LOG4CXX_DEBUG(
+ logger_,
+ "Unconsented groups still present for appID: " << policy_app_id);
+ it_pending->second.appPermissionsConsentNeeded = true;
+ return;
+ }
+ }
+
+ LOG4CXX_DEBUG(
+ logger_,
+ "Unconsented groups not present anymore for appID: " << policy_app_id);
+ it_pending->second.appPermissionsConsentNeeded = false;
+ return;
+}
+
+void PolicyManagerImpl::NotifyPermissionsChanges(
+ const std::string& policy_app_id,
+ const std::vector<FunctionalGroupPermission>& app_group_permissions) {
+ // Get current functional groups from DB with RPC permissions
+ policy_table::FunctionalGroupings functional_groups;
+ cache_->GetFunctionalGroupings(functional_groups);
+
+ // Get list of groups assigned to application
+ policy_table::Strings app_groups = GetGroupsNames(app_group_permissions);
+
+ // Fill notification data according to group permissions
+ Permissions notification_data;
+ PrepareNotificationData(
+ functional_groups, app_groups, app_group_permissions, notification_data);
+
+ listener()->OnPermissionsUpdated(policy_app_id, notification_data);
+}
+
+void PolicyManagerImpl::SetUserConsentForApp(
+ const PermissionConsent& permissions, const NotificationMode mode) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (permissions.group_permissions.empty()) {
+ LOG4CXX_DEBUG(logger_, "Permissions list is empty, skipping update.");
+ return;
+ }
+
+ cache_->ResetCalculatedPermissions();
+ PermissionConsent verified_permissions =
+ EnsureCorrectPermissionConsent(permissions);
+
+ bool app_permissions_changed = false;
+ if (!cache_->SetUserPermissionsForApp(verified_permissions,
+ &app_permissions_changed)) {
+ LOG4CXX_WARN(logger_, "Can't set user permissions for application.");
+ return;
+ }
+
+ if (kSilentMode == mode) {
+ LOG4CXX_WARN(logger_,
+ "Silent mode is enabled. Application won't be informed.");
+ return;
+ }
+
+ if (!app_permissions_changed) {
+ LOG4CXX_WARN(logger_,
+ "Application already has same consents. "
+ "Notificaton won't be sent.");
+ return;
+ }
+
+ std::vector<FunctionalGroupPermission> updated_app_group_permissons;
+ GetPermissionsForApp(verified_permissions.device_id,
+ verified_permissions.policy_app_id,
+ updated_app_group_permissons);
+
+ CheckPendingPermissionsChanges(verified_permissions.policy_app_id,
+ updated_app_group_permissons);
+
+ NotifyPermissionsChanges(verified_permissions.policy_app_id,
+ updated_app_group_permissons);
+}
+
+bool PolicyManagerImpl::GetDefaultHmi(const std::string& policy_app_id,
+ std::string* default_hmi) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const std::string device_id = GetCurrentDeviceId(policy_app_id);
+ DeviceConsent device_consent = GetUserConsentForDevice(device_id);
+ const std::string app_id = policy::kDeviceAllowed != device_consent
+ ? kPreDataConsentId
+ : policy_app_id;
+ return cache_->GetDefaultHMI(app_id, *default_hmi);
+}
+
+bool PolicyManagerImpl::GetPriority(const std::string& policy_app_id,
+ std::string* priority) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (!priority) {
+ LOG4CXX_WARN(logger_, "Input priority parameter is null.");
+ return false;
+ }
+
+ return cache_->GetPriority(policy_app_id, *priority);
+}
+
+std::vector<UserFriendlyMessage> PolicyManagerImpl::GetUserFriendlyMessages(
+ const std::vector<std::string>& message_code,
+ const std::string& language,
+ const std::string& active_hmi_language) {
+ return cache_->GetUserFriendlyMsg(
+ message_code, language, active_hmi_language);
+}
+
+void PolicyManagerImpl::GetUserConsentForApp(
+ const std::string& device_id,
+ const std::string& policy_app_id,
+ std::vector<FunctionalGroupPermission>& permissions) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ FunctionalIdType group_types;
+ if (!cache_->GetPermissionsForApp(device_id, policy_app_id, group_types)) {
+ LOG4CXX_WARN(logger_,
+ "Can't get user permissions for app " << policy_app_id);
+ return;
+ }
+
+ // Functional groups w/o alias ("user_consent_prompt") considered as
+ // automatically allowed and it could not be changed by user
+ FunctionalGroupNames group_names;
+ if (!cache_->GetFunctionalGroupNames(group_names)) {
+ LOG4CXX_WARN(logger_, "Can't get functional group names");
+ return;
+ }
+
+ FunctionalGroupNames::const_iterator it = group_names.begin();
+ FunctionalGroupNames::const_iterator it_end = group_names.end();
+ FunctionalGroupIDs auto_allowed_groups;
+ for (; it != it_end; ++it) {
+ if (it->second.first.empty()) {
+ auto_allowed_groups.push_back(it->first);
+ }
+ }
+
+ FunctionalGroupIDs all_groups = group_types[kTypeGeneral];
+ FunctionalGroupIDs preconsented_groups = group_types[kTypePreconsented];
+ FunctionalGroupIDs consent_allowed_groups = group_types[kTypeAllowed];
+ FunctionalGroupIDs consent_disallowed_groups = group_types[kTypeDisallowed];
+ FunctionalGroupIDs default_groups = group_types[kTypeDefault];
+ FunctionalGroupIDs predataconsented_groups =
+ group_types[kTypePreDataConsented];
+ FunctionalGroupIDs device_groups = group_types[kTypeDevice];
+
+ // Sorting groups by consent
+ FunctionalGroupIDs preconsented_wo_auto =
+ ExcludeSame(preconsented_groups, auto_allowed_groups);
+
+ FunctionalGroupIDs preconsented_wo_disallowed_auto =
+ ExcludeSame(preconsented_wo_auto, consent_disallowed_groups);
+
+ FunctionalGroupIDs allowed_groups =
+ Merge(consent_allowed_groups, preconsented_wo_disallowed_auto);
+
+ FunctionalGroupIDs merged_stage_1 =
+ Merge(default_groups, predataconsented_groups);
+
+ FunctionalGroupIDs merged_stage_2 = Merge(merged_stage_1, device_groups);
+
+ FunctionalGroupIDs merged_stage_3 =
+ Merge(merged_stage_2, auto_allowed_groups);
+
+ FunctionalGroupIDs excluded_stage_1 = ExcludeSame(all_groups, merged_stage_3);
+
+ FunctionalGroupIDs excluded_stage_2 =
+ ExcludeSame(excluded_stage_1, consent_disallowed_groups);
+
+ FunctionalGroupIDs undefined_consent =
+ ExcludeSame(excluded_stage_2, allowed_groups);
+
+ // Fill result
+ FillFunctionalGroupPermissions(
+ undefined_consent, group_names, kGroupUndefined, permissions);
+ FillFunctionalGroupPermissions(
+ allowed_groups, group_names, kGroupAllowed, permissions);
+ FillFunctionalGroupPermissions(
+ consent_disallowed_groups, group_names, kGroupDisallowed, permissions);
+}
+
+void PolicyManagerImpl::GetPermissionsForApp(
+ const std::string& device_id,
+ const std::string& policy_app_id,
+ std::vector<FunctionalGroupPermission>& permissions) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ std::string app_id_to_check = policy_app_id;
+
+ if (!cache_->IsApplicationRepresented(policy_app_id)) {
+ LOG4CXX_WARN(logger_,
+ "Application with id " << policy_app_id
+ << " is not found within known apps.");
+ return;
+ }
+
+ bool allowed_by_default = false;
+ if (cache_->IsDefaultPolicy(policy_app_id)) {
+ app_id_to_check = kDefaultId;
+ allowed_by_default = true;
+ } else if (cache_->IsPredataPolicy(policy_app_id) ||
+ policy::kDeviceDisallowed == GetUserConsentForDevice(device_id)) {
+ app_id_to_check = kPreDataConsentId;
+ allowed_by_default = true;
+ }
+
+ FunctionalIdType group_types;
+ if (!cache_->GetPermissionsForApp(device_id, app_id_to_check, group_types)) {
+ LOG4CXX_WARN(logger_,
+ "Can't get user permissions for app " << policy_app_id);
+ return;
+ }
+
+ // Functional groups w/o alias ("user_consent_prompt") considered as
+ // automatically allowed and it could not be changed by user
+ FunctionalGroupNames group_names;
+ if (!cache_->GetFunctionalGroupNames(group_names)) {
+ LOG4CXX_WARN(logger_, "Can't get functional group names");
+ return;
+ }
+
+ // The "default" and "pre_DataConsent" are auto-allowed groups
+ // So, check if application in the one of these mode.
+ if (allowed_by_default) {
+ LOG4CXX_INFO(logger_, "Get auto allowed groups");
+ GroupType type =
+ (kDefaultId == app_id_to_check ? kTypeDefault : kTypePreDataConsented);
+
+ FillFunctionalGroupPermissions(
+ group_types[type], group_names, kGroupAllowed, permissions);
+ } else {
+ // The code bellow allows to process application which
+ // has specific permissions(not default and pre_DataConsent).
+
+ // All groups for specific application
+ FunctionalGroupIDs all_groups = group_types[kTypeGeneral];
+
+ // Groups assigned by the user for specific application
+ FunctionalGroupIDs allowed_groups = group_types[kTypeAllowed];
+
+ // Groups disallowed by the user for specific application
+ FunctionalGroupIDs common_disallowed = group_types[kTypeDisallowed];
+
+ // Groups that allowed by default but can be changed by the user
+ FunctionalGroupIDs preconsented_groups = group_types[kTypePreconsented];
+
+ // Groups which has user consent promt but there is no any consnets now.
+ FunctionalGroupIDs unconsented_groups = group_types[kTypeUnconsented];
+
+ // Pull common groups from allowed and preconsented parts.
+ FunctionalGroupIDs allowed_preconsented =
+ Merge(allowed_groups, preconsented_groups);
+
+ // Get all groups that we suppose are allowed.
+ FunctionalGroupIDs all_allowed = Merge(allowed_preconsented, all_groups);
+
+ // In case when same groups exists in disallowed and allowed tables,
+ // disallowed one have priority over allowed. So we have to remove
+ // all disallowed groups from allowed table.
+ FunctionalGroupIDs common_allowed =
+ ExcludeSame(all_allowed, common_disallowed);
+ FunctionalGroupIDs consent_disallowed =
+ ExcludeSame(unconsented_groups, preconsented_groups);
+
+ // Disallowed groups are contain all directly disallowed,
+ // plus unconsented minus preconsented.
+ FunctionalGroupIDs all_disallowed =
+ Merge(common_disallowed, consent_disallowed);
+
+ // Fill result
+ FillFunctionalGroupPermissions(
+ consent_disallowed, group_names, kGroupUndefined, permissions);
+ FillFunctionalGroupPermissions(
+ common_allowed, group_names, kGroupAllowed, permissions);
+ FillFunctionalGroupPermissions(
+ all_disallowed, group_names, kGroupDisallowed, permissions);
+ }
+ return;
+}
+
+std::string& PolicyManagerImpl::GetCurrentDeviceId(
+ const std::string& policy_app_id) const {
+ LOG4CXX_INFO(logger_, "GetDeviceInfo");
+ last_device_id_ = listener()->OnCurrentDeviceIdUpdateRequired(policy_app_id);
+ return last_device_id_;
+}
+
+void PolicyManagerImpl::SetSystemLanguage(const std::string& language) {
+ cache_->SetSystemLanguage(language);
+}
+
+void PolicyManagerImpl::SetSystemInfo(const std::string& ccpu_version,
+ const std::string& wers_country_code,
+ const std::string& language) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ cache_->SetMetaInfo(ccpu_version, wers_country_code, language);
+}
+
+void PolicyManagerImpl::OnSystemReady() {
+ // Update policy table for the first time with system information
+ if (!cache_->IsMetaInfoPresent()) {
+ listener()->OnSystemInfoUpdateRequired();
+ }
+}
+
+uint32_t PolicyManagerImpl::GetNotificationsNumber(
+ const std::string& priority) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return cache_->GetNotificationsNumber(priority);
+}
+
+bool PolicyManagerImpl::ExceededIgnitionCycles() {
+ return 0 == cache_->IgnitionCyclesBeforeExchange();
+}
+
+bool PolicyManagerImpl::IsPTValid(
+ utils::SharedPtr<policy_table::Table> policy_table,
+ policy_table::PolicyTableType type) const {
+ policy_table->SetPolicyTableType(type);
+ if (!policy_table->is_valid()) {
+ LOG4CXX_ERROR(logger_, "Policy table is not valid.");
+ rpc::ValidationReport report("policy_table");
+ policy_table->ReportErrors(&report);
+ LOG4CXX_DEBUG(logger_, "Errors: " << rpc::PrettyFormat(report));
+ return false;
+ }
+ return true;
+}
+
+const PolicySettings& PolicyManagerImpl::get_settings() const {
+ DCHECK(settings_);
+ return *settings_;
+}
+
+void PolicyManagerImpl::UpdateAppConsentWithExternalConsent(
+ const std::string& device_id,
+ const std::string& application_id,
+ const GroupsNames& allowed_groups,
+ const GroupsNames& disallowed_groups,
+ const ConsentProcessingPolicy processing_policy) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (allowed_groups.empty() && disallowed_groups.empty()) {
+ LOG4CXX_DEBUG(logger_,
+ "Allowed and disallowed groups are empty, skipping update by "
+ "external user consent.");
+ return;
+ }
+
+ std::vector<FunctionalGroupPermission> current_permissions;
+ GetUserConsentForApp(device_id, application_id, current_permissions);
+
+ ConsentPriorityType prio = ConsentPriorityType::kExternalConsentPrio;
+ if (ConsentProcessingPolicy::kTimestampBased == processing_policy) {
+ prio = cache_->GetConsentsPriority(device_id, application_id);
+ }
+
+ std::vector<FunctionalGroupPermission> external_consent_groups_matches;
+ ConsentsUpdater updater(
+ allowed_groups, disallowed_groups, external_consent_groups_matches, prio);
+ std::for_each(
+ current_permissions.begin(), current_permissions.end(), updater);
+
+ const std::string source = "GUI";
+
+ PermissionConsent updated_user_permissions;
+ updated_user_permissions.group_permissions = current_permissions;
+ updated_user_permissions.device_id = device_id;
+ updated_user_permissions.policy_app_id = application_id;
+ updated_user_permissions.consent_source = source;
+
+ // Need to check to which app to send notification since maybe app registered
+ // from different device
+ SetUserConsentForApp(updated_user_permissions,
+ PolicyManager::kNotifyApplicationMode);
+
+ PermissionConsent updated_external_consent_permissions;
+ updated_external_consent_permissions.group_permissions =
+ external_consent_groups_matches;
+ updated_external_consent_permissions.device_id = device_id;
+ updated_external_consent_permissions.policy_app_id = application_id;
+ updated_user_permissions.consent_source = source;
+
+ cache_->SetExternalConsentForApp(updated_external_consent_permissions);
+}
+
+void PolicyManagerImpl::NotifySystem(
+ const PolicyManagerImpl::AppPoliciesValueType& app_policy) const {
+ listener()->OnPendingPermissionChange(app_policy.first);
+}
+
+void PolicyManagerImpl::SendPermissionsToApp(
+ const PolicyManagerImpl::AppPoliciesValueType& app_policy) {
+ const std::string app_id = app_policy.first;
+
+ const std::string device_id = GetCurrentDeviceId(app_id);
+ if (device_id.empty()) {
+ LOG4CXX_WARN(logger_,
+ "Couldn't find device info for application id: " << app_id);
+ return;
+ }
+ std::vector<FunctionalGroupPermission> group_permissons;
+ GetPermissionsForApp(device_id, app_id, group_permissons);
+
+ Permissions notification_data;
+
+ // Need to get rid of this call
+ utils::SharedPtr<policy_table::Table> policy_table_snapshot =
+ cache_->GenerateSnapshot();
+
+ PrepareNotificationData(
+ policy_table_snapshot->policy_table.functional_groupings,
+ app_policy.second.groups,
+ group_permissons,
+ notification_data);
+
+ LOG4CXX_INFO(logger_, "Send notification for application_id: " << app_id);
+ listener()->OnPermissionsUpdated(
+ app_id,
+ notification_data,
+ policy_table::EnumToJsonString(app_policy.second.default_hmi));
+}
+
+void PolicyManagerImpl::ProcessExternalConsentStatusUpdate(
+ const GroupsByExternalConsentStatus& groups_by_status,
+ const ConsentProcessingPolicy processing_policy) {
+ GroupsNames allowed_groups;
+ GroupsNames disallowed_groups;
+ CalculateGroupsConsentFromExternalConsent(
+ groups_by_status, allowed_groups, disallowed_groups);
+
+ std::map<std::string, std::string> known_links =
+ cache_->GetKnownLinksFromPT();
+ std::map<std::string, std::string> registered_links;
+ listener_->GetRegisteredLinks(registered_links);
+
+ std::map<std::string, std::string> all_known;
+ std::merge(known_links.begin(),
+ known_links.end(),
+ registered_links.begin(),
+ registered_links.end(),
+ std::inserter(all_known, all_known.begin()));
+
+ std::map<std::string, std::string>::const_iterator it_links =
+ all_known.begin();
+ for (; all_known.end() != it_links; ++it_links) {
+ UpdateAppConsentWithExternalConsent(it_links->first,
+ it_links->second,
+ allowed_groups,
+ disallowed_groups,
+ processing_policy);
+ }
+}
+
+bool ConsentStatusComparatorFunc(const ExternalConsentStatusItem& i1,
+ const ExternalConsentStatusItem& i2) {
+ return (i1.entity_id_ < i2.entity_id_) ||
+ (i1.entity_type_ < i2.entity_type_) || (i1.status_ < i2.status_);
+}
+
+bool PolicyManagerImpl::IsNeedToUpdateExternalConsentStatus(
+ const ExternalConsentStatus& new_status) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ typedef std::vector<ExternalConsentStatusItem> ItemV;
+ const ExternalConsentStatus existing_status =
+ cache_->GetExternalConsentEntities();
+
+ ItemV new_status_v(new_status.begin(), new_status.end());
+ ItemV existing_status_v(existing_status.begin(), existing_status.end());
+
+ ItemV difference_v;
+ difference_v.resize(new_status_v.size() + existing_status_v.size());
+
+ ItemV::iterator ci = difference_v.begin();
+ ci = std::set_difference(new_status_v.begin(),
+ new_status_v.end(),
+ existing_status_v.begin(),
+ existing_status_v.end(),
+ difference_v.begin(),
+ ConsentStatusComparatorFunc);
+ difference_v.resize(ci - difference_v.begin());
+
+ return !difference_v.empty();
+}
+
+bool PolicyManagerImpl::SetExternalConsentStatus(
+ const ExternalConsentStatus& status) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (status.empty()) {
+ LOG4CXX_INFO(logger_, "External consent status is empty, skipping update.");
+ return false;
+ }
+
+ if (!cache_->SetExternalConsentStatus(status)) {
+ LOG4CXX_WARN(logger_, "Can't set external user consent status.");
+ return false;
+ }
+
+ GroupsByExternalConsentStatus groups_by_status =
+ cache_->GetGroupsWithSameEntities(status);
+ ProcessExternalConsentStatusUpdate(
+ groups_by_status, ConsentProcessingPolicy::kExternalConsentBased);
+
+ return true;
+}
+
+ExternalConsentStatus PolicyManagerImpl::GetExternalConsentStatus() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return cache_->GetExternalConsentStatus();
+}
+
+void PolicyManagerImpl::CalculateGroupsConsentFromExternalConsent(
+ const GroupsByExternalConsentStatus& groups_by_external_consent,
+ GroupsNames& out_allowed_groups,
+ GroupsNames& out_disallowed_groups) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ GroupSorter sorter(out_allowed_groups, out_disallowed_groups);
+ std::for_each(groups_by_external_consent.begin(),
+ groups_by_external_consent.end(),
+ sorter);
+
+ GroupsNames filtered_allowed_groups;
+ std::set_difference(
+ out_allowed_groups.begin(),
+ out_allowed_groups.end(),
+ out_disallowed_groups.begin(),
+ out_disallowed_groups.end(),
+ std::inserter(filtered_allowed_groups, filtered_allowed_groups.begin()));
+
+ out_allowed_groups = filtered_allowed_groups;
+}
+
+bool PolicyManagerImpl::ExceededDays() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ TimevalStruct current_time = date_time::DateTime::getCurrentTime();
+ const int kSecondsInDay = 60 * 60 * 24;
+ const int days = current_time.tv_sec / kSecondsInDay;
+
+ DCHECK(std::numeric_limits<uint16_t>::max() >= days);
+
+ if (std::numeric_limits<uint16_t>::max() <= days) {
+ LOG4CXX_WARN(logger_, "The days since epoch exceeds maximum value.");
+ return false;
+ }
+ return 0 == cache_->DaysBeforeExchange(static_cast<uint16_t>(days));
+}
+
+void PolicyManagerImpl::KmsChanged(int kilometers) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (0 == cache_->KilometersBeforeExchange(kilometers)) {
+ LOG4CXX_INFO(logger_, "Enough kilometers passed to send for PT update.");
+ update_status_manager_.ScheduleUpdate();
+ StartPTExchange();
+ PTUpdatedAt(KILOMETERS, kilometers);
+ }
+}
+
+void PolicyManagerImpl::IncrementIgnitionCycles() {
+ cache_->IncrementIgnitionCycles();
+}
+
+std::string PolicyManagerImpl::ForcePTExchange() {
+ update_status_manager_.ScheduleUpdate();
+ StartPTExchange();
+ return update_status_manager_.StringifiedUpdateStatus();
+}
+
+std::string PolicyManagerImpl::ForcePTExchangeAtUserRequest() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ update_status_manager_.ScheduleManualUpdate();
+ StartPTExchange();
+ return update_status_manager_.StringifiedUpdateStatus();
+}
+
+std::string PolicyManagerImpl::GetPolicyTableStatus() const {
+ return update_status_manager_.StringifiedUpdateStatus();
+}
+
+int PolicyManagerImpl::NextRetryTimeout() {
+ sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
+ LOG4CXX_DEBUG(logger_, "Index: " << retry_sequence_index_);
+ int next = 0;
+ if (!retry_sequence_seconds_.empty() &&
+ retry_sequence_index_ < retry_sequence_seconds_.size()) {
+ next = retry_sequence_seconds_[retry_sequence_index_];
+ ++retry_sequence_index_;
+ }
+ return next;
+}
+
+void PolicyManagerImpl::RefreshRetrySequence() {
+ sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
+ retry_sequence_timeout_ = cache_->TimeoutResponse();
+ retry_sequence_seconds_.clear();
+ cache_->SecondsBetweenRetries(retry_sequence_seconds_);
+}
+
+void PolicyManagerImpl::ResetRetrySequence() {
+ sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
+ retry_sequence_index_ = 0;
+ update_status_manager_.OnResetRetrySequence();
+}
+
+uint32_t PolicyManagerImpl::TimeoutExchangeMSec() {
+ return retry_sequence_timeout_;
+}
+
+const std::vector<int> PolicyManagerImpl::RetrySequenceDelaysSeconds() {
+ sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
+ return retry_sequence_seconds_;
+}
+
+void PolicyManagerImpl::OnExceededTimeout() {
+ update_status_manager_.OnUpdateTimeoutOccurs();
+}
+
+void PolicyManagerImpl::OnUpdateStarted() {
+ uint32_t update_timeout = TimeoutExchangeMSec();
+ LOG4CXX_DEBUG(logger_,
+ "Update timeout will be set to (milisec): " << update_timeout);
+ send_on_update_sent_out_ =
+ !wrong_ptu_update_received_ && !update_status_manager_.IsUpdatePending();
+
+ if (send_on_update_sent_out_) {
+ update_status_manager_.OnUpdateSentOut(update_timeout);
+ }
+ cache_->SaveUpdateRequired(true);
+}
+
+void PolicyManagerImpl::PTUpdatedAt(Counters counter, int value) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ cache_->SetCountersPassedForSuccessfulUpdate(counter, value);
+ cache_->ResetIgnitionCycles();
+}
+
+void PolicyManagerImpl::Increment(usage_statistics::GlobalCounterId type) {
+ LOG4CXX_INFO(logger_, "Increment without app id");
+ cache_->Increment(type);
+}
+
+void PolicyManagerImpl::Increment(const std::string& app_id,
+ usage_statistics::AppCounterId type) {
+ LOG4CXX_DEBUG(logger_, "Increment " << app_id << " AppCounter: " << type);
+ cache_->Increment(app_id, type);
+}
+
+void PolicyManagerImpl::Set(const std::string& app_id,
+ usage_statistics::AppInfoId type,
+ const std::string& value) {
+ LOG4CXX_INFO(logger_, "Set " << app_id);
+ cache_->Set(app_id, type, value);
+}
+
+void PolicyManagerImpl::Add(const std::string& app_id,
+ usage_statistics::AppStopwatchId type,
+ int32_t timespan_seconds) {
+ LOG4CXX_INFO(logger_, "Add " << app_id);
+ cache_->Add(app_id, type, timespan_seconds);
+}
+
+bool PolicyManagerImpl::IsApplicationRevoked(const std::string& app_id) const {
+ return cache_->IsApplicationRevoked(app_id);
+}
+
+bool PolicyManagerImpl::IsConsentNeeded(const std::string& app_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const std::string device_id = GetCurrentDeviceId(app_id);
+ int count = cache_->CountUnconsentedGroups(app_id, device_id);
+ LOG4CXX_DEBUG(logger_, "There are: " << count << " unconsented groups.");
+ return count != 0;
+}
+
+void PolicyManagerImpl::SetVINValue(const std::string& value) {
+ cache_->SetVINValue(value);
+}
+
+AppPermissions PolicyManagerImpl::GetAppPermissionsChanges(
+ const std::string& policy_app_id) {
+ PendingPermissions::iterator app_id_diff =
+ app_permissions_diff_.find(policy_app_id);
+
+ AppPermissions permissions(policy_app_id);
+
+ if (app_permissions_diff_.end() != app_id_diff) {
+ permissions = app_id_diff->second;
+ } else {
+ permissions.appPermissionsConsentNeeded = IsConsentNeeded(policy_app_id);
+ permissions.appRevoked = IsApplicationRevoked(policy_app_id);
+ GetPriority(permissions.application_id, &permissions.priority);
+ }
+ return permissions;
+}
+
+void PolicyManagerImpl::RemovePendingPermissionChanges(
+ const std::string& app_id) {
+ app_permissions_diff_.erase(app_id);
+}
+
+bool PolicyManagerImpl::CanAppKeepContext(const std::string& app_id) const {
+ return cache_->CanAppKeepContext(app_id);
+}
+
+bool PolicyManagerImpl::CanAppStealFocus(const std::string& app_id) const {
+ return cache_->CanAppStealFocus(app_id);
+}
+
+void PolicyManagerImpl::MarkUnpairedDevice(const std::string& device_id) {
+ if (!cache_->SetUnpairedDevice(device_id)) {
+ LOG4CXX_DEBUG(logger_, "Could not set unpaired flag for " << device_id);
+ return;
+ }
+ SetUserConsentForDevice(device_id, false);
+}
+
+void PolicyManagerImpl::OnAppRegisteredOnMobile(
+ const std::string& application_id) {
+ StartPTExchange();
+ SendNotificationOnPermissionsUpdated(application_id);
+}
+
+const MetaInfo PolicyManagerImpl::GetMetaInfo() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return cache_->GetMetaInfo();
+}
+
+std::string PolicyManagerImpl::RetrieveCertificate() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return cache_->GetCertificate();
+}
+
+bool PolicyManagerImpl::HasCertificate() const {
+ return !cache_->GetCertificate().empty();
+}
+
+void PolicyManagerImpl::SetDecryptedCertificate(
+ const std::string& certificate) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ cache_->SetDecryptedCertificate(certificate);
+}
+
+AppIdURL PolicyManagerImpl::GetNextUpdateUrl(const EndpointUrls& urls) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ const AppIdURL next_app_url = RetrySequenceUrl(retry_sequence_url_, urls);
+
+ retry_sequence_url_.url_idx_ = next_app_url.second + 1;
+ retry_sequence_url_.app_idx_ = next_app_url.first;
+ retry_sequence_url_.policy_app_id_ = urls[next_app_url.first].app_id;
+
+ return next_app_url;
+}
+
+AppIdURL PolicyManagerImpl::RetrySequenceUrl(const struct RetrySequenceURL& rs,
+ const EndpointUrls& urls) const {
+ uint32_t url_idx = rs.url_idx_;
+ uint32_t app_idx = rs.app_idx_;
+ const std::string& app_id = rs.policy_app_id_;
+
+ if (urls.size() <= app_idx) {
+ // Index of current application doesn't exist any more due to app(s)
+ // unregistration
+ url_idx = 0;
+ app_idx = 0;
+ } else if (urls[app_idx].app_id != app_id) {
+ // Index of current application points to another one due to app(s)
+ // registration/unregistration
+ url_idx = 0;
+ } else if (url_idx >= urls[app_idx].url.size()) {
+ // Index of current application is OK, but all of its URL are sent,
+ // move to the next application
+ url_idx = 0;
+ if (++app_idx >= urls.size()) {
+ app_idx = 0;
+ }
+ }
+ const AppIdURL next_app_url = std::make_pair(app_idx, url_idx);
+
+ return next_app_url;
+}
+
+/**
+ * @brief The CallStatusChange class notify update manager aboun new application
+ */
+class CallStatusChange : public utils::Callable {
+ public:
+ CallStatusChange(UpdateStatusManager& upd_manager,
+ const DeviceConsent& device_consent)
+ : upd_manager_(upd_manager), device_consent_(device_consent) {}
+
+ // Callable interface
+ void operator()() const {
+ upd_manager_.OnNewApplicationAdded(device_consent_);
+ }
+
+ private:
+ UpdateStatusManager& upd_manager_;
+ const DeviceConsent device_consent_;
+};
+
+StatusNotifier PolicyManagerImpl::AddApplication(
+ const std::string& application_id,
+ const rpc::policy_table_interface_base::AppHmiTypes& hmi_types) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const std::string device_id = GetCurrentDeviceId(application_id);
+ DeviceConsent device_consent = GetUserConsentForDevice(device_id);
+ sync_primitives::AutoLock lock(apps_registration_lock_);
+ if (IsNewApplication(application_id)) {
+ AddNewApplication(application_id, device_consent);
+ return utils::MakeShared<CallStatusChange>(update_status_manager_,
+ device_consent);
+ } else {
+ PromoteExistedApplication(application_id, device_consent);
+ if (helpers::in_range(hmi_types, policy_table::AHT_NAVIGATION) &&
+ !HasCertificate()) {
+ LOG4CXX_DEBUG(logger_, "Certificate does not exist, scheduling update.");
+ update_status_manager_.ScheduleUpdate();
+ }
+ return utils::MakeShared<utils::CallNothing>();
+ }
+}
+
+void PolicyManagerImpl::RemoveAppConsentForGroup(
+ const std::string& app_id, const std::string& group_name) {
+ cache_->RemoveAppConsentForGroup(app_id, group_name);
+}
+
+bool PolicyManagerImpl::IsPredataPolicy(
+ const std::string& policy_app_id) const {
+ LOG4CXX_INFO(logger_, "IsPredataApp");
+ return cache_->IsPredataPolicy(policy_app_id);
+}
+
+void PolicyManagerImpl::ProcessExternalConsentStatusForApp(
+ const std::string& application_id,
+ const ConsentProcessingPolicy processing_policy) {
+ ExternalConsentStatus status = cache_->GetExternalConsentStatus();
+ GroupsByExternalConsentStatus groups_by_status =
+ cache_->GetGroupsWithSameEntities(status);
+
+ GroupsNames allowed_groups;
+ GroupsNames disallowed_groups;
+ CalculateGroupsConsentFromExternalConsent(
+ groups_by_status, allowed_groups, disallowed_groups);
+
+ const std::string device_id = GetCurrentDeviceId(application_id);
+ UpdateAppConsentWithExternalConsent(device_id,
+ application_id,
+ allowed_groups,
+ disallowed_groups,
+ processing_policy);
+}
+
+void PolicyManagerImpl::AddNewApplication(const std::string& application_id,
+ DeviceConsent device_consent) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (kDeviceHasNoConsent == device_consent ||
+ kDeviceDisallowed == device_consent) {
+ LOG4CXX_INFO(logger_,
+ "Setting "
+ << policy::kPreDataConsentId
+ << " permissions for application id: " << application_id);
+ cache_->SetPredataPolicy(application_id);
+ } else {
+ LOG4CXX_INFO(logger_,
+ "Setting "
+ << policy::kDefaultId
+ << " permissions for application id: " << application_id);
+ cache_->SetDefaultPolicy(application_id);
+ }
+
+ ProcessExternalConsentStatusForApp(
+ application_id, ConsentProcessingPolicy::kExternalConsentBased);
+}
+
+void PolicyManagerImpl::PromoteExistedApplication(
+ const std::string& application_id, DeviceConsent device_consent) {
+ // If device consent changed to allowed during application being
+ // disconnected, app permissions should be changed also
+ if (kDeviceAllowed == device_consent &&
+ cache_->IsPredataPolicy(application_id)) {
+ cache_->SetDefaultPolicy(application_id);
+ }
+ ProcessExternalConsentStatusForApp(application_id,
+ ConsentProcessingPolicy::kTimestampBased);
+}
+
+bool PolicyManagerImpl::IsNewApplication(
+ const std::string& application_id) const {
+ return false == cache_->IsApplicationRepresented(application_id);
+}
+
+bool PolicyManagerImpl::ResetPT(const std::string& file_name) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ cache_->ResetCalculatedPermissions();
+ const bool result = cache_->ResetPT(file_name);
+ if (result) {
+ RefreshRetrySequence();
+ }
+ return result;
+}
+
+bool PolicyManagerImpl::CheckAppStorageFolder() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const std::string app_storage_folder = get_settings().app_storage_folder();
+ LOG4CXX_DEBUG(logger_, "AppStorageFolder " << app_storage_folder);
+ if (!file_system::DirectoryExists(app_storage_folder)) {
+ LOG4CXX_WARN(logger_,
+ "Storage directory doesn't exist " << app_storage_folder);
+ return false;
+ }
+ if (!(file_system::IsWritingAllowed(app_storage_folder) &&
+ file_system::IsReadingAllowed(app_storage_folder))) {
+ LOG4CXX_WARN(logger_,
+ "Storage directory doesn't have read/write permissions "
+ << app_storage_folder);
+ return false;
+ }
+ return true;
+}
+
+bool PolicyManagerImpl::InitPT(const std::string& file_name,
+ const PolicySettings* settings) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ settings_ = settings;
+ if (!CheckAppStorageFolder()) {
+ LOG4CXX_ERROR(logger_, "Can not read/write into AppStorageFolder");
+ return false;
+ }
+ const bool ret = cache_->Init(file_name, settings);
+ if (ret) {
+ RefreshRetrySequence();
+ update_status_manager_.OnPolicyInit(cache_->UpdateRequired());
+ }
+ return ret;
+}
+
+uint32_t PolicyManagerImpl::HeartBeatTimeout(const std::string& app_id) const {
+ return cache_->HeartBeatTimeout(app_id);
+}
+
+void PolicyManagerImpl::SaveUpdateStatusRequired(bool is_update_needed) {
+ cache_->SaveUpdateRequired(is_update_needed);
+}
+
+void PolicyManagerImpl::set_cache_manager(
+ CacheManagerInterface* cache_manager) {
+ cache_ = cache_manager;
+}
+
+} // namespace policy
diff --git a/src/components/policy/policy_external/src/policy_table.cc b/src/components/policy/policy_external/src/policy_table.cc
new file mode 100644
index 0000000000..7a63fac50d
--- /dev/null
+++ b/src/components/policy/policy_external/src/policy_table.cc
@@ -0,0 +1,52 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "policy/policy_table.h"
+
+#include "policy/sql_pt_ext_representation.h"
+
+#include "utils/logger.h"
+
+namespace policy {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Policy")
+
+PolicyTable::PolicyTable() : pt_data_(new SQLPTExtRepresentation()) {}
+
+PolicyTable::PolicyTable(utils::SharedPtr<PTRepresentation> pt_data)
+ : pt_data_(pt_data) {}
+
+PolicyTable::~PolicyTable() {
+ LOG4CXX_INFO(logger_, "Destroying policy table.");
+}
+
+} // namespace policy
diff --git a/src/components/policy/policy_external/src/policy_table/enums.cc b/src/components/policy/policy_external/src/policy_table/enums.cc
new file mode 100644
index 0000000000..e70167c94b
--- /dev/null
+++ b/src/components/policy/policy_external/src/policy_table/enums.cc
@@ -0,0 +1,723 @@
+// This file is generated, do not edit
+#include "policy/policy_table/enums.h"
+
+namespace rpc {
+namespace policy_table_interface_base {
+bool IsValidEnum(Priority val) {
+ switch (val) {
+ case P_EMERGENCY:
+ return true;
+ case P_NAVIGATION:
+ return true;
+ case P_VOICECOM:
+ return true;
+ case P_COMMUNICATION:
+ return true;
+ case P_NORMAL:
+ return true;
+ case P_NONE:
+ return true;
+ default:
+ return false;
+ }
+}
+const char* EnumToJsonString(Priority val) {
+ switch (val) {
+ case P_EMERGENCY:
+ return "EMERGENCY";
+ case P_NAVIGATION:
+ return "NAVIGATION";
+ case P_VOICECOM:
+ return "VOICECOM";
+ case P_COMMUNICATION:
+ return "COMMUNICATION";
+ case P_NORMAL:
+ return "NORMAL";
+ case P_NONE:
+ return "NONE";
+ default:
+ return "";
+ }
+}
+bool EnumFromJsonString(const std::string& literal, Priority* result) {
+ if ("EMERGENCY" == literal) {
+ *result = P_EMERGENCY;
+ return true;
+ } else if ("NAVIGATION" == literal) {
+ *result = P_NAVIGATION;
+ return true;
+ } else if ("VOICECOM" == literal) {
+ *result = P_VOICECOM;
+ return true;
+ } else if ("COMMUNICATION" == literal) {
+ *result = P_COMMUNICATION;
+ return true;
+ } else if ("NORMAL" == literal) {
+ *result = P_NORMAL;
+ return true;
+ } else if ("NONE" == literal) {
+ *result = P_NONE;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool IsValidEnum(HmiLevel val) {
+ switch (val) {
+ case HL_BACKGROUND:
+ return true;
+ case HL_FULL:
+ return true;
+ case HL_LIMITED:
+ return true;
+ case HL_NONE:
+ return true;
+ default:
+ return false;
+ }
+}
+const char* EnumToJsonString(HmiLevel val) {
+ switch (val) {
+ case HL_BACKGROUND:
+ return "BACKGROUND";
+ case HL_FULL:
+ return "FULL";
+ case HL_LIMITED:
+ return "LIMITED";
+ case HL_NONE:
+ return "NONE";
+ default:
+ return "";
+ }
+}
+bool EnumFromJsonString(const std::string& literal, HmiLevel* result) {
+ if ("BACKGROUND" == literal) {
+ *result = HL_BACKGROUND;
+ return true;
+ } else if ("FULL" == literal) {
+ *result = HL_FULL;
+ return true;
+ } else if ("LIMITED" == literal) {
+ *result = HL_LIMITED;
+ return true;
+ } else if ("NONE" == literal) {
+ *result = HL_NONE;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool IsValidEnum(Parameter val) {
+ switch (val) {
+ case P_GPS:
+ return true;
+ case P_SPEED:
+ return true;
+ case P_ENGINETORQUE:
+ return true;
+ case P_EXTERNALTEMPERATURE:
+ return true;
+ case P_FUELLEVEL:
+ return true;
+ case P_FUELLEVEL_STATE:
+ return true;
+ case P_HEADLAMPSTATUS:
+ return true;
+ case P_INSTANTFUELCONSUMPTION:
+ return true;
+ case P_ODOMETER:
+ return true;
+ case P_TIREPRESSURE:
+ return true;
+ case P_WIPERSTATUS:
+ return true;
+ case P_VIN:
+ return true;
+ case P_ACCPEDALPOSITION:
+ return true;
+ case P_BELTSTATUS:
+ return true;
+ case P_DRIVERBRAKING:
+ return true;
+ case P_PRNDL:
+ return true;
+ case P_RPM:
+ return true;
+ case P_STEERINGWHEELANGLE:
+ return true;
+ case P_MYKEY:
+ return true;
+ case P_AIRBAGSTATUS:
+ return true;
+ case P_BODYINFORMATION:
+ return true;
+ case P_CLUSTERMODESTATUS:
+ return true;
+ case P_DEVICESTATUS:
+ return true;
+ case P_EMERGENCYEVENT:
+ return true;
+ case P_ECALLINFO:
+ return true;
+ case P_ABS_STATE:
+ return true;
+ case P_TURN_SIGNAL:
+ return true;
+ case P_FUEL_RANGE:
+ return true;
+ case P_TIRE_PRESSURE_VALUE:
+ return true;
+ case P_TPMS:
+ return true;
+ case P_LONGTITUDE_DEGREES:
+ return true;
+ case P_LATITUDE_DEGREES:
+ return true;
+ case P_LOCATION_NAME:
+ return true;
+ case P_LOCATION_DESCRIPTION:
+ return true;
+ case P_ADDRESS_LINES:
+ return true;
+ case P_PHONE_NUMBER:
+ return true;
+ case P_LOCATION_IMAGE:
+ return true;
+ case P_DELIVERY_MODE:
+ return true;
+ case P_TIMESTAMP:
+ return true;
+ case P_ADDRESS:
+ return true;
+ case P_EMPTY:
+ return true;
+ default:
+ return false;
+ }
+}
+
+const char* EnumToJsonString(Parameter val) {
+ switch (val) {
+ case P_GPS:
+ return "gps";
+ case P_SPEED:
+ return "speed";
+ case P_ENGINETORQUE:
+ return "engineTorque";
+ case P_EXTERNALTEMPERATURE:
+ return "externalTemperature";
+ case P_FUELLEVEL:
+ return "fuelLevel";
+ case P_FUELLEVEL_STATE:
+ return "fuelLevel_State";
+ case P_HEADLAMPSTATUS:
+ return "headLampStatus";
+ case P_INSTANTFUELCONSUMPTION:
+ return "instantFuelConsumption";
+ case P_ODOMETER:
+ return "odometer";
+ case P_TIREPRESSURE:
+ return "tirePressure";
+ case P_WIPERSTATUS:
+ return "wiperStatus";
+ case P_VIN:
+ return "vin";
+ case P_ACCPEDALPOSITION:
+ return "accPedalPosition";
+ case P_BELTSTATUS:
+ return "beltStatus";
+ case P_DRIVERBRAKING:
+ return "driverBraking";
+ case P_PRNDL:
+ return "prndl";
+ case P_RPM:
+ return "rpm";
+ case P_STEERINGWHEELANGLE:
+ return "steeringWheelAngle";
+ case P_MYKEY:
+ return "myKey";
+ case P_AIRBAGSTATUS:
+ return "airbagStatus";
+ case P_BODYINFORMATION:
+ return "bodyInformation";
+ case P_CLUSTERMODESTATUS:
+ return "clusterModeStatus";
+ case P_DEVICESTATUS:
+ return "deviceStatus";
+ case P_EMERGENCYEVENT:
+ return "emergencyEvent";
+ case P_ECALLINFO:
+ return "eCallInfo";
+ case P_ABS_STATE:
+ return "abs_State";
+ case P_TURN_SIGNAL:
+ return "turnSignal";
+ case P_FUEL_RANGE:
+ return "fuelRange";
+ case P_TIRE_PRESSURE_VALUE:
+ return "tirePressureValue";
+ case P_TPMS:
+ return "tpms";
+ case P_LONGTITUDE_DEGREES:
+ return "longitudeDegrees";
+ case P_LATITUDE_DEGREES:
+ return "latitudeDegrees";
+ case P_LOCATION_NAME:
+ return "locationName";
+ case P_LOCATION_DESCRIPTION:
+ return "locationDescription";
+ case P_ADDRESS_LINES:
+ return "addressLines";
+ case P_PHONE_NUMBER:
+ return "phoneNumber";
+ case P_LOCATION_IMAGE:
+ return "locationImage";
+ case P_DELIVERY_MODE:
+ return "deliveryMode";
+ case P_TIMESTAMP:
+ return "timeStamp";
+ case P_ADDRESS:
+ return "address";
+ case P_EMPTY:
+ return "EMPTY";
+ default:
+ return "";
+ }
+}
+
+bool EnumFromJsonString(const std::string& literal, Parameter* result) {
+ if ("gps" == literal) {
+ *result = P_GPS;
+ return true;
+ } else if ("speed" == literal) {
+ *result = P_SPEED;
+ return true;
+ } else if ("engineTorque" == literal) {
+ *result = P_ENGINETORQUE;
+ return true;
+ } else if ("externalTemperature" == literal) {
+ *result = P_EXTERNALTEMPERATURE;
+ return true;
+ } else if ("fuelLevel" == literal) {
+ *result = P_FUELLEVEL;
+ return true;
+ } else if ("fuelLevel_State" == literal) {
+ *result = P_FUELLEVEL_STATE;
+ return true;
+ } else if ("headLampStatus" == literal) {
+ *result = P_HEADLAMPSTATUS;
+ return true;
+ } else if ("instantFuelConsumption" == literal) {
+ *result = P_INSTANTFUELCONSUMPTION;
+ return true;
+ } else if ("odometer" == literal) {
+ *result = P_ODOMETER;
+ return true;
+ } else if ("tirePressure" == literal) {
+ *result = P_TIREPRESSURE;
+ return true;
+ } else if ("wiperStatus" == literal) {
+ *result = P_WIPERSTATUS;
+ return true;
+ } else if ("vin" == literal) {
+ *result = P_VIN;
+ return true;
+ } else if ("accPedalPosition" == literal) {
+ *result = P_ACCPEDALPOSITION;
+ return true;
+ } else if ("beltStatus" == literal) {
+ *result = P_BELTSTATUS;
+ return true;
+ } else if ("driverBraking" == literal) {
+ *result = P_DRIVERBRAKING;
+ return true;
+ } else if ("prndl" == literal) {
+ *result = P_PRNDL;
+ return true;
+ } else if ("rpm" == literal) {
+ *result = P_RPM;
+ return true;
+ } else if ("steeringWheelAngle" == literal) {
+ *result = P_STEERINGWHEELANGLE;
+ return true;
+ } else if ("myKey" == literal) {
+ *result = P_MYKEY;
+ return true;
+ } else if ("airbagStatus" == literal) {
+ *result = P_AIRBAGSTATUS;
+ return true;
+ } else if ("bodyInformation" == literal) {
+ *result = P_BODYINFORMATION;
+ return true;
+ } else if ("clusterModeStatus" == literal) {
+ *result = P_CLUSTERMODESTATUS;
+ return true;
+ } else if ("deviceStatus" == literal) {
+ *result = P_DEVICESTATUS;
+ return true;
+ } else if ("emergencyEvent" == literal) {
+ *result = P_EMERGENCYEVENT;
+ return true;
+ } else if ("eCallInfo" == literal) {
+ *result = P_ECALLINFO;
+ return true;
+ } else if ("abs_State" == literal) {
+ *result = P_ABS_STATE;
+ return true;
+ } else if ("turnSignal" == literal) {
+ *result = P_TURN_SIGNAL;
+ return true;
+ } else if ("fuelRange" == literal) {
+ *result = P_FUEL_RANGE;
+ return true;
+ } else if ("tirePressureValue" == literal) {
+ *result = P_TIRE_PRESSURE_VALUE;
+ return true;
+ } else if ("tpms" == literal) {
+ *result = P_TPMS;
+ return true;
+ } else if ("longitudeDegrees" == literal) {
+ *result = P_LONGTITUDE_DEGREES;
+ return true;
+ } else if ("latitudeDegrees" == literal) {
+ *result = P_LATITUDE_DEGREES;
+ return true;
+ } else if ("locationName" == literal) {
+ *result = P_LOCATION_NAME;
+ return true;
+ } else if ("locationDescription" == literal) {
+ *result = P_LOCATION_DESCRIPTION;
+ return true;
+ } else if ("addressLines" == literal) {
+ *result = P_ADDRESS_LINES;
+ return true;
+ } else if ("phoneNumber" == literal) {
+ *result = P_PHONE_NUMBER;
+ return true;
+ } else if ("locationImage" == literal) {
+ *result = P_LOCATION_IMAGE;
+ return true;
+ } else if ("deliveryMode" == literal) {
+ *result = P_DELIVERY_MODE;
+ return true;
+ } else if ("timeStamp" == literal) {
+ *result = P_TIMESTAMP;
+ return true;
+ } else if ("address" == literal) {
+ *result = P_ADDRESS;
+ return true;
+ } else if ("EMPTY" == literal) {
+ *result = P_EMPTY;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool IsValidEnum(AppHMIType val) {
+ switch (val) {
+ case AHT_DEFAULT:
+ return true;
+ case AHT_COMMUNICATION:
+ return true;
+ case AHT_MEDIA:
+ return true;
+ case AHT_MESSAGING:
+ return true;
+ case AHT_NAVIGATION:
+ return true;
+ case AHT_INFORMATION:
+ return true;
+ case AHT_SOCIAL:
+ return true;
+ case AHT_BACKGROUND_PROCESS:
+ return true;
+ case AHT_TESTING:
+ return true;
+ case AHT_SYSTEM:
+ return true;
+ default:
+ return false;
+ }
+}
+const char* EnumToJsonString(AppHMIType val) {
+ switch (val) {
+ case AHT_DEFAULT:
+ return "DEFAULT";
+ case AHT_COMMUNICATION:
+ return "COMMUNICATION";
+ case AHT_MEDIA:
+ return "MEDIA";
+ case AHT_MESSAGING:
+ return "MESSAGING";
+ case AHT_NAVIGATION:
+ return "NAVIGATION";
+ case AHT_INFORMATION:
+ return "INFORMATION";
+ case AHT_SOCIAL:
+ return "SOCIAL";
+ case AHT_BACKGROUND_PROCESS:
+ return "BACKGROUND_PROCESS";
+ case AHT_TESTING:
+ return "TESTING";
+ case AHT_SYSTEM:
+ return "SYSTEM";
+ default:
+ return "";
+ }
+}
+bool EnumFromJsonString(const std::string& literal, AppHMIType* result) {
+ if ("DEFAULT" == literal) {
+ *result = AHT_DEFAULT;
+ return true;
+ } else if ("COMMUNICATION" == literal) {
+ *result = AHT_COMMUNICATION;
+ return true;
+ } else if ("MEDIA" == literal) {
+ *result = AHT_MEDIA;
+ return true;
+ } else if ("MESSAGING" == literal) {
+ *result = AHT_MESSAGING;
+ return true;
+ } else if ("NAVIGATION" == literal) {
+ *result = AHT_NAVIGATION;
+ return true;
+ } else if ("INFORMATION" == literal) {
+ *result = AHT_INFORMATION;
+ return true;
+ } else if ("SOCIAL" == literal) {
+ *result = AHT_SOCIAL;
+ return true;
+ } else if ("BACKGROUND_PROCESS" == literal) {
+ *result = AHT_BACKGROUND_PROCESS;
+ return true;
+ } else if ("TESTING" == literal) {
+ *result = AHT_TESTING;
+ return true;
+ } else if ("SYSTEM" == literal) {
+ *result = AHT_SYSTEM;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool IsValidEnum(Input val) {
+ switch (val) {
+ case I_GUI:
+ return true;
+ case I_VUI:
+ return true;
+ default:
+ return false;
+ }
+}
+const char* EnumToJsonString(Input val) {
+ switch (val) {
+ case I_GUI:
+ return "GUI";
+ case I_VUI:
+ return "VUI";
+ default:
+ return "";
+ }
+}
+bool EnumFromJsonString(const std::string& literal, Input* result) {
+ if ("GUI" == literal) {
+ *result = I_GUI;
+ return true;
+ } else if ("VUI" == literal) {
+ *result = I_VUI;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool IsValidEnum(RequestType val) {
+ switch (val) {
+ case RT_HTTP:
+ return true;
+ case RT_FILE_RESUME:
+ return true;
+ case RT_AUTH_REQUEST:
+ return true;
+ case RT_AUTH_CHALLENGE:
+ return true;
+ case RT_AUTH_ACK:
+ return true;
+ case RT_PROPRIETARY:
+ return true;
+ case RT_QUERY_APPS:
+ return true;
+ case RT_LAUNCH_APP:
+ return true;
+ case RT_LOCK_SCREEN_ICON_URL:
+ return true;
+ case RT_TRAFFIC_MESSAGE_CHANNEL:
+ return true;
+ case RT_DRIVER_PROFILE:
+ return true;
+ case RT_VOICE_SEARCH:
+ return true;
+ case RT_NAVIGATION:
+ return true;
+ case RT_PHONE:
+ return true;
+ case RT_CLIMATE:
+ return true;
+ case RT_SETTINGS:
+ return true;
+ case RT_VEHICLE_DIAGNOSTICS:
+ return true;
+ case RT_EMERGENCY:
+ return true;
+ case RT_MEDIA:
+ return true;
+ case RT_FOTA:
+ return true;
+ default:
+ return false;
+ }
+}
+
+const char* EnumToJsonString(RequestType val) {
+ switch (val) {
+ case RT_HTTP:
+ return "HTTP";
+ case RT_FILE_RESUME:
+ return "FILE_RESUME";
+ case RT_AUTH_REQUEST:
+ return "AUTH_REQUEST";
+ case RT_AUTH_CHALLENGE:
+ return "AUTH_CHALLENGE";
+ case RT_AUTH_ACK:
+ return "AUTH_ACK";
+ case RT_PROPRIETARY:
+ return "PROPRIETARY";
+ case RT_QUERY_APPS:
+ return "QUERY_APPS";
+ case RT_LAUNCH_APP:
+ return "LAUNCH_APP";
+ case RT_LOCK_SCREEN_ICON_URL:
+ return "LOCK_SCREEN_ICON_URL";
+ case RT_TRAFFIC_MESSAGE_CHANNEL:
+ return "TRAFFIC_MESSAGE_CHANNEL";
+ case RT_DRIVER_PROFILE:
+ return "DRIVER_PROFILE";
+ case RT_VOICE_SEARCH:
+ return "VOICE_SEARCH";
+ case RT_NAVIGATION:
+ return "NAVIGATION";
+ case RT_PHONE:
+ return "PHONE";
+ case RT_CLIMATE:
+ return "CLIMATE";
+ case RT_SETTINGS:
+ return "SETTINGS";
+ case RT_VEHICLE_DIAGNOSTICS:
+ return "VEHICLE_DIAGNOSTICS";
+ case RT_EMERGENCY:
+ return "EMERGENCY";
+ case RT_MEDIA:
+ return "MEDIA";
+ case RT_FOTA:
+ return "FOTA";
+ default:
+ return "";
+ }
+}
+
+bool EnumFromJsonString(const std::string& literal, RequestType* result) {
+ if ("HTTP" == literal) {
+ *result = RT_HTTP;
+ return true;
+ }
+ if ("FILE_RESUME" == literal) {
+ *result = RT_FILE_RESUME;
+ return true;
+ }
+ if ("AUTH_REQUEST" == literal) {
+ *result = RT_AUTH_REQUEST;
+ return true;
+ }
+ if ("AUTH_CHALLENGE" == literal) {
+ *result = RT_AUTH_CHALLENGE;
+ return true;
+ }
+ if ("AUTH_ACK" == literal) {
+ *result = RT_AUTH_ACK;
+ return true;
+ }
+ if ("PROPRIETARY" == literal) {
+ *result = RT_PROPRIETARY;
+ return true;
+ }
+ if ("QUERY_APPS" == literal) {
+ *result = RT_QUERY_APPS;
+ return true;
+ }
+ if ("LAUNCH_APP" == literal) {
+ *result = RT_LAUNCH_APP;
+ return true;
+ }
+ if ("LOCK_SCREEN_ICON_URL" == literal) {
+ *result = RT_LOCK_SCREEN_ICON_URL;
+ return true;
+ }
+ if ("TRAFFIC_MESSAGE_CHANNEL" == literal) {
+ *result = RT_TRAFFIC_MESSAGE_CHANNEL;
+ return true;
+ }
+ if ("DRIVER_PROFILE" == literal) {
+ *result = RT_DRIVER_PROFILE;
+ return true;
+ }
+ if ("VOICE_SEARCH" == literal) {
+ *result = RT_VOICE_SEARCH;
+ return true;
+ }
+ if ("NAVIGATION" == literal) {
+ *result = RT_NAVIGATION;
+ return true;
+ }
+ if ("PHONE" == literal) {
+ *result = RT_PHONE;
+ return true;
+ }
+ if ("CLIMATE" == literal) {
+ *result = RT_CLIMATE;
+ return true;
+ }
+ if ("SETTINGS" == literal) {
+ *result = RT_SETTINGS;
+ return true;
+ }
+ if ("VEHICLE_DIAGNOSTICS" == literal) {
+ *result = RT_VEHICLE_DIAGNOSTICS;
+ return true;
+ }
+ if ("EMERGENCY" == literal) {
+ *result = RT_EMERGENCY;
+ return true;
+ }
+ if ("MEDIA" == literal) {
+ *result = RT_MEDIA;
+ return true;
+ }
+ if ("FOTA" == literal) {
+ *result = RT_FOTA;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+const std::string kDefaultApp = "default";
+const std::string kPreDataConsentApp = "pre_DataConsent";
+const std::string kDeviceApp = "device";
+
+} // namespace policy_table_interface_base
+} // namespace rpc
diff --git a/src/components/policy/policy_external/src/policy_table/types.cc b/src/components/policy/policy_external/src/policy_table/types.cc
new file mode 100644
index 0000000000..528d70a426
--- /dev/null
+++ b/src/components/policy/policy_external/src/policy_table/types.cc
@@ -0,0 +1,2134 @@
+#include <algorithm>
+#include "policy/policy_table/types.h"
+#include "rpc_base/rpc_base_json_inl.h"
+
+namespace rpc {
+namespace policy_table_interface_base {
+
+std::string PolicyTableTypeToString(const PolicyTableType pt_type) {
+ switch (pt_type) {
+ case PT_PRELOADED: {
+ return "PT_PRELOADED";
+ }
+ case PT_UPDATE: {
+ return "PT_UPDATE";
+ }
+ case PT_SNAPSHOT: {
+ return "PT_SNAPSHOT";
+ }
+ default: { return "INVALID_PT_TYPE"; }
+ }
+}
+
+// PolicyBase methods
+PolicyBase::PolicyBase() : CompositeType(kUninitialized) {}
+
+PolicyBase::PolicyBase(const Strings& groups,
+ Priority priority,
+ HmiLevel default_hmi,
+ bool keep_context,
+ bool steal_focus)
+ : CompositeType(kUninitialized)
+ , groups(groups)
+ , priority(priority)
+ , default_hmi(default_hmi)
+ , keep_context(keep_context)
+ , steal_focus(steal_focus) {}
+
+PolicyBase::~PolicyBase() {}
+
+PolicyBase::PolicyBase(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , groups(impl::ValueMember(value__, "groups"))
+ , preconsented_groups(impl::ValueMember(value__, "preconsented_groups"))
+ , priority(impl::ValueMember(value__, "priority"))
+ , default_hmi(impl::ValueMember(value__, "default_hmi"))
+ , keep_context(impl::ValueMember(value__, "keep_context"))
+ , steal_focus(impl::ValueMember(value__, "steal_focus")) {}
+
+Json::Value PolicyBase::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("groups", groups, &result__);
+ impl::WriteJsonField("preconsented_groups", preconsented_groups, &result__);
+ impl::WriteJsonField("priority", priority, &result__);
+ impl::WriteJsonField("default_hmi", default_hmi, &result__);
+ impl::WriteJsonField("keep_context", keep_context, &result__);
+ impl::WriteJsonField("steal_focus", steal_focus, &result__);
+ return result__;
+}
+
+bool PolicyBase::is_valid() const {
+ if (!groups.is_valid()) {
+ return false;
+ }
+ if (!preconsented_groups.is_valid()) {
+ return false;
+ }
+ if (!priority.is_valid()) {
+ return false;
+ }
+ if (!default_hmi.is_valid()) {
+ return false;
+ }
+ if (!keep_context.is_valid()) {
+ return false;
+ }
+ if (!steal_focus.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool PolicyBase::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool PolicyBase::struct_empty() const {
+ if (groups.is_initialized()) {
+ return false;
+ }
+ if (preconsented_groups.is_initialized()) {
+ return false;
+ }
+ if (priority.is_initialized()) {
+ return false;
+ }
+ if (default_hmi.is_initialized()) {
+ return false;
+ }
+ if (keep_context.is_initialized()) {
+ return false;
+ }
+ if (steal_focus.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void PolicyBase::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!groups.is_valid()) {
+ groups.ReportErrors(&report__->ReportSubobject("groups"));
+ }
+ if (!preconsented_groups.is_valid()) {
+ preconsented_groups.ReportErrors(
+ &report__->ReportSubobject("preconsented_groups"));
+ }
+ if (!priority.is_valid()) {
+ priority.ReportErrors(&report__->ReportSubobject("priority"));
+ }
+ if (!default_hmi.is_valid()) {
+ default_hmi.ReportErrors(&report__->ReportSubobject("default_hmi"));
+ }
+ if (!keep_context.is_valid()) {
+ keep_context.ReportErrors(&report__->ReportSubobject("keep_context"));
+ }
+ if (!steal_focus.is_valid()) {
+ steal_focus.ReportErrors(&report__->ReportSubobject("steal_focus"));
+ }
+}
+
+void PolicyBase::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ groups.SetPolicyTableType(pt_type);
+ priority.SetPolicyTableType(pt_type);
+}
+
+// DevicePolicy methods
+DevicePolicy::DevicePolicy() : PolicyBase() {}
+
+DevicePolicy::DevicePolicy(const Strings& groups,
+ Priority priority,
+ HmiLevel default_hmi,
+ bool keep_context,
+ bool steal_focus)
+ : PolicyBase(groups, priority, default_hmi, keep_context, steal_focus) {}
+
+DevicePolicy::~DevicePolicy() {}
+
+DevicePolicy::DevicePolicy(const Json::Value* value__) : PolicyBase(value__) {}
+
+// AppPoliciesSection methods
+ApplicationPoliciesSection::ApplicationPoliciesSection()
+ : CompositeType(kUninitialized) {}
+
+ApplicationPoliciesSection::ApplicationPoliciesSection(
+ const ApplicationPolicies& apps, const DevicePolicy& device)
+ : CompositeType(kUninitialized), apps(apps), device(device) {}
+
+ApplicationPoliciesSection::~ApplicationPoliciesSection() {}
+
+ApplicationPoliciesSection::ApplicationPoliciesSection(
+ const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , apps(value__)
+ , device(impl::ValueMember(value__, "device")) {
+ // Since "device" is moved to separate struct, we have to delete it from
+ // parsed apps to avoid validation issues due to possible wrong params in
+ // device section
+ apps.erase("device");
+}
+
+Json::Value ApplicationPoliciesSection::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ result__ = apps.ToJsonValue();
+ impl::WriteJsonField("device", device, &result__);
+ return result__;
+}
+
+bool ApplicationPoliciesSection::is_valid() const {
+ if (!device.is_valid()) {
+ return false;
+ }
+ if (!apps.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool ApplicationPoliciesSection::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool ApplicationPoliciesSection::struct_empty() const {
+ if (device.is_initialized()) {
+ return false;
+ }
+ if (apps.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void ApplicationPoliciesSection::ReportErrors(
+ rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!device.is_valid()) {
+ device.ReportErrors(&report__->ReportSubobject("device"));
+ }
+ if (!apps.is_valid()) {
+ apps.ReportErrors(&report__->ReportSubobject("apps"));
+ }
+}
+
+void ApplicationPoliciesSection::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ device.SetPolicyTableType(pt_type);
+ apps.SetPolicyTableType(pt_type);
+}
+
+// ApplicationParams methods
+ApplicationParams::ApplicationParams() : PolicyBase() {}
+
+ApplicationParams::ApplicationParams(const Strings& groups,
+ Priority priority,
+ HmiLevel default_hmi,
+ bool keep_context,
+ bool steal_focus)
+ : PolicyBase(groups, priority, default_hmi, keep_context, steal_focus) {}
+
+ApplicationParams::~ApplicationParams() {}
+
+ApplicationParams::ApplicationParams(const Json::Value* value__)
+ : PolicyBase(value__)
+ , nicknames(impl::ValueMember(value__, "nicknames"))
+ , AppHMIType(impl::ValueMember(value__, "AppHMIType"))
+ , RequestType(impl::ValueMember(value__, "RequestType"))
+ , memory_kb(impl::ValueMember(value__, "memory_kb"), 0)
+ , heart_beat_timeout_ms(
+ impl::ValueMember(value__, "heart_beat_timeout_ms")) {}
+
+Json::Value ApplicationParams::ToJsonValue() const {
+ Json::Value result__(PolicyBase::ToJsonValue());
+ impl::WriteJsonField("nicknames", nicknames, &result__);
+ impl::WriteJsonField("AppHMIType", AppHMIType, &result__);
+ impl::WriteJsonField("RequestType", RequestType, &result__);
+ impl::WriteJsonField("memory_kb", memory_kb, &result__);
+ impl::WriteJsonField(
+ "heart_beat_timeout_ms", heart_beat_timeout_ms, &result__);
+ return result__;
+}
+
+bool ApplicationParams::is_valid() const {
+ // RequestType is not validated since there is high-level validation logic,
+ // which takes into account information not available here.
+ if (!PolicyBase::is_valid()) {
+ return false;
+ }
+ if (!nicknames.is_valid()) {
+ return false;
+ }
+ if (!AppHMIType.is_valid()) {
+ return false;
+ }
+ if (!memory_kb.is_valid()) {
+ return false;
+ }
+ if (!heart_beat_timeout_ms.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool ApplicationParams::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool ApplicationParams::struct_empty() const {
+ if (!PolicyBase::is_initialized()) {
+ return false;
+ }
+ if (nicknames.is_initialized()) {
+ return false;
+ }
+ if (AppHMIType.is_initialized()) {
+ return false;
+ }
+ if (RequestType.is_initialized()) {
+ return false;
+ }
+ if (memory_kb.is_initialized()) {
+ return false;
+ }
+ if (heart_beat_timeout_ms.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void ApplicationParams::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!groups.is_valid()) {
+ groups.ReportErrors(&report__->ReportSubobject("groups"));
+ }
+ if (!nicknames.is_valid()) {
+ nicknames.ReportErrors(&report__->ReportSubobject("nicknames"));
+ }
+ if (!preconsented_groups.is_valid()) {
+ preconsented_groups.ReportErrors(
+ &report__->ReportSubobject("preconsented_groups"));
+ }
+ if (!AppHMIType.is_valid()) {
+ AppHMIType.ReportErrors(&report__->ReportSubobject("AppHMIType"));
+ }
+ if (!RequestType.is_valid()) {
+ RequestType.ReportErrors(&report__->ReportSubobject("RequestType"));
+ }
+ if (!priority.is_valid()) {
+ priority.ReportErrors(&report__->ReportSubobject("priority"));
+ }
+ if (!default_hmi.is_valid()) {
+ default_hmi.ReportErrors(&report__->ReportSubobject("default_hmi"));
+ }
+ if (!keep_context.is_valid()) {
+ keep_context.ReportErrors(&report__->ReportSubobject("keep_context"));
+ }
+ if (!steal_focus.is_valid()) {
+ steal_focus.ReportErrors(&report__->ReportSubobject("steal_focus"));
+ }
+ if (!memory_kb.is_valid()) {
+ memory_kb.ReportErrors(&report__->ReportSubobject("memory_kb"));
+ }
+ if (!heart_beat_timeout_ms.is_valid()) {
+ heart_beat_timeout_ms.ReportErrors(
+ &report__->ReportSubobject("heart_beat_timeout_ms"));
+ }
+}
+
+void ApplicationParams::SetPolicyTableType(PolicyTableType pt_type) {
+ PolicyBase::SetPolicyTableType(pt_type);
+ AppHMIType.SetPolicyTableType(pt_type);
+ RequestType.SetPolicyTableType(pt_type);
+ memory_kb.SetPolicyTableType(pt_type);
+ heart_beat_timeout_ms.SetPolicyTableType(pt_type);
+}
+
+// RpcParameters methods
+RpcParameters::RpcParameters() : CompositeType(kUninitialized) {}
+
+RpcParameters::RpcParameters(const HmiLevels& hmi_levels)
+ : CompositeType(kUninitialized), hmi_levels(hmi_levels) {}
+
+RpcParameters::~RpcParameters() {}
+
+RpcParameters::RpcParameters(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , hmi_levels(impl::ValueMember(value__, "hmi_levels"))
+ , parameters(impl::ValueMember(value__, "parameters")) {}
+
+Json::Value RpcParameters::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("hmi_levels", hmi_levels, &result__);
+ impl::WriteJsonField("parameters", parameters, &result__);
+ return result__;
+}
+
+bool RpcParameters::is_valid() const {
+ if (!hmi_levels.is_valid()) {
+ return false;
+ }
+ if (!parameters.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool RpcParameters::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool RpcParameters::struct_empty() const {
+ if (hmi_levels.is_initialized()) {
+ return false;
+ }
+ if (parameters.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void RpcParameters::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!hmi_levels.is_valid()) {
+ hmi_levels.ReportErrors(&report__->ReportSubobject("hmi_levels"));
+ }
+ if (!parameters.is_valid()) {
+ parameters.ReportErrors(&report__->ReportSubobject("parameters"));
+ }
+}
+
+void RpcParameters::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ hmi_levels.SetPolicyTableType(pt_type);
+ parameters.SetPolicyTableType(pt_type);
+}
+
+// Rpcs methods
+Rpcs::Rpcs() : CompositeType(kUninitialized) {}
+
+Rpcs::Rpcs(const Rpc& rpcs) : CompositeType(kUninitialized), rpcs(rpcs) {}
+
+Rpcs::~Rpcs() {}
+
+Rpcs::Rpcs(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , user_consent_prompt(impl::ValueMember(value__, "user_consent_prompt"))
+ , rpcs(impl::ValueMember(value__, "rpcs"))
+ , disallowed_by_external_consent_entities_on(impl::ValueMember(
+ value__, "disallowed_by_external_consent_entities_on"))
+ , disallowed_by_external_consent_entities_off(impl::ValueMember(
+ value__, "disallowed_by_external_consent_entities_off")) {}
+
+Json::Value Rpcs::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("user_consent_prompt", user_consent_prompt, &result__);
+ impl::WriteJsonField("rpcs", rpcs, &result__);
+ impl::WriteJsonField("disallowed_by_external_consent_entities_on",
+ disallowed_by_external_consent_entities_on,
+ &result__);
+ impl::WriteJsonField("disallowed_by_external_consent_entities_off",
+ disallowed_by_external_consent_entities_off,
+ &result__);
+ return result__;
+}
+
+bool Rpcs::is_valid() const {
+ if (!user_consent_prompt.is_valid()) {
+ return false;
+ }
+ if (!rpcs.is_valid()) {
+ return false;
+ }
+ if (!disallowed_by_external_consent_entities_on.is_valid()) {
+ return false;
+ }
+ if (!disallowed_by_external_consent_entities_off.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool Rpcs::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool Rpcs::struct_empty() const {
+ if (user_consent_prompt.is_initialized()) {
+ return false;
+ }
+ if (rpcs.is_initialized()) {
+ return false;
+ }
+ if (disallowed_by_external_consent_entities_on.is_initialized()) {
+ return false;
+ }
+ if (disallowed_by_external_consent_entities_off.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void Rpcs::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!user_consent_prompt.is_valid()) {
+ user_consent_prompt.ReportErrors(
+ &report__->ReportSubobject("user_consent_prompt"));
+ }
+ if (!rpcs.is_valid()) {
+ rpcs.ReportErrors(&report__->ReportSubobject("rpcs"));
+ }
+ if (!disallowed_by_external_consent_entities_on.is_valid()) {
+ disallowed_by_external_consent_entities_on.ReportErrors(
+ &report__->ReportSubobject(
+ "disallowed_by_external_consent_entities_on"));
+ }
+ if (!disallowed_by_external_consent_entities_off.is_valid()) {
+ disallowed_by_external_consent_entities_off.ReportErrors(
+ &report__->ReportSubobject(
+ "disallowed_by_external_consent_entities_off"));
+ }
+}
+
+void Rpcs::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ user_consent_prompt.SetPolicyTableType(pt_type);
+ rpcs.SetPolicyTableType(pt_type);
+ disallowed_by_external_consent_entities_off.SetPolicyTableType(pt_type);
+ disallowed_by_external_consent_entities_on.SetPolicyTableType(pt_type);
+}
+
+// ModuleConfig methods
+ModuleConfig::ModuleConfig() : CompositeType(kUninitialized) {}
+
+ModuleConfig::ModuleConfig(
+ uint8_t exchange_after_x_ignition_cycles,
+ int64_t exchange_after_x_kilometers,
+ uint8_t exchange_after_x_days,
+ uint16_t timeout_after_x_seconds,
+ const SecondsBetweenRetries& seconds_between_retries,
+ const ServiceEndpoints& endpoints,
+ const NumberOfNotificationsPerMinute& notifications_per_minute_by_priority)
+ : CompositeType(kUninitialized)
+ , exchange_after_x_ignition_cycles(exchange_after_x_ignition_cycles)
+ , exchange_after_x_kilometers(exchange_after_x_kilometers)
+ , exchange_after_x_days(exchange_after_x_days)
+ , timeout_after_x_seconds(timeout_after_x_seconds)
+ , seconds_between_retries(seconds_between_retries)
+ , endpoints(endpoints)
+ , notifications_per_minute_by_priority(
+ notifications_per_minute_by_priority) {}
+
+ModuleConfig::~ModuleConfig() {}
+
+ModuleConfig::ModuleConfig(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , exchange_after_x_ignition_cycles(
+ impl::ValueMember(value__, "exchange_after_x_ignition_cycles"))
+ , exchange_after_x_kilometers(
+ impl::ValueMember(value__, "exchange_after_x_kilometers"))
+ , exchange_after_x_days(impl::ValueMember(value__, "exchange_after_x_days"))
+ , timeout_after_x_seconds(
+ impl::ValueMember(value__, "timeout_after_x_seconds"))
+ , seconds_between_retries(
+ impl::ValueMember(value__, "seconds_between_retries"))
+ , endpoints(impl::ValueMember(value__, "endpoints"))
+ , notifications_per_minute_by_priority(
+ impl::ValueMember(value__, "notifications_per_minute_by_priority"))
+ , vehicle_make(impl::ValueMember(value__, "vehicle_make"))
+ , vehicle_model(impl::ValueMember(value__, "vehicle_model"))
+ , vehicle_year(impl::ValueMember(value__, "vehicle_year"))
+ , preloaded_date(impl::ValueMember(value__, "preloaded_date"))
+ , certificate(impl::ValueMember(value__, "certificate"))
+ , preloaded_pt(impl::ValueMember(value__, "preloaded_pt")) {}
+
+void ModuleConfig::SafeCopyFrom(const ModuleConfig& from) {
+ exchange_after_x_days = from.exchange_after_x_days;
+ exchange_after_x_kilometers = from.exchange_after_x_kilometers;
+ exchange_after_x_days = from.exchange_after_x_days;
+ exchange_after_x_ignition_cycles = from.exchange_after_x_ignition_cycles;
+ timeout_after_x_seconds = from.timeout_after_x_seconds;
+ seconds_between_retries = from.seconds_between_retries;
+ endpoints = from.endpoints;
+ notifications_per_minute_by_priority =
+ from.notifications_per_minute_by_priority;
+
+ certificate.assign_if_valid(from.certificate);
+ vehicle_make.assign_if_valid(from.vehicle_make);
+ vehicle_model.assign_if_valid(from.vehicle_model);
+ vehicle_year.assign_if_valid(from.vehicle_year);
+}
+
+Json::Value ModuleConfig::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("certificate", certificate, &result__);
+ impl::WriteJsonField("preloaded_pt", preloaded_pt, &result__);
+ impl::WriteJsonField("exchange_after_x_ignition_cycles",
+ exchange_after_x_ignition_cycles,
+ &result__);
+ impl::WriteJsonField(
+ "exchange_after_x_kilometers", exchange_after_x_kilometers, &result__);
+ impl::WriteJsonField(
+ "exchange_after_x_days", exchange_after_x_days, &result__);
+ impl::WriteJsonField(
+ "timeout_after_x_seconds", timeout_after_x_seconds, &result__);
+ impl::WriteJsonField(
+ "seconds_between_retries", seconds_between_retries, &result__);
+ impl::WriteJsonField("endpoints", endpoints, &result__);
+ impl::WriteJsonField("notifications_per_minute_by_priority",
+ notifications_per_minute_by_priority,
+ &result__);
+ impl::WriteJsonField("vehicle_make", vehicle_make, &result__);
+ impl::WriteJsonField("vehicle_model", vehicle_model, &result__);
+ impl::WriteJsonField("vehicle_year", vehicle_year, &result__);
+ impl::WriteJsonField("certificate", certificate, &result__);
+ impl::WriteJsonField("preloaded_date", preloaded_date, &result__);
+ return result__;
+}
+
+bool ModuleConfig::is_valid() const {
+ if (!certificate.is_valid()) {
+ return false;
+ }
+ if (!preloaded_pt.is_valid()) {
+ return false;
+ }
+ if (!exchange_after_x_ignition_cycles.is_valid()) {
+ return false;
+ }
+ if (!exchange_after_x_kilometers.is_valid()) {
+ return false;
+ }
+ if (!exchange_after_x_days.is_valid()) {
+ return false;
+ }
+ if (!timeout_after_x_seconds.is_valid()) {
+ return false;
+ }
+ if (!seconds_between_retries.is_valid()) {
+ return false;
+ }
+ if (!endpoints.is_valid()) {
+ return false;
+ }
+ if (!notifications_per_minute_by_priority.is_valid()) {
+ return false;
+ }
+ if (!vehicle_make.is_valid()) {
+ return false;
+ }
+ if (!vehicle_model.is_valid()) {
+ return false;
+ }
+ if (!vehicle_year.is_valid()) {
+ return false;
+ }
+ if (!certificate.is_valid()) {
+ return false;
+ }
+ if (!preloaded_date.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool ModuleConfig::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool ModuleConfig::struct_empty() const {
+ if (certificate.is_initialized()) {
+ return false;
+ }
+ if (preloaded_pt.is_initialized()) {
+ return false;
+ }
+
+ if (exchange_after_x_ignition_cycles.is_initialized()) {
+ return false;
+ }
+ if (exchange_after_x_kilometers.is_initialized()) {
+ return false;
+ }
+
+ if (exchange_after_x_days.is_initialized()) {
+ return false;
+ }
+ if (timeout_after_x_seconds.is_initialized()) {
+ return false;
+ }
+
+ if (seconds_between_retries.is_initialized()) {
+ return false;
+ }
+ if (endpoints.is_initialized()) {
+ return false;
+ }
+
+ if (notifications_per_minute_by_priority.is_initialized()) {
+ return false;
+ }
+ if (vehicle_make.is_initialized()) {
+ return false;
+ }
+
+ if (vehicle_model.is_initialized()) {
+ return false;
+ }
+ if (vehicle_year.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void ModuleConfig::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!certificate.is_valid()) {
+ certificate.ReportErrors(&report__->ReportSubobject("certificate"));
+ }
+ if (!preloaded_pt.is_valid()) {
+ preloaded_pt.ReportErrors(&report__->ReportSubobject("preloaded_pt"));
+ }
+ if (!exchange_after_x_ignition_cycles.is_valid()) {
+ exchange_after_x_ignition_cycles.ReportErrors(
+ &report__->ReportSubobject("exchange_after_x_ignition_cycles"));
+ }
+ if (!exchange_after_x_kilometers.is_valid()) {
+ exchange_after_x_kilometers.ReportErrors(
+ &report__->ReportSubobject("exchange_after_x_kilometers"));
+ }
+ if (!exchange_after_x_days.is_valid()) {
+ exchange_after_x_days.ReportErrors(
+ &report__->ReportSubobject("exchange_after_x_days"));
+ }
+ if (!timeout_after_x_seconds.is_valid()) {
+ timeout_after_x_seconds.ReportErrors(
+ &report__->ReportSubobject("timeout_after_x_seconds"));
+ }
+ if (!seconds_between_retries.is_valid()) {
+ seconds_between_retries.ReportErrors(
+ &report__->ReportSubobject("seconds_between_retries"));
+ }
+ if (!endpoints.is_valid()) {
+ endpoints.ReportErrors(&report__->ReportSubobject("endpoints"));
+ }
+ if (!notifications_per_minute_by_priority.is_valid()) {
+ notifications_per_minute_by_priority.ReportErrors(
+ &report__->ReportSubobject("notifications_per_minute_by_priority"));
+ }
+ if (!vehicle_make.is_valid()) {
+ vehicle_make.ReportErrors(&report__->ReportSubobject("vehicle_make"));
+ }
+ if (!vehicle_model.is_valid()) {
+ vehicle_model.ReportErrors(&report__->ReportSubobject("vehicle_model"));
+ }
+ if (!vehicle_year.is_valid()) {
+ vehicle_year.ReportErrors(&report__->ReportSubobject("vehicle_year"));
+ }
+ const std::string validation_info =
+ omitted_validation_info + PolicyTableTypeToString(GetPolicyTableType());
+
+ rpc::ValidationReport* omitted_field_report = NULL;
+ switch (GetPolicyTableType()) {
+ case PT_PRELOADED: {
+ if (vehicle_make.is_initialized()) {
+ omitted_field_report = &report__->ReportSubobject("vehicle_make");
+ omitted_field_report->set_validation_info(validation_info);
+ }
+ if (vehicle_year.is_initialized()) {
+ omitted_field_report = &report__->ReportSubobject("vehicle_year");
+ omitted_field_report->set_validation_info(validation_info);
+ }
+ if (vehicle_model.is_initialized()) {
+ omitted_field_report = &report__->ReportSubobject("vehicle_model");
+ omitted_field_report->set_validation_info(validation_info);
+ }
+ break;
+ }
+ case PT_UPDATE: {
+ if (preloaded_pt.is_initialized()) {
+ omitted_field_report = &report__->ReportSubobject("preloaded_pt");
+ omitted_field_report->set_validation_info(validation_info);
+ }
+ if (preloaded_date.is_initialized()) {
+ rpc::ValidationReport& preloaded_pt_omitted_field_report =
+ report__->ReportSubobject("preloaded_date");
+ preloaded_pt_omitted_field_report.set_validation_info(validation_info);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void ModuleConfig::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ certificate.SetPolicyTableType(pt_type);
+ preloaded_pt.SetPolicyTableType(pt_type);
+ exchange_after_x_ignition_cycles.SetPolicyTableType(pt_type);
+ exchange_after_x_kilometers.SetPolicyTableType(pt_type);
+ exchange_after_x_days.SetPolicyTableType(pt_type);
+ timeout_after_x_seconds.SetPolicyTableType(pt_type);
+ seconds_between_retries.SetPolicyTableType(pt_type);
+ endpoints.SetPolicyTableType(pt_type);
+ notifications_per_minute_by_priority.SetPolicyTableType(pt_type);
+ vehicle_make.SetPolicyTableType(pt_type);
+ vehicle_model.SetPolicyTableType(pt_type);
+ vehicle_year.SetPolicyTableType(pt_type);
+}
+
+// MessageString methods
+MessageString::MessageString() : CompositeType(kUninitialized) {}
+
+MessageString::~MessageString() {}
+
+MessageString::MessageString(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , line1(impl::ValueMember(value__, "line1"))
+ , line2(impl::ValueMember(value__, "line2"))
+ , tts(impl::ValueMember(value__, "tts"))
+ , label(impl::ValueMember(value__, "label"))
+ , textBody(impl::ValueMember(value__, "textBody")) {}
+
+Json::Value MessageString::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("line1", line1, &result__);
+ impl::WriteJsonField("line2", line2, &result__);
+ impl::WriteJsonField("tts", tts, &result__);
+ impl::WriteJsonField("label", label, &result__);
+ impl::WriteJsonField("textBody", textBody, &result__);
+ return result__;
+}
+
+bool MessageString::is_valid() const {
+ if (struct_empty()) {
+ return initialization_state__ == kInitialized && Validate();
+ }
+ if (!line1.is_valid()) {
+ return false;
+ }
+ if (!line2.is_valid()) {
+ return false;
+ }
+ if (!tts.is_valid()) {
+ return false;
+ }
+ if (!label.is_valid()) {
+ return false;
+ }
+ if (!textBody.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool MessageString::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool MessageString::struct_empty() const {
+ if (line1.is_initialized()) {
+ return false;
+ }
+ if (line2.is_initialized()) {
+ return false;
+ }
+
+ if (tts.is_initialized()) {
+ return false;
+ }
+ if (label.is_initialized()) {
+ return false;
+ }
+
+ if (textBody.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void MessageString::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!line1.is_valid()) {
+ line1.ReportErrors(&report__->ReportSubobject("line1"));
+ }
+ if (!line2.is_valid()) {
+ line2.ReportErrors(&report__->ReportSubobject("line2"));
+ }
+ if (!tts.is_valid()) {
+ tts.ReportErrors(&report__->ReportSubobject("tts"));
+ }
+ if (!label.is_valid()) {
+ label.ReportErrors(&report__->ReportSubobject("label"));
+ }
+ if (!textBody.is_valid()) {
+ textBody.ReportErrors(&report__->ReportSubobject("textBody"));
+ }
+}
+
+void MessageString::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ line1.SetPolicyTableType(pt_type);
+ line2.SetPolicyTableType(pt_type);
+ tts.SetPolicyTableType(pt_type);
+ label.SetPolicyTableType(pt_type);
+ textBody.SetPolicyTableType(pt_type);
+}
+
+// MessageLanguages methods
+const std::string MessageLanguages::kMandatoryLanguage_("en-us");
+
+MessageLanguages::MessageLanguages() : CompositeType(kUninitialized) {}
+
+MessageLanguages::MessageLanguages(const Languages& languages)
+ : CompositeType(kUninitialized), languages(languages) {}
+
+MessageLanguages::~MessageLanguages() {}
+
+MessageLanguages::MessageLanguages(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , languages(impl::ValueMember(value__, "languages")) {}
+
+Json::Value MessageLanguages::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("languages", languages, &result__);
+ return result__;
+}
+
+bool MessageLanguages::is_valid() const {
+ if (!languages.is_valid()) {
+ return false;
+ }
+ // Each RPC must have message in english
+ if (languages.end() == languages.find(kMandatoryLanguage_)) {
+ return false;
+ }
+ return Validate();
+}
+
+bool MessageLanguages::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool MessageLanguages::struct_empty() const {
+ if (languages.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void MessageLanguages::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (PT_SNAPSHOT == GetPolicyTableType()) {
+ if (languages.is_initialized()) {
+ std::string validation_info =
+ omitted_validation_info +
+ PolicyTableTypeToString(GetPolicyTableType());
+ report__->ReportSubobject("languages")
+ .set_validation_info(validation_info);
+ }
+ }
+ if (!languages.is_valid()) {
+ languages.ReportErrors(&report__->ReportSubobject("languages"));
+ }
+ if (languages.end() == languages.find(kMandatoryLanguage_)) {
+ report__->set_validation_info("no mandatory language '" +
+ kMandatoryLanguage_ + "' is present");
+ }
+}
+
+void MessageLanguages::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ languages.SetPolicyTableType(pt_type);
+}
+
+// ConsumerFriendlyMessages methods
+ConsumerFriendlyMessages::ConsumerFriendlyMessages()
+ : CompositeType(kUninitialized) {}
+
+ConsumerFriendlyMessages::ConsumerFriendlyMessages(const std::string& version)
+ : CompositeType(kUninitialized), version(version) {}
+
+ConsumerFriendlyMessages::~ConsumerFriendlyMessages() {}
+
+ConsumerFriendlyMessages::ConsumerFriendlyMessages(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , version(impl::ValueMember(value__, "version"))
+ , messages(impl::ValueMember(value__, "messages")) {}
+
+Json::Value ConsumerFriendlyMessages::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("version", version, &result__);
+ // According to requirements, it is not necessary to provide this to PTS
+ // impl::WriteJsonField("messages", messages, &result__);
+ return result__;
+}
+
+bool ConsumerFriendlyMessages::is_valid() const {
+ if (!version.is_valid()) {
+ return false;
+ }
+ if (!messages.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool ConsumerFriendlyMessages::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool ConsumerFriendlyMessages::struct_empty() const {
+ if (version.is_initialized()) {
+ return false;
+ }
+ if (messages.is_initialized()) {
+ return false;
+ }
+
+ return true;
+}
+
+void ConsumerFriendlyMessages::ReportErrors(
+ rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!version.is_valid()) {
+ version.ReportErrors(&report__->ReportSubobject("version"));
+ }
+ if (PT_SNAPSHOT == GetPolicyTableType()) {
+ if (messages.is_initialized()) {
+ std::string validation_info =
+ omitted_validation_info +
+ PolicyTableTypeToString(GetPolicyTableType());
+ report__->ReportSubobject("messages")
+ .set_validation_info(validation_info);
+ }
+ }
+ if (!messages.is_valid()) {
+ messages.ReportErrors(&report__->ReportSubobject("messages"));
+ }
+}
+
+void ConsumerFriendlyMessages::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ version.SetPolicyTableType(pt_type);
+ messages.SetPolicyTableType(pt_type);
+}
+
+// ModuleMeta methods
+ModuleMeta::ModuleMeta() : CompositeType(kUninitialized) {}
+
+ModuleMeta::~ModuleMeta() {}
+
+ModuleMeta::ModuleMeta(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , ccpu_version(impl::ValueMember(value__, "ccpu_version"))
+ , language(impl::ValueMember(value__, "language"))
+ , wers_country_code(impl::ValueMember(value__, "wers_country_code"))
+ , pt_exchanged_at_odometer_x(
+ impl::ValueMember(value__, "pt_exchanged_at_odometer_x"))
+ , pt_exchanged_x_days_after_epoch(
+ impl::ValueMember(value__, "pt_exchanged_x_days_after_epoch"))
+ , ignition_cycles_since_last_exchange(
+ impl::ValueMember(value__, "ignition_cycles_since_last_exchange"))
+ , vin(impl::ValueMember(value__, "vin")) {}
+
+Json::Value ModuleMeta::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("ccpu_version", ccpu_version, &result__);
+ impl::WriteJsonField("language", language, &result__);
+ impl::WriteJsonField("wers_country_code", wers_country_code, &result__);
+ impl::WriteJsonField(
+ "pt_exchanged_at_odometer_x", pt_exchanged_at_odometer_x, &result__);
+ impl::WriteJsonField("pt_exchanged_x_days_after_epoch",
+ pt_exchanged_x_days_after_epoch,
+ &result__);
+ impl::WriteJsonField("ignition_cycles_since_last_exchange",
+ ignition_cycles_since_last_exchange,
+ &result__);
+ impl::WriteJsonField("vin", vin, &result__);
+ return result__;
+}
+
+bool ModuleMeta::is_valid() const {
+ if (struct_empty()) {
+ return initialization_state__ == kInitialized && Validate();
+ }
+ if (!ccpu_version.is_valid()) {
+ return false;
+ }
+ if (!language.is_valid()) {
+ return false;
+ }
+ if (!wers_country_code.is_valid()) {
+ return false;
+ }
+ if (!pt_exchanged_at_odometer_x.is_valid()) {
+ return false;
+ }
+ if (!pt_exchanged_x_days_after_epoch.is_valid()) {
+ return false;
+ }
+ if (!ignition_cycles_since_last_exchange.is_valid()) {
+ return false;
+ }
+ if (!vin.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool ModuleMeta::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool ModuleMeta::struct_empty() const {
+ if (ccpu_version.is_initialized()) {
+ return false;
+ }
+ if (language.is_initialized()) {
+ return false;
+ }
+
+ if (wers_country_code.is_initialized()) {
+ return false;
+ }
+ if (pt_exchanged_at_odometer_x.is_initialized()) {
+ return false;
+ }
+
+ if (pt_exchanged_x_days_after_epoch.is_initialized()) {
+ return false;
+ }
+ if (ignition_cycles_since_last_exchange.is_initialized()) {
+ return false;
+ }
+
+ if (vin.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void ModuleMeta::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!ccpu_version.is_valid()) {
+ ccpu_version.ReportErrors(&report__->ReportSubobject("ccpu_version"));
+ }
+ if (!language.is_valid()) {
+ language.ReportErrors(&report__->ReportSubobject("language"));
+ }
+ if (!wers_country_code.is_valid()) {
+ wers_country_code.ReportErrors(
+ &report__->ReportSubobject("wers_country_code"));
+ }
+ if (!pt_exchanged_at_odometer_x.is_valid()) {
+ pt_exchanged_at_odometer_x.ReportErrors(
+ &report__->ReportSubobject("pt_exchanged_at_odometer_x"));
+ }
+ if (!pt_exchanged_x_days_after_epoch.is_valid()) {
+ pt_exchanged_x_days_after_epoch.ReportErrors(
+ &report__->ReportSubobject("pt_exchanged_x_days_after_epoch"));
+ }
+ if (!ignition_cycles_since_last_exchange.is_valid()) {
+ ignition_cycles_since_last_exchange.ReportErrors(
+ &report__->ReportSubobject("ignition_cycles_since_last_exchange"));
+ }
+ if (!vin.is_valid()) {
+ vin.ReportErrors(&report__->ReportSubobject("vin"));
+ }
+ if (GetPolicyTableType() == PT_UPDATE ||
+ GetPolicyTableType() == PT_PRELOADED) {
+ std::string validation_info =
+ omitted_validation_info + PolicyTableTypeToString(GetPolicyTableType());
+ report__->set_validation_info(validation_info.c_str());
+ }
+}
+
+void ModuleMeta::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ ccpu_version.SetPolicyTableType(pt_type);
+ language.SetPolicyTableType(pt_type);
+ wers_country_code.SetPolicyTableType(pt_type);
+ pt_exchanged_at_odometer_x.SetPolicyTableType(pt_type);
+ pt_exchanged_x_days_after_epoch.SetPolicyTableType(pt_type);
+ ignition_cycles_since_last_exchange.SetPolicyTableType(pt_type);
+ vin.SetPolicyTableType(pt_type);
+}
+
+// AppLevel methods
+AppLevel::AppLevel() : CompositeType(kUninitialized) {}
+
+AppLevel::AppLevel(uint16_t minutes_in_hmi_full,
+ const std::string& app_registration_language_gui,
+ const std::string& app_registration_language_vui,
+ uint16_t minutes_in_hmi_limited,
+ uint16_t minutes_in_hmi_background,
+ uint16_t minutes_in_hmi_none,
+ uint16_t count_of_user_selections,
+ uint16_t count_of_rejections_sync_out_of_memory,
+ uint16_t count_of_rejections_nickname_mismatch,
+ uint16_t count_of_rejections_duplicate_name,
+ uint16_t count_of_rejected_rpc_calls,
+ uint16_t count_of_rpcs_sent_in_hmi_none,
+ uint16_t count_of_removals_for_bad_behavior,
+ uint16_t count_of_tls_errors,
+ uint16_t count_of_run_attempts_while_revoked)
+ : CompositeType(kUninitialized)
+ , minutes_in_hmi_full(minutes_in_hmi_full)
+ , app_registration_language_gui(app_registration_language_gui)
+ , app_registration_language_vui(app_registration_language_vui)
+ , minutes_in_hmi_limited(minutes_in_hmi_limited)
+ , minutes_in_hmi_background(minutes_in_hmi_background)
+ , minutes_in_hmi_none(minutes_in_hmi_none)
+ , count_of_user_selections(count_of_user_selections)
+ , count_of_rejections_sync_out_of_memory(
+ count_of_rejections_sync_out_of_memory)
+ , count_of_rejections_nickname_mismatch(
+ count_of_rejections_nickname_mismatch)
+ , count_of_rejections_duplicate_name(count_of_rejections_duplicate_name)
+ , count_of_rejected_rpc_calls(count_of_rejected_rpc_calls)
+ , count_of_rpcs_sent_in_hmi_none(count_of_rpcs_sent_in_hmi_none)
+ , count_of_removals_for_bad_behavior(count_of_removals_for_bad_behavior)
+ , count_of_tls_errors(count_of_tls_errors)
+ , count_of_run_attempts_while_revoked(count_of_run_attempts_while_revoked) {
+}
+
+AppLevel::~AppLevel() {}
+
+AppLevel::AppLevel(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , minutes_in_hmi_full(impl::ValueMember(value__, "minutes_in_hmi_full"))
+ , app_registration_language_gui(
+ impl::ValueMember(value__, "app_registration_language_gui"))
+ , app_registration_language_vui(
+ impl::ValueMember(value__, "app_registration_language_vui"))
+ , minutes_in_hmi_limited(
+ impl::ValueMember(value__, "minutes_in_hmi_limited"))
+ , minutes_in_hmi_background(
+ impl::ValueMember(value__, "minutes_in_hmi_background"))
+ , minutes_in_hmi_none(impl::ValueMember(value__, "minutes_in_hmi_none"))
+ , count_of_user_selections(
+ impl::ValueMember(value__, "count_of_user_selections"))
+ , count_of_rejections_sync_out_of_memory(
+ impl::ValueMember(value__, "count_of_rejections_sync_out_of_memory"))
+ , count_of_rejections_nickname_mismatch(
+ impl::ValueMember(value__, "count_of_rejections_nickname_mismatch"))
+ , count_of_rejections_duplicate_name(
+ impl::ValueMember(value__, "count_of_rejections_duplicate_name"))
+ , count_of_rejected_rpc_calls(
+ impl::ValueMember(value__, "count_of_rejected_rpc_calls"))
+ , count_of_rpcs_sent_in_hmi_none(
+ impl::ValueMember(value__, "count_of_rpcs_sent_in_hmi_none"))
+ , count_of_removals_for_bad_behavior(
+ impl::ValueMember(value__, "count_of_removals_for_bad_behavior"))
+ , count_of_tls_errors(impl::ValueMember(value__, "count_of_tls_errors"))
+ , count_of_run_attempts_while_revoked(
+ impl::ValueMember(value__, "count_of_run_attempts_while_revoked")) {}
+
+Json::Value AppLevel::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("minutes_in_hmi_full", minutes_in_hmi_full, &result__);
+ impl::WriteJsonField("app_registration_language_gui",
+ app_registration_language_gui,
+ &result__);
+ impl::WriteJsonField("app_registration_language_vui",
+ app_registration_language_vui,
+ &result__);
+ impl::WriteJsonField(
+ "minutes_in_hmi_limited", minutes_in_hmi_limited, &result__);
+ impl::WriteJsonField(
+ "minutes_in_hmi_background", minutes_in_hmi_background, &result__);
+ impl::WriteJsonField("minutes_in_hmi_none", minutes_in_hmi_none, &result__);
+ impl::WriteJsonField(
+ "count_of_user_selections", count_of_user_selections, &result__);
+ impl::WriteJsonField("count_of_rejections_sync_out_of_memory",
+ count_of_rejections_sync_out_of_memory,
+ &result__);
+ impl::WriteJsonField("count_of_rejections_nickname_mismatch",
+ count_of_rejections_nickname_mismatch,
+ &result__);
+ impl::WriteJsonField("count_of_rejections_duplicate_name",
+ count_of_rejections_duplicate_name,
+ &result__);
+ impl::WriteJsonField(
+ "count_of_rejected_rpc_calls", count_of_rejected_rpc_calls, &result__);
+ impl::WriteJsonField("count_of_rpcs_sent_in_hmi_none",
+ count_of_rpcs_sent_in_hmi_none,
+ &result__);
+ impl::WriteJsonField("count_of_removals_for_bad_behavior",
+ count_of_removals_for_bad_behavior,
+ &result__);
+ impl::WriteJsonField("count_of_TLS_errors", count_of_tls_errors, &result__);
+ impl::WriteJsonField("count_of_run_attempts_while_revoked",
+ count_of_run_attempts_while_revoked,
+ &result__);
+ return result__;
+}
+
+bool AppLevel::is_valid() const {
+ if (!minutes_in_hmi_full.is_valid()) {
+ return false;
+ }
+ if (!app_registration_language_gui.is_valid()) {
+ return false;
+ }
+ if (!app_registration_language_vui.is_valid()) {
+ return false;
+ }
+ if (!minutes_in_hmi_limited.is_valid()) {
+ return false;
+ }
+ if (!minutes_in_hmi_background.is_valid()) {
+ return false;
+ }
+ if (!minutes_in_hmi_none.is_valid()) {
+ return false;
+ }
+ if (!count_of_user_selections.is_valid()) {
+ return false;
+ }
+ if (!count_of_rejections_sync_out_of_memory.is_valid()) {
+ return false;
+ }
+ if (!count_of_rejections_nickname_mismatch.is_valid()) {
+ return false;
+ }
+ if (!count_of_rejections_duplicate_name.is_valid()) {
+ return false;
+ }
+ if (!count_of_rejected_rpc_calls.is_valid()) {
+ return false;
+ }
+ if (!count_of_rpcs_sent_in_hmi_none.is_valid()) {
+ return false;
+ }
+ if (!count_of_removals_for_bad_behavior.is_valid()) {
+ return false;
+ }
+ if (!count_of_tls_errors.is_valid()) {
+ return false;
+ }
+ if (!count_of_run_attempts_while_revoked.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool AppLevel::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool AppLevel::struct_empty() const {
+ if (minutes_in_hmi_full.is_initialized()) {
+ return false;
+ }
+ if (app_registration_language_gui.is_initialized()) {
+ return false;
+ }
+
+ if (app_registration_language_vui.is_initialized()) {
+ return false;
+ }
+
+ if (minutes_in_hmi_limited.is_initialized()) {
+ return false;
+ }
+ if (minutes_in_hmi_background.is_initialized()) {
+ return false;
+ }
+
+ if (minutes_in_hmi_none.is_initialized()) {
+ return false;
+ }
+ if (count_of_user_selections.is_initialized()) {
+ return false;
+ }
+
+ if (count_of_rejections_sync_out_of_memory.is_initialized()) {
+ return false;
+ }
+ if (count_of_rejections_nickname_mismatch.is_initialized()) {
+ return false;
+ }
+
+ if (count_of_rejections_duplicate_name.is_initialized()) {
+ return false;
+ }
+ if (count_of_rejected_rpc_calls.is_initialized()) {
+ return false;
+ }
+
+ if (count_of_rpcs_sent_in_hmi_none.is_initialized()) {
+ return false;
+ }
+ if (count_of_removals_for_bad_behavior.is_initialized()) {
+ return false;
+ }
+ if (count_of_tls_errors.is_initialized()) {
+ return false;
+ }
+ if (count_of_run_attempts_while_revoked.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void AppLevel::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!minutes_in_hmi_full.is_valid()) {
+ minutes_in_hmi_full.ReportErrors(
+ &report__->ReportSubobject("minutes_in_hmi_full"));
+ }
+ if (!app_registration_language_gui.is_valid()) {
+ app_registration_language_gui.ReportErrors(
+ &report__->ReportSubobject("app_registration_language_gui"));
+ }
+ if (!app_registration_language_vui.is_valid()) {
+ app_registration_language_vui.ReportErrors(
+ &report__->ReportSubobject("app_registration_language_vui"));
+ }
+ if (!minutes_in_hmi_limited.is_valid()) {
+ minutes_in_hmi_limited.ReportErrors(
+ &report__->ReportSubobject("minutes_in_hmi_limited"));
+ }
+ if (!minutes_in_hmi_background.is_valid()) {
+ minutes_in_hmi_background.ReportErrors(
+ &report__->ReportSubobject("minutes_in_hmi_background"));
+ }
+ if (!minutes_in_hmi_none.is_valid()) {
+ minutes_in_hmi_none.ReportErrors(
+ &report__->ReportSubobject("minutes_in_hmi_none"));
+ }
+ if (!count_of_user_selections.is_valid()) {
+ count_of_user_selections.ReportErrors(
+ &report__->ReportSubobject("count_of_user_selections"));
+ }
+ if (!count_of_rejections_sync_out_of_memory.is_valid()) {
+ count_of_rejections_sync_out_of_memory.ReportErrors(
+ &report__->ReportSubobject("count_of_rejections_sync_out_of_memory"));
+ }
+ if (!count_of_rejections_nickname_mismatch.is_valid()) {
+ count_of_rejections_nickname_mismatch.ReportErrors(
+ &report__->ReportSubobject("count_of_rejections_nickname_mismatch"));
+ }
+ if (!count_of_rejections_duplicate_name.is_valid()) {
+ count_of_rejections_duplicate_name.ReportErrors(
+ &report__->ReportSubobject("count_of_rejections_duplicate_name"));
+ }
+ if (!count_of_rejected_rpc_calls.is_valid()) {
+ count_of_rejected_rpc_calls.ReportErrors(
+ &report__->ReportSubobject("count_of_rejected_rpc_calls"));
+ }
+ if (!count_of_rpcs_sent_in_hmi_none.is_valid()) {
+ count_of_rpcs_sent_in_hmi_none.ReportErrors(
+ &report__->ReportSubobject("count_of_rpcs_sent_in_hmi_none"));
+ }
+ if (!count_of_removals_for_bad_behavior.is_valid()) {
+ count_of_removals_for_bad_behavior.ReportErrors(
+ &report__->ReportSubobject("count_of_removals_for_bad_behavior"));
+ }
+ if (!count_of_run_attempts_while_revoked.is_valid()) {
+ count_of_run_attempts_while_revoked.ReportErrors(
+ &report__->ReportSubobject("count_of_run_attempts_while_revoked"));
+ }
+ if (PT_PRELOADED == GetPolicyTableType() ||
+ PT_UPDATE == GetPolicyTableType()) {
+ std::string validation_info =
+ omitted_validation_info + PolicyTableTypeToString(GetPolicyTableType());
+ report__->set_validation_info(validation_info);
+ }
+}
+
+void AppLevel::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ app_registration_language_gui.SetPolicyTableType(pt_type);
+ app_registration_language_vui.SetPolicyTableType(pt_type);
+ minutes_in_hmi_limited.SetPolicyTableType(pt_type);
+ minutes_in_hmi_full.SetPolicyTableType(pt_type);
+ minutes_in_hmi_background.SetPolicyTableType(pt_type);
+ minutes_in_hmi_none.SetPolicyTableType(pt_type);
+ count_of_user_selections.SetPolicyTableType(pt_type);
+ count_of_rejections_sync_out_of_memory.SetPolicyTableType(pt_type);
+ count_of_rejections_nickname_mismatch.SetPolicyTableType(pt_type);
+ count_of_rejections_duplicate_name.SetPolicyTableType(pt_type);
+ count_of_rejected_rpc_calls.SetPolicyTableType(pt_type);
+ count_of_rpcs_sent_in_hmi_none.SetPolicyTableType(pt_type);
+ count_of_removals_for_bad_behavior.SetPolicyTableType(pt_type);
+ count_of_run_attempts_while_revoked.SetPolicyTableType(pt_type);
+}
+
+// UsageAndErrorCounts methods
+UsageAndErrorCounts::UsageAndErrorCounts() : CompositeType(kUninitialized) {}
+
+UsageAndErrorCounts::~UsageAndErrorCounts() {}
+
+UsageAndErrorCounts::UsageAndErrorCounts(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , count_of_iap_buffer_full(
+ impl::ValueMember(value__, "count_of_iap_buffer_full"))
+ , count_sync_out_of_memory(
+ impl::ValueMember(value__, "count_sync_out_of_memory"))
+ , count_of_sync_reboots(impl::ValueMember(value__, "count_of_sync_reboots"))
+ , app_level(impl::ValueMember(value__, "app_level")) {}
+
+Json::Value UsageAndErrorCounts::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField(
+ "count_of_iap_buffer_full", count_of_iap_buffer_full, &result__);
+ impl::WriteJsonField(
+ "count_sync_out_of_memory", count_sync_out_of_memory, &result__);
+ impl::WriteJsonField(
+ "count_of_sync_reboots", count_of_sync_reboots, &result__);
+ impl::WriteJsonField("app_level", app_level, &result__);
+ return result__;
+}
+
+bool UsageAndErrorCounts::is_valid() const {
+ if (struct_empty()) {
+ return initialization_state__ == kInitialized && Validate();
+ }
+ if (!count_of_iap_buffer_full.is_valid()) {
+ return false;
+ }
+ if (!count_sync_out_of_memory.is_valid()) {
+ return false;
+ }
+ if (!count_of_sync_reboots.is_valid()) {
+ return false;
+ }
+ if (!app_level.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool UsageAndErrorCounts::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool UsageAndErrorCounts::struct_empty() const {
+ if (count_of_iap_buffer_full.is_initialized()) {
+ return false;
+ }
+ if (count_sync_out_of_memory.is_initialized()) {
+ return false;
+ }
+
+ if (count_of_sync_reboots.is_initialized()) {
+ return false;
+ }
+ if (app_level.is_initialized()) {
+ return false;
+ }
+
+ return true;
+}
+
+void UsageAndErrorCounts::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (PT_PRELOADED == GetPolicyTableType() ||
+ PT_UPDATE == GetPolicyTableType()) {
+ std::string validation_info =
+ omitted_validation_info + PolicyTableTypeToString(GetPolicyTableType());
+ report__->set_validation_info(validation_info);
+ }
+ if (!count_of_iap_buffer_full.is_valid()) {
+ count_of_iap_buffer_full.ReportErrors(
+ &report__->ReportSubobject("count_of_iap_buffer_full"));
+ }
+ if (!count_sync_out_of_memory.is_valid()) {
+ count_sync_out_of_memory.ReportErrors(
+ &report__->ReportSubobject("count_sync_out_of_memory"));
+ }
+ if (!count_of_sync_reboots.is_valid()) {
+ count_of_sync_reboots.ReportErrors(
+ &report__->ReportSubobject("count_of_sync_reboots"));
+ }
+ if (!app_level.is_valid()) {
+ app_level.ReportErrors(&report__->ReportSubobject("app_level"));
+ }
+}
+
+void UsageAndErrorCounts::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ count_of_iap_buffer_full.SetPolicyTableType(pt_type);
+ count_sync_out_of_memory.SetPolicyTableType(pt_type);
+ count_of_sync_reboots.SetPolicyTableType(pt_type);
+ app_level.SetPolicyTableType(pt_type);
+}
+
+// ConsentRecords methods
+ConsentRecords::ConsentRecords()
+ : CompositeType(kUninitialized)
+ , consent_last_updated(0)
+ , ext_consent_last_updated(0) {}
+
+ConsentRecords::~ConsentRecords() {}
+
+ConsentRecords::ConsentRecords(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , consent_groups(impl::ValueMember(value__, "consent_groups"))
+ , external_consent_status_groups(
+ impl::ValueMember(value__, "external_consent_status_groups"))
+ , input(impl::ValueMember(value__, "input"))
+ , time_stamp(impl::ValueMember(value__, "time_stamp"))
+ , consent_last_updated(0)
+ , ext_consent_last_updated(0) {}
+
+Json::Value ConsentRecords::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("consent_groups", consent_groups, &result__);
+ impl::WriteJsonField("external_consent_status_groups",
+ external_consent_status_groups,
+ &result__);
+ impl::WriteJsonField("input", input, &result__);
+ impl::WriteJsonField("time_stamp", time_stamp, &result__);
+ return result__;
+}
+
+bool ConsentRecords::is_valid() const {
+ if (struct_empty()) {
+ return initialization_state__ == kUninitialized && Validate();
+ }
+ if (!consent_groups.is_valid()) {
+ return false;
+ }
+ if (!external_consent_status_groups.is_valid()) {
+ return false;
+ }
+ if (!input.is_valid()) {
+ return false;
+ }
+ if (!time_stamp.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool ConsentRecords::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool ConsentRecords::struct_empty() const {
+ if (consent_groups.is_initialized()) {
+ return false;
+ }
+
+ if (external_consent_status_groups.is_initialized()) {
+ return false;
+ }
+ if (input.is_initialized()) {
+ return false;
+ }
+
+ if (time_stamp.is_initialized()) {
+ return false;
+ }
+
+ return true;
+}
+
+void ConsentRecords::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!consent_groups.is_valid()) {
+ consent_groups.ReportErrors(&report__->ReportSubobject("consent_groups"));
+ }
+ if (!external_consent_status_groups.is_valid()) {
+ external_consent_status_groups.ReportErrors(
+ &report__->ReportSubobject("external_consent_status_groups"));
+ }
+ if (!input.is_valid()) {
+ input.ReportErrors(&report__->ReportSubobject("input"));
+ }
+ if (!time_stamp.is_valid()) {
+ time_stamp.ReportErrors(&report__->ReportSubobject("time_stamp"));
+ }
+}
+
+void ConsentRecords::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ consent_groups.SetPolicyTableType(pt_type);
+ external_consent_status_groups.SetPolicyTableType(pt_type);
+ input.SetPolicyTableType(pt_type);
+ time_stamp.SetPolicyTableType(pt_type);
+}
+
+// DeviceParams methods
+DeviceParams::DeviceParams() : CompositeType(kUninitialized) {}
+
+DeviceParams::~DeviceParams() {}
+
+DeviceParams::DeviceParams(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , hardware(impl::ValueMember(value__, "hardware"))
+ , firmware_rev(impl::ValueMember(value__, "firmware_rev"))
+ , os(impl::ValueMember(value__, "os"))
+ , os_version(impl::ValueMember(value__, "os_version"))
+ , carrier(impl::ValueMember(value__, "carrier"))
+ , user_consent_records(impl::ValueMember(value__, "user_consent_records"))
+ , max_number_rfcom_ports(
+ impl::ValueMember(value__, "max_number_rfcom_ports"))
+ , connection_type(impl::ValueMember(value__, "connection_type")) {}
+
+Json::Value DeviceParams::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("hardware", hardware, &result__);
+ impl::WriteJsonField("firmware_rev", firmware_rev, &result__);
+ impl::WriteJsonField("os", os, &result__);
+ impl::WriteJsonField("os_version", os_version, &result__);
+ impl::WriteJsonField("carrier", carrier, &result__);
+ impl::WriteJsonField("user_consent_records", user_consent_records, &result__);
+ impl::WriteJsonField(
+ "max_number_rfcom_ports", max_number_rfcom_ports, &result__);
+ impl::WriteJsonField("connection_type", connection_type, &result__);
+ return result__;
+}
+
+bool DeviceParams::is_valid() const {
+ if (struct_empty()) {
+ return initialization_state__ == kInitialized && Validate();
+ }
+ if (!hardware.is_valid()) {
+ return false;
+ }
+ if (!firmware_rev.is_valid()) {
+ return false;
+ }
+ if (!os.is_valid()) {
+ return false;
+ }
+ if (!os_version.is_valid()) {
+ return false;
+ }
+ if (!carrier.is_valid()) {
+ return false;
+ }
+ if (!user_consent_records.is_valid()) {
+ return false;
+ }
+ if (!max_number_rfcom_ports.is_valid()) {
+ return false;
+ }
+ if (!connection_type.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool DeviceParams::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool DeviceParams::struct_empty() const {
+ if (hardware.is_initialized()) {
+ return false;
+ }
+ if (firmware_rev.is_initialized()) {
+ return false;
+ }
+
+ if (os.is_initialized()) {
+ return false;
+ }
+ if (os_version.is_initialized()) {
+ return false;
+ }
+
+ if (carrier.is_initialized()) {
+ return false;
+ }
+ if (user_consent_records.is_initialized()) {
+ return false;
+ }
+
+ if (max_number_rfcom_ports.is_initialized()) {
+ return false;
+ }
+
+ if (connection_type.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void DeviceParams::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!hardware.is_valid()) {
+ hardware.ReportErrors(&report__->ReportSubobject("hardware"));
+ }
+ if (!firmware_rev.is_valid()) {
+ firmware_rev.ReportErrors(&report__->ReportSubobject("firmware_rev"));
+ }
+ if (!os.is_valid()) {
+ os.ReportErrors(&report__->ReportSubobject("os"));
+ }
+ if (!os_version.is_valid()) {
+ os_version.ReportErrors(&report__->ReportSubobject("os_version"));
+ }
+ if (!carrier.is_valid()) {
+ carrier.ReportErrors(&report__->ReportSubobject("carrier"));
+ }
+ if (!user_consent_records.is_valid()) {
+ user_consent_records.ReportErrors(
+ &report__->ReportSubobject("user_consent_records"));
+ }
+ if (!max_number_rfcom_ports.is_valid()) {
+ max_number_rfcom_ports.ReportErrors(
+ &report__->ReportSubobject("max_number_rfcom_ports"));
+ }
+ if (!connection_type.is_valid()) {
+ connection_type.ReportErrors(&report__->ReportSubobject("connection_type"));
+ }
+}
+
+void DeviceParams::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ hardware.SetPolicyTableType(pt_type);
+ firmware_rev.SetPolicyTableType(pt_type);
+ os.SetPolicyTableType(pt_type);
+ os_version.SetPolicyTableType(pt_type);
+ carrier.SetPolicyTableType(pt_type);
+ user_consent_records.SetPolicyTableType(pt_type);
+ max_number_rfcom_ports.SetPolicyTableType(pt_type);
+ connection_type.SetPolicyTableType(pt_type);
+}
+
+// PolicyTable methods
+PolicyTable::PolicyTable() : CompositeType(kUninitialized) {}
+
+PolicyTable::PolicyTable(
+ const ApplicationPoliciesSection& app_policies_section,
+ const FunctionalGroupings& functional_groupings,
+ const ConsumerFriendlyMessages& consumer_friendly_messages,
+ const ModuleConfig& module_config)
+ : CompositeType(kUninitialized)
+ , app_policies_section(app_policies_section)
+ , functional_groupings(functional_groupings)
+ , consumer_friendly_messages(consumer_friendly_messages)
+ , module_config(module_config) {}
+
+PolicyTable::~PolicyTable() {}
+
+PolicyTable::PolicyTable(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , app_policies_section(impl::ValueMember(value__, "app_policies"))
+ , functional_groupings(impl::ValueMember(value__, "functional_groupings"))
+ , consumer_friendly_messages(
+ impl::ValueMember(value__, "consumer_friendly_messages"))
+ , module_config(impl::ValueMember(value__, "module_config"))
+ , module_meta(impl::ValueMember(value__, "module_meta"))
+ , usage_and_error_counts(
+ impl::ValueMember(value__, "usage_and_error_counts"))
+ , device_data(impl::ValueMember(value__, "device_data")) {}
+
+Json::Value PolicyTable::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("app_policies", app_policies_section, &result__);
+ impl::WriteJsonField("functional_groupings", functional_groupings, &result__);
+ impl::WriteJsonField(
+ "consumer_friendly_messages", consumer_friendly_messages, &result__);
+ impl::WriteJsonField("module_config", module_config, &result__);
+ impl::WriteJsonField("module_meta", module_meta, &result__);
+ impl::WriteJsonField(
+ "usage_and_error_counts", usage_and_error_counts, &result__);
+ impl::WriteJsonField("device_data", device_data, &result__);
+ return result__;
+}
+
+bool PolicyTable::is_valid() const {
+ if (!app_policies_section.is_valid()) {
+ return false;
+ }
+ if (!functional_groupings.is_valid()) {
+ return false;
+ }
+ if (!consumer_friendly_messages.is_valid()) {
+ return false;
+ }
+ if (!module_config.is_valid()) {
+ return false;
+ }
+ if (!module_meta.is_valid()) {
+ return false;
+ }
+ if (!usage_and_error_counts.is_valid()) {
+ return false;
+ }
+ if (!device_data.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool PolicyTable::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool PolicyTable::struct_empty() const {
+ if (app_policies_section.is_initialized()) {
+ return false;
+ }
+ if (functional_groupings.is_initialized()) {
+ return false;
+ }
+
+ if (consumer_friendly_messages.is_initialized()) {
+ return false;
+ }
+ if (module_config.is_initialized()) {
+ return false;
+ }
+
+ if (module_meta.is_initialized()) {
+ return false;
+ }
+ if (usage_and_error_counts.is_initialized()) {
+ return false;
+ }
+
+ if (device_data.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void PolicyTable::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (PT_PRELOADED == GetPolicyTableType() ||
+ PT_UPDATE == GetPolicyTableType()) {
+ std::string validation_info =
+ omitted_validation_info + PolicyTableTypeToString(GetPolicyTableType());
+
+ if (device_data.is_initialized()) {
+ report__->ReportSubobject("device_data")
+ .set_validation_info(validation_info);
+ }
+ }
+ if (!app_policies_section.is_valid()) {
+ app_policies_section.ReportErrors(
+ &report__->ReportSubobject("app_policies"));
+ }
+ if (!functional_groupings.is_valid()) {
+ functional_groupings.ReportErrors(
+ &report__->ReportSubobject("functional_groupings"));
+ }
+ if (!consumer_friendly_messages.is_valid()) {
+ consumer_friendly_messages.ReportErrors(
+ &report__->ReportSubobject("consumer_friendly_messages"));
+ }
+ if (!module_config.is_valid()) {
+ module_config.ReportErrors(&report__->ReportSubobject("module_config"));
+ }
+ if (!module_meta.is_valid()) {
+ module_meta.ReportErrors(&report__->ReportSubobject("module_meta"));
+ }
+ if (!usage_and_error_counts.is_valid()) {
+ usage_and_error_counts.ReportErrors(
+ &report__->ReportSubobject("usage_and_error_counts"));
+ }
+ if (!device_data.is_valid()) {
+ device_data.ReportErrors(&report__->ReportSubobject("device_data"));
+ }
+}
+
+void PolicyTable::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ app_policies_section.SetPolicyTableType(pt_type);
+ functional_groupings.SetPolicyTableType(pt_type);
+ consumer_friendly_messages.SetPolicyTableType(pt_type);
+ module_config.SetPolicyTableType(pt_type);
+ module_meta.SetPolicyTableType(pt_type);
+ usage_and_error_counts.SetPolicyTableType(pt_type);
+ device_data.SetPolicyTableType(pt_type);
+}
+
+// Table methods
+Table::Table() : CompositeType(kUninitialized) {}
+
+Table::Table(const PolicyTable& policy_table)
+ : CompositeType(kUninitialized), policy_table(policy_table) {}
+
+Table::~Table() {}
+
+Table::Table(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , policy_table(impl::ValueMember(value__, "policy_table")) {}
+
+Json::Value Table::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("policy_table", policy_table, &result__);
+ return result__;
+}
+
+bool Table::is_valid() const {
+ if (!policy_table.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool Table::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool Table::struct_empty() const {
+ if (policy_table.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void Table::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!policy_table.is_valid()) {
+ policy_table.ReportErrors(&report__->ReportSubobject("policy_table"));
+ }
+}
+
+void Table::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ policy_table.SetPolicyTableType(pt_type);
+}
+
+RequestTypes::RequestTypes() : RequestsTypeArray(), is_cleaned_up_(false) {}
+
+RequestTypes::RequestTypes(Json::Value* value)
+ : RequestsTypeArray(value), is_cleaned_up_(false) {}
+
+RequestTypes::RequestTypes(const Json::Value* value)
+ : RequestsTypeArray(value), is_cleaned_up_(false) {}
+
+void RequestTypes::CleanUp() {
+ if (!this->size()) {
+ return;
+ }
+ this->erase(
+ std::remove_if(
+ this->begin(),
+ this->end(),
+ std::not1(std::mem_fun_ref(&RequestTypes::value_type::is_valid))),
+ this->end());
+
+ is_cleaned_up_ = !this->size();
+}
+
+bool RequestTypes::is_valid() const {
+ // Array size must be within allowed range
+ if (!Range<size_t>(0, 255).Includes(this->size())) {
+ return false;
+ }
+ RequestTypes::const_iterator it = std::find_if(
+ this->begin(),
+ this->end(),
+ std::not1(std::mem_fun_ref(&RequestTypes::value_type::is_valid)));
+ if (this->end() != it) {
+ return false;
+ }
+ return true;
+}
+
+bool RequestTypes::is_omitted() const {
+ return this->empty() && !this->is_initialized();
+}
+
+bool RequestTypes::is_empty() const {
+ return this->empty() && this->is_initialized();
+}
+
+bool RequestTypes::is_cleaned_up() const {
+ return is_cleaned_up_;
+}
+
+ExternalConsentEntity::ExternalConsentEntity()
+ : CompositeType(kUninitialized)
+ , entity_type(INT32_MAX)
+ , entity_id(INT32_MAX) {}
+
+ExternalConsentEntity::ExternalConsentEntity(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , entity_type(impl::ValueMember(value__, "entityType"))
+ , entity_id(impl::ValueMember(value__, "entityID")) {}
+
+ExternalConsentEntity::ExternalConsentEntity(const int32_t type,
+ const int32_t id)
+ : CompositeType(kInitialized), entity_type(type), entity_id(id) {}
+
+Json::Value ExternalConsentEntity::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("entityType", entity_type, &result__);
+ impl::WriteJsonField("entityID", entity_id, &result__);
+ return result__;
+}
+
+bool ExternalConsentEntity::operator==(const ExternalConsentEntity& rhs) const {
+ return rhs.entity_id == this->entity_id &&
+ rhs.entity_type == this->entity_type;
+}
+
+bool ExternalConsentEntity::is_valid() const {
+ if (!is_initialized()) {
+ return false;
+ }
+ if (!entity_type.is_valid()) {
+ return false;
+ }
+ if (!entity_id.is_valid()) {
+ return false;
+ }
+ return true;
+}
+
+bool ExternalConsentEntity::is_initialized() const {
+ return kInitialized == initialization_state__;
+}
+
+void ExternalConsentEntity::ReportErrors(ValidationReport* report__) const {
+ if (!entity_type.is_valid()) {
+ entity_type.ReportErrors(&report__->ReportSubobject("entityType"));
+ }
+ if (!entity_id.is_valid()) {
+ entity_id.ReportErrors(&report__->ReportSubobject("entityID"));
+ }
+}
+
+void ExternalConsentEntity::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ entity_type.SetPolicyTableType(pt_type);
+ entity_id.SetPolicyTableType(pt_type);
+}
+
+} // namespace policy_table_interface_base
+} // namespace rpc
diff --git a/src/components/policy/policy_external/src/policy_table/validation.cc b/src/components/policy/policy_external/src/policy_table/validation.cc
new file mode 100644
index 0000000000..45034c6fe8
--- /dev/null
+++ b/src/components/policy/policy_external/src/policy_table/validation.cc
@@ -0,0 +1,256 @@
+#include <iostream>
+#include <algorithm>
+#include "policy/policy_table/types.h"
+#include "utils/logger.h"
+#include "utils/helpers.h"
+
+namespace {
+bool IsPredefinedApplication(const std::string& app_id) {
+ using namespace rpc::policy_table_interface_base;
+ return kPreDataConsentApp == app_id || kDefaultApp == app_id;
+}
+}
+
+namespace rpc {
+namespace policy_table_interface_base {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Policy")
+
+bool VerifyPredefinedApp(ApplicationPolicies::value_type& app_policies) {
+ const std::string& app_id = app_policies.first;
+ if (!IsPredefinedApplication(app_id)) {
+ return true;
+ }
+
+ RequestTypes& predefined_request_types = *app_policies.second.RequestType;
+
+ if (!predefined_request_types.is_valid()) {
+ LOG4CXX_WARN(logger_,
+ app_id << " policy invalid RequestTypes will be cleaned.");
+ predefined_request_types.CleanUp();
+ if (PT_PRELOADED == app_policies.second.GetPolicyTableType() &&
+ predefined_request_types.is_cleaned_up()) {
+ LOG4CXX_ERROR(
+ logger_,
+ app_id << " policy RequestTypes is empty after clean-up. Exiting.");
+ return false;
+ }
+
+ LOG4CXX_WARN(logger_, app_id << " request types have cleaned up.");
+ }
+ return true;
+}
+
+bool PolicyBase::Validate() const {
+ // Check for empty "groups" sub-sections
+ if (groups.empty()) {
+ return false;
+ }
+ return true;
+}
+
+bool ApplicationPoliciesSection::Validate() const {
+ ApplicationPolicies::iterator it_default_policy = apps.find(kDefaultApp);
+ ApplicationPolicies::iterator it_pre_data_policy =
+ apps.find(kPreDataConsentApp);
+
+ // Default and PreData policies are mandatory
+ if (apps.end() == it_default_policy || apps.end() == it_pre_data_policy) {
+ LOG4CXX_ERROR(logger_, "Default or preData policy is not present.");
+ return false;
+ }
+
+ // Device policy is mandatory
+ if (!device.is_initialized()) {
+ LOG4CXX_ERROR(logger_, "Device policy is not present.");
+ return false;
+ }
+
+ PolicyTableType pt_type = GetPolicyTableType();
+ if (PT_PRELOADED != pt_type && PT_UPDATE != pt_type) {
+ return true;
+ }
+
+ if (!VerifyPredefinedApp(*it_default_policy)) {
+ return false;
+ }
+
+ if (!VerifyPredefinedApp(*it_pre_data_policy)) {
+ return false;
+ }
+
+ ApplicationPolicies::iterator iter = apps.begin();
+ ApplicationPolicies::iterator end_iter = apps.end();
+
+ while (iter != end_iter) {
+ const std::string app_id = iter->first;
+ if (IsPredefinedApplication(app_id)) {
+ ++iter;
+ continue;
+ }
+
+ RequestTypes& app_request_types = *iter->second.RequestType;
+
+ if (app_request_types.is_omitted()) {
+ LOG4CXX_WARN(logger_,
+ "RequestTypes omitted for "
+ << app_id << " Will be replaced with default.");
+ app_request_types = *apps[kDefaultApp].RequestType;
+ ++iter;
+ continue;
+ }
+
+ if (!app_request_types.is_valid()) {
+ LOG4CXX_WARN(logger_,
+ "Invalid RequestTypes for " << app_id
+ << " Will be cleaned up.");
+ app_request_types.CleanUp();
+ if (app_request_types.is_cleaned_up()) {
+ if (PT_PRELOADED == pt_type) {
+ LOG4CXX_ERROR(logger_,
+ "RequestTypes empty after clean-up for "
+ << app_id << " Exiting.");
+ return false;
+ }
+
+ LOG4CXX_WARN(logger_,
+ "RequestTypes empty after clean-up for "
+ << app_id << " Will be replaced with default.");
+
+ app_request_types = *apps[kDefaultApp].RequestType;
+ }
+
+ LOG4CXX_DEBUG(logger_, "Clean up for " << app_id << " is done.");
+
+ ++iter;
+ continue;
+ }
+
+ if (app_request_types.is_empty()) {
+ LOG4CXX_WARN(logger_, "RequestTypes is empty for " << app_id);
+ }
+
+ ++iter;
+ }
+
+ return true;
+}
+bool ApplicationParams::Validate() const {
+ if (is_initialized()) {
+ if (preconsented_groups.is_initialized()) {
+ const Strings& all = groups;
+ const Strings& preconsented = *preconsented_groups;
+ if (preconsented.size() > all.size()) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+bool RpcParameters::Validate() const {
+ return true;
+}
+bool Rpcs::Validate() const {
+ return true;
+}
+bool ModuleConfig::Validate() const {
+ switch (GetPolicyTableType()) {
+ case PT_PRELOADED: {
+ if (helpers::Compare<bool, helpers::EQ, helpers::ONE>(
+ true,
+ vehicle_make.is_initialized(),
+ vehicle_year.is_initialized(),
+ vehicle_model.is_initialized())) {
+ return false;
+ }
+ break;
+ }
+ case PT_UPDATE: {
+ if (preloaded_pt->is_initialized()) {
+ return false;
+ }
+ if (preloaded_date->is_initialized()) {
+ return false;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return true;
+}
+
+bool MessageString::Validate() const {
+ return true;
+}
+bool MessageLanguages::Validate() const {
+ if (PT_SNAPSHOT == GetPolicyTableType()) {
+ return false;
+ }
+ return true;
+}
+bool ConsumerFriendlyMessages::Validate() const {
+ return true;
+}
+bool ModuleMeta::Validate() const {
+ if (GetPolicyTableType() == PT_UPDATE ||
+ GetPolicyTableType() == PT_PRELOADED) {
+ return false;
+ }
+ return true;
+}
+bool AppLevel::Validate() const {
+ if (PT_PRELOADED == GetPolicyTableType() ||
+ PT_UPDATE == GetPolicyTableType()) {
+ return false;
+ }
+ return true;
+}
+bool UsageAndErrorCounts::Validate() const {
+ if (PT_PRELOADED == GetPolicyTableType() ||
+ PT_UPDATE == GetPolicyTableType()) {
+ return false;
+ }
+ return true;
+}
+bool ConsentRecords::Validate() const {
+ if (PT_SNAPSHOT != GetPolicyTableType()) {
+ return !external_consent_status_groups->is_initialized();
+ }
+
+ return true;
+}
+bool DeviceParams::Validate() const {
+ return true;
+}
+bool PolicyTable::Validate() const {
+ PolicyTableType policy_table_type = GetPolicyTableType();
+
+ if (PT_PRELOADED == policy_table_type || PT_UPDATE == policy_table_type) {
+ if (device_data.is_initialized()) {
+ return false;
+ }
+ }
+
+ if (PT_PRELOADED == policy_table_type || PT_SNAPSHOT == policy_table_type) {
+ // Check upper bound of each "groups" sub section in the app policies
+ const FunctionalGroupings::size_type functional_groupings_count =
+ functional_groupings.size();
+ for (ApplicationPolicies::const_iterator app_policiies_it =
+ app_policies_section.apps.begin();
+ app_policies_section.apps.end() != app_policiies_it;
+ ++app_policiies_it) {
+ if (app_policiies_it->second.groups.size() > functional_groupings_count) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool Table::Validate() const {
+ return true;
+}
+} // namespace policy_table_interface_base
+} // namespace rpc
diff --git a/src/components/policy/policy_external/src/sql_pt_ext_queries.cc b/src/components/policy/policy_external/src/sql_pt_ext_queries.cc
new file mode 100644
index 0000000000..afb1180692
--- /dev/null
+++ b/src/components/policy/policy_external/src/sql_pt_ext_queries.cc
@@ -0,0 +1,299 @@
+/*
+ Copyright (c) 2013, " Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, " with or without
+ modification, " are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, " this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, "
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, " INCLUDING, " BUT NOT LIMITED TO, " THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, " INDIRECT, " INCIDENTAL, " SPECIAL, " EXEMPLARY, " OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, " BUT NOT LIMITED TO, " PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, " DATA, " OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, " WHETHER IN
+ CONTRACT, " STRICT LIABILITY, " OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, " EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "policy/sql_pt_ext_queries.h"
+
+namespace policy {
+namespace sql_pt_ext {
+
+const std::string kSelectKeepContext =
+ "SELECT `keep_context` FROM `application` WHERE `id` = ? LIMIT 1";
+
+const std::string kSelectStealFocus =
+ "SELECT `steal_focus` FROM `application` WHERE `id` = ? LIMIT 1";
+
+const std::string kSelectDefaultHmi =
+ "SELECT `default_hmi` FROM `application` WHERE `id` = ? LIMIT 1";
+
+const std::string kResetDeviceConsents = "DELETE FROM `device_consent_group`";
+
+const std::string kResetAppConsents = "DELETE FROM `consent_group`";
+
+const std::string kCountDeviceConsentGroup =
+ "SELECT COUNT (`device_id`) "
+ "FROM `device_consent_group` WHERE `device_id` = ?";
+
+const std::string kCountDevice =
+ "SELECT COUNT (`id`) "
+ "FROM `device` WHERE `id` = ?";
+
+const std::string kSelectDeviceConsentedGroup =
+ "SELECT * FROM `device_consent_group` WHERE `device_id` = ?";
+
+const std::string kUpdateDeviceConsentedGroup =
+ "UPDATE `device_consent_group` SET `is_consented` = ?, `input` = ? WHERE "
+ "(`device_id` = ? AND `functional_group_id` = ?)";
+
+const std::string kUpdateDevice =
+ "UPDATE `device` SET `hardware` = ?, `firmware_rev` = ?, `os` = ?, "
+ "`os_version` = ?, `carrier` = ?, `max_number_rfcom_ports` = ?, "
+ " `connection_type` = ? WHERE `id` = ? ";
+
+const std::string kInsertDeviceConsentedGroup =
+ "INSERT OR REPLACE INTO `device_consent_group` "
+ "(`device_id`, `functional_group_id`, `is_consented`, `input`, "
+ "`time_stamp`) "
+ "VALUES (?,?,?,?,?)";
+
+const std::string kInsertDevice =
+ "INSERT OR IGNORE INTO `device` "
+ "(`id`, `hardware`, `firmware_rev`, `os`, `os_version`, `carrier`,"
+ "`max_number_rfcom_ports`, `connection_type`) "
+ "VALUES (?,?,?,?,?,?,?,?)";
+
+const std::string kSelectDeviceData = "SELECT * FROM `device`";
+
+const std::string kSelectConsentGroup =
+ "SELECT * FROM `consent_group` WHERE `device_id` = ? ";
+
+const std::string kSelectExternalConsentStatusGroup =
+ "SELECT * FROM `external_consent_status_group` WHERE `device_id` = ? ";
+
+const std::string kInsertPreconsentedGroups =
+ "INSERT INTO `preconsented_group` (`application_id`, `functional_group_id`)"
+ " SELECT ?, `id` FROM `functional_group` WHERE `name` = ? LIMIT 1";
+
+const std::string kSelectPreconsentedGroups =
+ "SELECT `f`.`name` FROM `preconsented_group` AS `p`"
+ " LEFT JOIN `functional_group` AS `f` "
+ " ON (`f`.`id` = `p`.`functional_group_id`)"
+ " WHERE `p`.`application_id` = ?";
+
+const std::string kDeletePreconsentedGroups =
+ "DELETE FROM `preconsented_group`";
+
+const std::string kSelectUsageAndErrorCount =
+ "SELECT `count_of_iap_buffer_full`, `count_sync_out_of_memory`, "
+ " `count_of_sync_reboots` "
+ "FROM `usage_and_error_count` LIMIT 1";
+
+const std::string kSelectAppLevels =
+ "SELECT `application_id`, `minutes_in_hmi_full`, `minutes_in_hmi_limited`, "
+ " `minutes_in_hmi_background`, `minutes_in_hmi_none`, "
+ " `count_of_user_selections`, "
+ " `count_of_rejections_sync_out_of_memory`, "
+ " `count_of_rejections_nickname_mismatch`, "
+ " `count_of_rejections_duplicate_name`, "
+ " `count_of_rejected_rpcs_calls`, "
+ " `count_of_rpcs_sent_in_hmi_none`, "
+ " `count_of_removals_for_bad_behavior`, "
+ " `count_of_run_attempts_while_revoked`, "
+ " `app_registration_language_gui`, "
+ " `app_registration_language_vui`, "
+ " `count_of_tls_errors` "
+ "FROM `app_level`";
+
+const std::string kUpdateGlobalCounters =
+ "UPDATE `usage_and_error_count` SET "
+ "`count_of_iap_buffer_full` = ?, "
+ "`count_sync_out_of_memory` = ?, "
+ "`count_of_sync_reboots` = ? ";
+
+const std::string kInsertDeviceData =
+ "INSERT OR IGNORE INTO `device` "
+ "(`id`, `hardware`, `firmware_rev`, `os`, `os_version`, `carrier`, "
+ "`max_number_rfcom_ports`,`connection_type`) VALUES (?,?,?,?,?,?,?,?) ";
+
+const std::string kInsertConsentGroups =
+ "INSERT OR REPLACE INTO `consent_group` "
+ "(`device_id`, `application_id`, `functional_group_id`, `is_consented`, "
+ "`input`, `time_stamp`, `last_updated`) "
+ "VALUES (?,?,?,?,?,?,?)";
+
+const std::string kInsertExternalConsentStatusGroups =
+ "INSERT OR REPLACE INTO `external_consent_status_group` "
+ "(`device_id`, `application_id`, `functional_group_id`, `is_consented`, "
+ "`input`, `time_stamp`, `last_updated`) "
+ "VALUES (?,?,?,?,?,?,?)";
+
+const std::string kDeleteAppGroupConsent =
+ "DELETE FROM `consent_group` WHERE "
+ "`application_id` = ? AND `functional_group_id` = ? ";
+
+const std::string kSelectGroupId =
+ "SELECT `id` FROM `functional_group` WHERE `name` = ? ";
+
+const std::string kCountUnconsentedGroups =
+ "SELECT COUNT(`a`.`functional_group_id`) FROM `app_group` AS `a` "
+ " WHERE `a`.`application_id` = ? AND NOT EXISTS "
+ " (SELECT NULL FROM `preconsented_group` AS `p` WHERE "
+ " (`p`.`functional_group_id` = `a`.`functional_group_id` AND "
+ " `p`.`application_id` = `a`.`application_id`)) "
+ " AND NOT EXISTS (SELECT NULL FROM `consent_group` AS `c` "
+ " WHERE (`c`.`application_id` = `a`.`application_id` "
+ " AND `c`.`functional_group_id` = `a`.`functional_group_id` "
+ " AND `c`.`device_id` = ?)) AND NOT EXISTS "
+ " (SELECT NULL FROM `app_group` AS `def` WHERE "
+ " (`def`.`application_id` = ? OR "
+ " `def`.`application_id` = ?) "
+ " AND `def`.`functional_group_id` = `a`.`functional_group_id`)"
+ " AND NOT EXISTS (SELECT NULL FROM `functional_group` AS `f` "
+ " WHERE (`a`.`functional_group_id` = `f`.`id`"
+ " AND`f`.`user_consent_prompt` IS NULL))";
+
+const std::string kSelectModuleMeta = "SELECT* FROM `module_meta`";
+
+const std::string kUpdateMetaParams =
+ "UPDATE `module_meta` SET "
+ "`ccpu_version` = ?, `wers_country_code` = ?, `language` = ? ";
+
+const std::string kUpdateModuleMetaVinParam =
+ "UPDATE `module_meta` SET `vin` = ? ";
+
+const std::string kSaveModuleMeta =
+ "UPDATE `module_meta` SET `ccpu_version` = ?, `language` = ?,"
+ "`wers_country_code` = ?, `pt_exchanged_at_odometer_x` = ?,"
+ "`pt_exchanged_x_days_after_epoch` = ?,"
+ "`ignition_cycles_since_last_exchange` = ?, `vin` = ?";
+
+const std::string kSelectMetaParams =
+ "SELECT `ccpu_version`, "
+ "`wers_country_code`, `language` from `module_meta`";
+
+const std::string kUpdateMetaLanguage =
+ "UPDATE `module_meta` SET `language` = ? ";
+
+const std::string kCountAppLevel =
+ "SELECT COUNT(`application_id`) FROM `app_level`"
+ " WHERE `application_id` = ? ";
+
+const std::string kUpdateGroupPermissions =
+ "UPDATE `consent_group` "
+ "SET `is_consented` = ?, `input` = ? "
+ "WHERE(`application_id` = ? AND `functional_group_id` = ? AND `device_id` "
+ "= ?) ";
+
+const std::string kInsertApplication =
+ "INSERT OR IGNORE INTO `application`(`id`, `keep_context`, `steal_focus`, "
+ " `default_hmi`, `priority_value`, `is_revoked`, `memory_kb`, "
+ " `heart_beat_timeout_ms`) VALUES( ?, ?, ?, ?, ?, ?, ?, ?) ";
+
+const std::string kCollectFriendlyMsg = "SELECT * FROM `message`";
+
+const std::string kSelectFriendlyMsg =
+ "SELECT `tts`, `label`, `line1`, `line2`, `textBody` FROM `message` "
+ "WHERE `message_type_name` = ? AND `language_code` = ? LIMIT 1";
+
+const std::string kSelectAppGroupsId =
+ "SELECT `functional_group_id` "
+ "FROM `app_group` WHERE `application_id` = ? ";
+
+const std::string kSelectConsentedGroupsId =
+ "SELECT `functional_group_id`, `is_consented` "
+ "FROM `consent_group` WHERE(`application_id` = ? AND `device_id` = ?) ";
+
+const std::string kCountAppConsents =
+ "SELECT COUNT(*) from `consent_group`"
+ "WHERE(`device_id` = ? AND `application_id` = ? AND "
+ "`functional_group_id` = ?) ";
+
+const std::string kSelectPreconsentedGroupsId =
+ "SELECT `functional_group_id` "
+ "FROM `preconsented_group` WHERE `application_id` = ? ";
+
+const std::string kSelectAppPolicies =
+ "SELECT `id`, `priority_value`, `default_hmi`, `keep_context`, "
+ "`steal_focus`, "
+ " `memory_kb`, `heart_beat_timeout_ms` FROM `application`";
+
+const std::string kSelectFunctionalGroupNames =
+ "SELECT `id`, `user_consent_prompt`, `name`"
+ " FROM `functional_group`";
+
+const std::string kDeleteDeviceConsent =
+ "DELETE FROM `device_consent_group` "
+ "WHERE `device_id` = ? ";
+
+const std::string kDeleteAppConsent =
+ "DELETE FROM `consent_group` "
+ "WHERE `device_id` = ? ";
+
+const std::string kSelectApplicationIsPreData =
+ "SELECT `is_predata` FROM `application` WHERE `id` = ? ";
+
+const std::string kUpdateIsPredata =
+ "UPDATE `application` SET `is_predata` = ? WHERE `id` = ? ";
+
+const std::string kHasAppPreloadedGroups =
+ "SELECT COUNT(`a1`.`functional_group_id`) FROM `app_group` "
+ " AS `a1` JOIN `app_group` AS `a2` "
+ " ON `a1`.`functional_group_id` = `a2`.`functional_group_id` "
+ " WHERE `a1`.`application_id` = ? AND `a2`.`application_id` = ? ";
+
+const std::string kUpdateUnpairedDevice =
+ "UPDATE `device` SET `unpaired` = ? WHERE `id` = ? ";
+
+const std::string kSelectUnpairedDevices =
+ "SELECT `id` FROM `device` WHERE `unpaired` = 1";
+
+const std::string kHasMsgLanguageCode =
+ "SELECT COUNT (`id`) FROM message "
+ "WHERE `message_type_name` = ? AND `language_code` = ? ";
+
+const std::string kDeletePreconsentedGroupsByApplicationId =
+ "DELETE FROM `preconsented_group` WHERE `application_id` = ?";
+
+const std::string kSelectExternalConsentStatus =
+ "SELECT `entity_type`, `entity_id`, `on_off` from "
+ "`_internal_external_consent_status`";
+
+const std::string kInsertExternalConsentStatus =
+ "INSERT OR REPLACE INTO `_internal_external_consent_status` "
+ "(`id`,`entity_type`, "
+ "`entity_id`, `on_off`) VALUES ((SELECT `id` from "
+ "`_internal_external_consent_status` "
+ "WHERE `entity_type` = ? AND `entity_id` = ?), ?, ?, ?)";
+
+const std::string kDeleteExternalConsentEntities =
+ "DELETE FROM `external_consent_entities`";
+
+const std::string kInsertExternalConsentEntity =
+ "INSERT INTO `external_consent_entities` (`group_id`, `entity_type`, "
+ "`entity_id`, `on_off`) "
+ " VALUES (?, ?, ?, ?)";
+
+const std::string kSelectExternalConsentEntity =
+ "SELECT `group_id`, `entity_type`, `entity_id`, `on_off` from "
+ "`external_consent_entities`";
+
+} // namespace sql_pt_ext
+} // namespace policy
diff --git a/src/components/policy/policy_external/src/sql_pt_ext_representation.cc b/src/components/policy/policy_external/src/sql_pt_ext_representation.cc
new file mode 100644
index 0000000000..f58a7f0b82
--- /dev/null
+++ b/src/components/policy/policy_external/src/sql_pt_ext_representation.cc
@@ -0,0 +1,1937 @@
+/*
+ Copyright (c) 2015, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <algorithm>
+#include <utility>
+#include "utils/logger.h"
+#include "policy/sql_pt_ext_representation.h"
+#include "policy/sql_wrapper.h"
+#include "policy/sql_pt_queries.h"
+#include "policy/sql_pt_ext_queries.h"
+#include "policy/policy_helper.h"
+#include "policy/cache_manager.h"
+
+namespace policy {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Policy")
+
+SQLPTExtRepresentation::SQLPTExtRepresentation() {}
+SQLPTExtRepresentation::SQLPTExtRepresentation(bool in_memory)
+ : SQLPTRepresentation(in_memory) {}
+
+bool SQLPTExtRepresentation::CanAppKeepContext(const std::string& app_id) {
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt_ext::kSelectKeepContext)) {
+ query.Bind(0, app_id);
+ if (query.Exec()) {
+ return query.GetBoolean(0);
+ }
+ }
+ return false;
+}
+
+bool SQLPTExtRepresentation::CanAppStealFocus(const std::string& app_id) {
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt_ext::kSelectStealFocus)) {
+ query.Bind(0, app_id);
+ if (query.Exec()) {
+ return query.GetBoolean(0);
+ }
+ }
+ return false;
+}
+
+bool SQLPTExtRepresentation::ResetUserConsent() {
+ return ResetDeviceConsents() && ResetAppConsents();
+}
+
+bool SQLPTExtRepresentation::ResetDeviceConsents() {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kResetDeviceConsents)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete statement from device_consents.");
+ return false;
+ }
+ return query.Exec();
+}
+
+bool SQLPTExtRepresentation::ResetAppConsents() {
+ return utils::dbms::SQLQuery(db()).Exec(sql_pt_ext::kResetAppConsents);
+}
+
+bool SQLPTExtRepresentation::GetUserPermissionsForDevice(
+ const std::string& device_id,
+ StringArray* consented_groups,
+ StringArray* disallowed_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectDeviceConsentedGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from device consented groups");
+ return false;
+ }
+ query.Bind(0, device_id);
+ while (query.Next()) {
+ if (query.GetBoolean(2)) {
+ if (!consented_groups) {
+ continue;
+ }
+ consented_groups->push_back(query.GetString(1));
+ } else {
+ if (!disallowed_groups) {
+ continue;
+ }
+ disallowed_groups->push_back(query.GetString(1));
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetPermissionsForApp(
+ const std::string& device_id,
+ const std::string& policy_app_id,
+ FunctionalIdType* group_types) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (!group_types) {
+ LOG4CXX_WARN(logger_, "Input parameter for group types is null.");
+ return false;
+ }
+ // Get all app groups for specified device and application
+ FunctionalGroupIDs all_groups;
+ if (!GetAllAppGroups(policy_app_id, all_groups)) {
+ return false;
+ }
+ // Get preconsented group
+ FunctionalGroupIDs preconsented_groups;
+ if (!GetPreconsentedGroups(policy_app_id, preconsented_groups)) {
+ return false;
+ }
+ // Get consented (allowed/disallowed) groups
+ FunctionalGroupIDs allowed_groups;
+ FunctionalGroupIDs disallowed_groups;
+ if (!GetConsentedGroups(
+ policy_app_id, device_id, allowed_groups, disallowed_groups)) {
+ return false;
+ }
+ // Get all default groups
+ FunctionalGroupIDs default_groups;
+ if (!GetAllAppGroups(kDefaultId, default_groups)) {
+ return false;
+ }
+
+ // Get all pre_DataConsent groups
+ FunctionalGroupIDs predataconsented_groups;
+ if (!GetAllAppGroups(kPreDataConsentId, predataconsented_groups)) {
+ return false;
+ }
+
+ // Get all device groups
+ FunctionalGroupIDs device_groups;
+ if (!GetAllAppGroups(kDeviceId, device_groups)) {
+ return false;
+ }
+
+ (*group_types)[kTypeDefault] = default_groups;
+ (*group_types)[kTypeAllowed] = allowed_groups;
+ (*group_types)[kTypeDisallowed] = disallowed_groups;
+ (*group_types)[kTypePreconsented] = preconsented_groups;
+ (*group_types)[kTypeGeneral] = all_groups;
+ (*group_types)[kTypePreDataConsented] = predataconsented_groups;
+ (*group_types)[kTypeDevice] = device_groups;
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetDeviceGroupsFromPolicies(
+ policy_table::Strings* groups, policy_table::Strings* preconsented_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (groups) {
+ GatherAppGroup(kDeviceId, groups);
+ }
+ if (preconsented_groups) {
+ GatherPreconsentedGroup(kDeviceId, preconsented_groups);
+ }
+ return true;
+}
+
+bool SQLPTExtRepresentation::SetDeviceData(const std::string& device_id,
+ const std::string& hardware,
+ const std::string& firmware,
+ const std::string& os,
+ const std::string& os_version,
+ const std::string& carrier,
+ const uint32_t number_of_ports,
+ const std::string& connection_type) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery count_query(db());
+ if (!count_query.Prepare(sql_pt_ext::kCountDevice)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for count of device.");
+ return false;
+ }
+
+ count_query.Bind(0, device_id);
+
+ if (!count_query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect count of device.");
+ return false;
+ }
+
+ bool update = count_query.GetInteger(0);
+
+ // Update old value
+ if (update) {
+ utils::dbms::SQLQuery update_query(db());
+ if (!update_query.Prepare(sql_pt_ext::kUpdateDevice)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for udpate device.");
+ return false;
+ }
+
+ update_query.Bind(0, hardware);
+ update_query.Bind(1, firmware);
+ update_query.Bind(2, os);
+ update_query.Bind(3, os_version);
+ update_query.Bind(4, carrier);
+ update_query.Bind(5, static_cast<int>(number_of_ports));
+ update_query.Bind(6, device_id);
+ update_query.Bind(7, connection_type);
+
+ if (!update_query.Exec() || !update_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect update for device.");
+ return false;
+ }
+
+ return true;
+ }
+
+ // Insert new data
+ utils::dbms::SQLQuery insert_query(db());
+ if (!insert_query.Prepare(sql_pt_ext::kInsertDevice)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for device.");
+ return false;
+ }
+
+ insert_query.Bind(0, device_id);
+ insert_query.Bind(1, hardware);
+ insert_query.Bind(2, firmware);
+ insert_query.Bind(3, os);
+ insert_query.Bind(4, os_version);
+ insert_query.Bind(5, carrier);
+ insert_query.Bind(6, static_cast<int>(number_of_ports));
+ insert_query.Bind(7, connection_type);
+
+ if (!insert_query.Exec() || !insert_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert to device.");
+ return false;
+ }
+
+ SetPreloaded(false);
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SetUserPermissionsForDevice(
+ const std::string& device_id,
+ const StringArray& consented_groups,
+ const StringArray& disallowed_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery count_query(db());
+ if (!count_query.Prepare(sql_pt_ext::kCountDeviceConsentGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect count of device consented groups");
+ return false;
+ }
+
+ count_query.Bind(0, device_id);
+
+ if (!count_query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed count of device consented groups");
+ return false;
+ }
+
+ bool update = count_query.GetInteger(0);
+
+ // TODO(AOleynik): Split to several methods?
+ utils::dbms::SQLQuery query(db());
+ // Update old values
+ if (update) {
+ if (!query.Prepare(sql_pt_ext::kUpdateDeviceConsentedGroup)) {
+ LOG4CXX_WARN(
+ logger_,
+ "Incorrect statement for updating consented groups on device");
+ return false;
+ }
+
+ StringArray::const_iterator it_consented_groups = consented_groups.begin();
+ StringArray::const_iterator it_consented_groups_end =
+ consented_groups.end();
+ for (; it_consented_groups != it_consented_groups_end;
+ ++it_consented_groups) {
+ query.Bind(0, true);
+ query.Bind(1, std::string("GUI"));
+ query.Bind(2, device_id);
+ query.Bind(3, *it_consented_groups);
+ // TODO(AOleynik): Get this info from external data
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_,
+ "Failed update of device allowed consented groups.");
+ return false;
+ }
+ }
+
+ StringArray::const_iterator it_disallowed_groups =
+ disallowed_groups.begin();
+ StringArray::const_iterator it_disallowed_groups_end =
+ disallowed_groups.end();
+ for (; it_disallowed_groups != it_disallowed_groups_end;
+ ++it_disallowed_groups) {
+ query.Bind(0, false);
+ query.Bind(1);
+ query.Bind(2, device_id);
+ query.Bind(3, *it_disallowed_groups);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_,
+ "Failed update of device disallowed consented groups.");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // Insert new values
+ if (!query.Prepare(sql_pt_ext::kInsertDeviceConsentedGroup)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect statement of inserting to device consented groups");
+ return false;
+ }
+
+ StringArray::const_iterator it_consented_groups = consented_groups.begin();
+ StringArray::const_iterator it_consented_groups_end = consented_groups.end();
+ for (; it_consented_groups != it_consented_groups_end;
+ ++it_consented_groups) {
+ query.Bind(0, device_id);
+ query.Bind(1, *it_consented_groups);
+ query.Bind(2, true);
+ // TODO(AOleynik): Get this info from external data
+ query.Bind(3, std::string("GUI"));
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_,
+ "Failed insert to device allowed consented groups.");
+ return false;
+ }
+ }
+
+ StringArray::const_iterator it_disallowed_groups = disallowed_groups.begin();
+ StringArray::const_iterator it_disallowed_groups_end =
+ disallowed_groups.end();
+ for (; it_disallowed_groups != it_disallowed_groups_end;
+ ++it_disallowed_groups) {
+ query.Bind(0, device_id);
+ query.Bind(1, *it_disallowed_groups);
+ query.Bind(2, false);
+ query.Bind(3);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_,
+ "Failed insert to device disallowed consented groups.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::ReactOnUserDevConsentForApp(
+ const std::string& app_id, bool is_device_allowed) {
+ bool result = true;
+ if (is_device_allowed) {
+ // If app has pre_DataConsented groups it should be 'promoted' to default
+ // If app has only pre_DataConsented flag it should be only set to false and
+ // all groups get restored automatically
+ if (IsPredataPolicy(app_id)) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kHasAppPreloadedGroups)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect statement for has app preloaded groups");
+ return false;
+ }
+ query.Bind(0, app_id);
+ query.Bind(1, kPreDataConsentId);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect select for app has predataconsted groups");
+ return false;
+ }
+ if (query.GetInteger(0) > 0) {
+ result = result && SetDefaultPolicy(app_id);
+ } else {
+ result = result && SetIsPredata(app_id, false);
+ }
+ }
+ } else {
+ // If app has default groups change them to pre_DataConsented
+ // If app has 'normal' groups leave them as is and set
+ // pre_DataConsented flag to true.
+ if (IsDefaultPolicy(app_id)) {
+ result = result && SetPredataPolicy(app_id);
+ } else {
+ result = result && SetIsPredata(app_id, true);
+ }
+ }
+ return result;
+}
+
+bool SQLPTExtRepresentation::SetUserPermissionsForApp(
+ const PermissionConsent& permissions) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ // TODO(AOleynik): Handle situation, when no application was specified, i.e.
+ // general permissions were set
+ std::vector<FunctionalGroupPermission>::const_iterator it =
+ permissions.group_permissions.begin();
+ std::vector<FunctionalGroupPermission>::const_iterator it_end =
+ permissions.group_permissions.end();
+
+ utils::dbms::SQLQuery query(db());
+ for (; it != it_end; ++it) {
+ utils::dbms::SQLQuery counter(db());
+ if (!counter.Prepare(sql_pt_ext::kCountAppConsents)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for consent group count.");
+ return false;
+ }
+
+ counter.Bind(0, permissions.device_id);
+ counter.Bind(1, permissions.policy_app_id);
+ counter.Bind(2, static_cast<int>((*it).group_id));
+ if (!counter.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrent count on consent groups.");
+ return false;
+ }
+
+ bool update_required = counter.GetInteger(0);
+
+ // Update already present consent record
+ if (update_required) {
+ if (!query.Prepare(sql_pt_ext::kUpdateGroupPermissions)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for update consent groups.");
+ return false;
+ }
+
+ // Skip consent saving, if user didn't choose any state
+ if (policy::kGroupUndefined == (*it).state) {
+ continue;
+ }
+ query.Bind(0, (*it).state == kGroupAllowed ? 1 : 0);
+ query.Bind(1, permissions.consent_source);
+ query.Bind(2, permissions.policy_app_id);
+ query.Bind(3, static_cast<int>((*it).group_id));
+ query.Bind(4, permissions.device_id);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect update on user defined permissions "
+ "for app groups.");
+ return false;
+ }
+ continue;
+ }
+
+ // Insert new consent record
+ if (!query.Prepare(sql_pt_ext::kInsertConsentGroups)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect statement for update app group permissions.");
+ return false;
+ }
+
+ // Skip consent saving, if user didn't choose any state
+ if (policy::kGroupUndefined == (*it).state) {
+ continue;
+ }
+ query.Bind(0, permissions.device_id);
+ query.Bind(1, permissions.policy_app_id);
+ query.Bind(2, static_cast<int>((*it).group_id));
+ query.Bind(3, (*it).state == kGroupAllowed ? 1 : 0);
+ query.Bind(4, permissions.consent_source);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert to user defined permissions "
+ "for app groups.");
+ return false;
+ }
+ continue;
+ }
+ return true;
+}
+
+std::vector<UserFriendlyMessage> SQLPTExtRepresentation::GetUserFriendlyMsg(
+ const std::vector<std::string>& msg_codes, const std::string& language) {
+ utils::dbms::SQLQuery query(db());
+ std::vector<UserFriendlyMessage> result;
+ if (!query.Prepare(sql_pt_ext::kSelectFriendlyMsg)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for select friendly messages.");
+ return result;
+ }
+
+ const std::string fallback_language = "en-us";
+ std::vector<std::string>::const_iterator it = msg_codes.begin();
+ std::vector<std::string>::const_iterator it_end = msg_codes.end();
+ for (; it != it_end; ++it) {
+ std::string msg_language = language;
+ // If message has no records with required language, fallback language
+ // should be used instead.
+ if (!IsMsgLanguagePresent((*it), language)) {
+ msg_language = fallback_language;
+ }
+ query.Bind(0, *it);
+ query.Bind(1, msg_language);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect select from friendly messages.");
+ return result;
+ }
+
+ UserFriendlyMessage msg;
+
+ msg.message_code = *it;
+ msg.tts = query.GetString(0);
+ msg.label = query.GetString(1);
+ msg.line1 = query.GetString(2);
+ msg.line2 = query.GetString(3);
+ msg.text_body = query.GetString(4);
+
+ result.push_back(msg);
+
+ if (!query.Reset()) {
+ LOG4CXX_WARN(logger_,
+ "Failed reset statement for selecting friendly "
+ "messages.");
+ return result;
+ }
+ }
+
+ return result;
+}
+
+bool SQLPTExtRepresentation::GatherConsumerFriendlyMessages(
+ policy_table::ConsumerFriendlyMessages* messages) const {
+ if (NULL == messages) {
+ LOG4CXX_ERROR(logger_, "NULL pointer has been passed to fill");
+ return false;
+ }
+
+ if (!SQLPTRepresentation::GatherConsumerFriendlyMessages(messages)) {
+ return false;
+ }
+
+ utils::dbms::SQLQuery query(db());
+ bool result = query.Prepare(sql_pt_ext::kCollectFriendlyMsg);
+
+ if (result) {
+ while (query.Next()) {
+ UserFriendlyMessage msg;
+
+ msg.tts = query.GetString(1);
+ msg.label = query.GetString(2);
+ msg.line1 = query.GetString(3);
+ msg.line2 = query.GetString(4);
+ msg.text_body = query.GetString(5);
+ msg.message_code = query.GetString(7);
+
+ std::string language = query.GetString(6);
+ if (!msg.tts.empty()) {
+ *(*messages->messages)[msg.message_code].languages[language].tts =
+ msg.tts;
+ }
+ if (!msg.label.empty()) {
+ *(*messages->messages)[msg.message_code].languages[language].label =
+ msg.label;
+ }
+ if (!msg.line1.empty()) {
+ *(*messages->messages)[msg.message_code].languages[language].line1 =
+ msg.line1;
+ }
+ if (!msg.line2.empty()) {
+ *(*messages->messages)[msg.message_code].languages[language].line2 =
+ msg.line2;
+ }
+ if (!msg.text_body.empty()) {
+ *(*messages->messages)[msg.message_code].languages[language].textBody =
+ msg.text_body;
+ }
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "Incorrect statement for select friendly messages.");
+ }
+ return result;
+}
+
+bool SQLPTExtRepresentation::SetMetaInfo(const std::string& ccpu_version,
+ const std::string& wers_country_code,
+ const std::string& language) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kUpdateMetaParams)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for insert to module meta.");
+ return false;
+ }
+
+ query.Bind(0, ccpu_version);
+ query.Bind(1, wers_country_code);
+ query.Bind(2, language);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert to module meta.");
+ return false;
+ }
+ return true;
+}
+
+bool SQLPTExtRepresentation::IsMetaInfoPresent() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectMetaParams)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for selecting meta info.");
+ return false;
+ }
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect select from module meta.");
+ return false;
+ }
+
+ return !query.IsNull(0) && !query.IsNull(1) && !query.IsNull(2);
+}
+
+bool SQLPTExtRepresentation::SetSystemLanguage(const std::string& language) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kUpdateMetaLanguage)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for update meta language.");
+ return false;
+ }
+
+ query.Bind(0, language);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect update for meta language.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SaveApplicationPoliciesSection(
+ const policy_table::ApplicationPoliciesSection& policies) {
+ LOG4CXX_INFO(logger_, "SaveApplicationPolicies ext");
+ utils::dbms::SQLQuery query_delete(db());
+ if (!query_delete.Exec(sql_pt::kDeleteAppGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from app_group.");
+ return false;
+ }
+
+ utils::dbms::SQLQuery query_delete_preconsented(db());
+ if (!query_delete_preconsented.Exec(sql_pt_ext::kDeletePreconsentedGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from preconsented_group.");
+ return false;
+ }
+
+ if (!query_delete.Exec(sql_pt::kDeleteApplication)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from application.");
+ return false;
+ }
+
+ if (!query_delete.Exec(sql_pt::kDeleteRequestType)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from request type.");
+ return false;
+ }
+
+ // First, all predefined apps (e.g. default, pre_DataConsent) should be saved,
+ // otherwise another app with the predefined permissions can get incorrect
+ // permissions
+ policy_table::ApplicationPolicies::const_iterator it_default =
+ policies.apps.find(kDefaultId);
+ if (policies.apps.end() != it_default) {
+ if (!SaveSpecificAppPolicy(*it_default)) {
+ return false;
+ }
+ }
+ policy_table::ApplicationPolicies::const_iterator it_pre_data_consent =
+ policies.apps.find(kPreDataConsentId);
+ if (policies.apps.end() != it_pre_data_consent) {
+ if (!SaveSpecificAppPolicy(*it_pre_data_consent)) {
+ return false;
+ }
+ }
+
+ if (!SaveDevicePolicy(policies.device)) {
+ return false;
+ }
+
+ policy_table::ApplicationPolicies::const_iterator it;
+ for (it = policies.apps.begin(); it != policies.apps.end(); ++it) {
+ // Skip saving of predefined app, since they should be saved before
+ if (IsPredefinedApp(*it)) {
+ continue;
+ }
+ if (!SaveSpecificAppPolicy(*it)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SaveSpecificAppPolicy(
+ const policy_table::ApplicationPolicies::value_type& app) {
+ if (app.second.is_string()) {
+ if (kDefaultId.compare(app.second.get_string()) == 0) {
+ if (!SetDefaultPolicy(app.first)) {
+ return false;
+ }
+ if (!SaveRequestType(app.first, *app.second.RequestType)) {
+ return false;
+ }
+ } else if (kPreDataConsentId.compare(app.second.get_string()) == 0) {
+ if (!SetPredataPolicy(app.first)) {
+ return false;
+ }
+ if (!SaveRequestType(app.first, *app.second.RequestType)) {
+ return false;
+ }
+ }
+
+ // Stop saving other params, since predefined permissions already set
+ return true;
+ }
+
+ SetIsDefault(app.first, false);
+ SetIsPredata(app.first, false);
+
+ utils::dbms::SQLQuery app_query(db());
+ if (!app_query.Prepare(sql_pt_ext::kInsertApplication)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement into application.");
+ return false;
+ }
+
+ app_query.Bind(0, app.first);
+ app_query.Bind(1, app.second.keep_context);
+ app_query.Bind(2, app.second.steal_focus);
+ app_query.Bind(
+ 3, std::string(policy_table::EnumToJsonString(app.second.default_hmi)));
+ app_query.Bind(
+ 4, std::string(policy_table::EnumToJsonString(app.second.priority)));
+ app_query.Bind(5, app.second.is_null());
+ app_query.Bind(6, *app.second.memory_kb);
+ app_query.Bind(7, static_cast<int64_t>(*app.second.heart_beat_timeout_ms));
+
+ if (!app_query.Exec() || !app_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into application.");
+ return false;
+ }
+
+ if (!SaveAppGroup(app.first, app.second.groups)) {
+ return false;
+ }
+ if (!SaveNickname(app.first, *app.second.nicknames)) {
+ return false;
+ }
+ if (!SaveAppType(app.first, *app.second.AppHMIType)) {
+ return false;
+ }
+ if (!SavePreconsentedGroup(app.first, *app.second.preconsented_groups)) {
+ return false;
+ }
+
+ if (!SaveRequestType(app.first, *app.second.RequestType)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool policy::SQLPTExtRepresentation::SaveDevicePolicy(
+ const policy_table::DevicePolicy& device) {
+ utils::dbms::SQLQuery app_query(db());
+ if (!app_query.Prepare(sql_pt_ext::kInsertApplication)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement into application (device).");
+ return false;
+ }
+ app_query.Bind(0, kDeviceId);
+ app_query.Bind(1, device.keep_context);
+ app_query.Bind(2, device.steal_focus);
+ app_query.Bind(
+ 3, std::string(policy_table::EnumToJsonString(device.default_hmi)));
+ app_query.Bind(4,
+ std::string(policy_table::EnumToJsonString(device.priority)));
+ app_query.Bind(5, false);
+ app_query.Bind(6, 0);
+ app_query.Bind(7, 0);
+
+ if (!app_query.Exec() || !app_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into application.");
+ return false;
+ }
+
+ if (!SaveAppGroup(kDeviceId, device.groups)) {
+ return false;
+ }
+ if (!SavePreconsentedGroup(kDeviceId, *device.preconsented_groups)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GatherApplicationPoliciesSection(
+ policy_table::ApplicationPoliciesSection* policies) const {
+ LOG4CXX_INFO(logger_, "Gather applications policies");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectAppPolicies)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app_policies");
+ return false;
+ }
+
+ while (query.Next()) {
+ rpc::Nullable<policy_table::ApplicationParams> params;
+ const std::string& app_id = query.GetString(0);
+ if (IsApplicationRevoked(app_id)) {
+ params.set_to_null();
+ (*policies).apps[app_id] = params;
+ continue;
+ }
+ if (IsDefaultPolicy(app_id)) {
+ (*policies).apps[app_id].set_to_string(kDefaultId);
+ }
+ if (IsPredataPolicy(app_id)) {
+ (*policies).apps[app_id].set_to_string(kPreDataConsentId);
+ }
+ if (kDeviceId == app_id) {
+ policy_table::DevicePolicy device_policy;
+ policy_table::Priority priority;
+ policy_table::EnumFromJsonString(query.GetString(1), &priority);
+ device_policy.priority = priority;
+ policy_table::HmiLevel hmi;
+ policy_table::EnumFromJsonString(query.GetString(2), &hmi);
+ device_policy.default_hmi = hmi;
+ device_policy.keep_context = query.GetBoolean(3);
+ device_policy.steal_focus = query.GetBoolean(4);
+ if (!GatherAppGroup(app_id, &device_policy.groups)) {
+ return false;
+ }
+ GatherPreconsentedGroup(app_id, &*device_policy.preconsented_groups);
+ (*policies).device = device_policy;
+ continue;
+ }
+ policy_table::Priority priority;
+ policy_table::EnumFromJsonString(query.GetString(1), &priority);
+ params.priority = priority;
+ policy_table::HmiLevel hmi;
+ policy_table::EnumFromJsonString(query.GetString(2), &hmi);
+ params.default_hmi = hmi;
+ params.keep_context = query.GetBoolean(3);
+ params.steal_focus = query.GetBoolean(4);
+ *params.memory_kb = query.GetInteger(5);
+ *params.heart_beat_timeout_ms = query.GetUInteger(6);
+
+ if (!GatherAppGroup(app_id, &params.groups)) {
+ return false;
+ }
+ if (!GatherNickName(app_id, &*params.nicknames)) {
+ return false;
+ }
+ if (!GatherAppType(app_id, &*params.AppHMIType)) {
+ return false;
+ }
+ if (!GatherRequestType(app_id, &*params.RequestType)) {
+ return false;
+ }
+ GatherPreconsentedGroup(app_id, &*params.preconsented_groups);
+ (*policies).apps[app_id] = params;
+ }
+ return true;
+}
+
+void SQLPTExtRepresentation::GatherPreconsentedGroup(
+ const std::string& app_id, policy_table::Strings* groups) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectPreconsentedGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from preconsented group");
+ return;
+ }
+
+ query.Bind(0, app_id);
+ while (query.Next()) {
+ groups->push_back(query.GetString(0));
+ }
+}
+
+bool SQLPTExtRepresentation::GatherUsageAndErrorCounts(
+ policy_table::UsageAndErrorCounts* counts) const {
+ LOG4CXX_INFO(logger_, "Gather Usage and Error Counts.");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectUsageAndErrorCount) || !query.Exec()) {
+ LOG4CXX_INFO(logger_, "Failed select from user_and_error_count");
+ return false;
+ }
+
+ *counts->count_of_iap_buffer_full = query.GetInteger(0);
+ *counts->count_sync_out_of_memory = query.GetInteger(1);
+ *counts->count_of_sync_reboots = query.GetInteger(2);
+
+ return GatherAppLevels(&*counts->app_level);
+}
+
+bool SQLPTExtRepresentation::GatherAppLevels(
+ policy_table::AppLevels* apps) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectAppLevels)) {
+ LOG4CXX_INFO(logger_,
+ "Failed select from app_level. SQLError = "
+ << query.LastError().text());
+ return false;
+ }
+ while (query.Next()) {
+ policy_table::AppLevel level;
+ // value of time fields database is seconds
+ level.minutes_in_hmi_full = query.GetInteger(1);
+ level.minutes_in_hmi_limited = query.GetInteger(2);
+ level.minutes_in_hmi_background = query.GetInteger(3);
+ level.minutes_in_hmi_none = query.GetInteger(4);
+ level.count_of_user_selections = query.GetInteger(5);
+ level.count_of_rejections_sync_out_of_memory = query.GetInteger(6);
+ level.count_of_rejections_nickname_mismatch = query.GetInteger(7);
+ level.count_of_rejections_duplicate_name = query.GetInteger(8);
+ level.count_of_rejected_rpc_calls = query.GetInteger(9);
+ level.count_of_rpcs_sent_in_hmi_none = query.GetInteger(10);
+ level.count_of_removals_for_bad_behavior = query.GetInteger(11);
+ level.count_of_run_attempts_while_revoked = query.GetInteger(12);
+ level.app_registration_language_gui = query.GetString(13);
+ level.app_registration_language_vui = query.GetString(14);
+ level.count_of_tls_errors = query.GetInteger(15);
+ (*apps)[query.GetString(0)] = level;
+ }
+
+ return true;
+}
+
+void SQLPTExtRepresentation::GatherDeviceData(
+ policy_table::DeviceData* data) const {
+ LOG4CXX_INFO(logger_, "Gather device data.");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectDeviceData)) {
+ LOG4CXX_WARN(logger_, "Incorrect select statement for device data.");
+ return;
+ }
+ data->mark_initialized();
+ while (query.Next()) {
+ policy_table::DeviceParams* specific_device = &(*data)[query.GetString(0)];
+ *specific_device->hardware = query.GetString(1);
+ *specific_device->firmware_rev = query.GetString(2);
+ *specific_device->os = query.GetString(3);
+ *specific_device->os_version = query.GetString(4);
+ *specific_device->carrier = query.GetString(5);
+ *specific_device->max_number_rfcom_ports = query.GetInteger(6);
+
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ GatherConsentGroup(query.GetString(0),
+ &(*specific_device->user_consent_records));
+ }
+}
+
+void SQLPTExtRepresentation::GatherConsentGroup(
+ const std::string& device_id,
+ policy_table::UserConsentRecords* records) const {
+ LOG4CXX_INFO(logger_, "Gather consent records.");
+ utils::dbms::SQLQuery query(db());
+ // Fill data for device
+ if (!query.Prepare(sql_pt_ext::kSelectDeviceConsentedGroup)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect select statement for device consented groups.");
+ return;
+ }
+
+ query.Bind(0, device_id);
+
+ // Fill device_data -> user_consent_records -> "device"
+ while (query.Next()) {
+ policy_table::ConsentRecords* device_consent_records =
+ &(*records)[kDeviceId];
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ policy_table::ConsentGroups& consent_groups =
+ *device_consent_records->consent_groups;
+ consent_groups[query.GetString(1)] = query.GetBoolean(2);
+ policy_table::Input input;
+ policy_table::EnumFromJsonString(query.GetString(3), &input);
+ *device_consent_records->input = input;
+ *device_consent_records->time_stamp = query.GetString(4);
+ }
+
+ if (!query.Reset()) {
+ return;
+ }
+
+ // Fill data for applications
+ if (!query.Prepare(sql_pt_ext::kSelectConsentGroup)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect select statement for app consented groups.");
+ return;
+ }
+
+ query.Bind(0, device_id);
+
+ // Fill device_data -> user_consent_records -> <app_id>
+ while (query.Next()) {
+ policy_table::ConsentRecords* app_consent_records =
+ &(*records)[query.GetString(1)];
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ policy_table::ConsentGroups& consent_groups =
+ *app_consent_records->consent_groups;
+
+ consent_groups[query.GetString(2)] = query.GetBoolean(3);
+ policy_table::Input input;
+ policy_table::EnumFromJsonString(query.GetString(4), &input);
+ *app_consent_records->input = input;
+ *app_consent_records->time_stamp = query.GetString(5);
+ app_consent_records->consent_last_updated = query.GetInteger(6);
+ }
+ if (!query.Reset()) {
+ return;
+ }
+
+ // Fill data for ExternalConsent consents
+ if (!query.Prepare(sql_pt_ext::kSelectExternalConsentStatusGroup)) {
+ LOG4CXX_WARN(
+ logger_,
+ "Incorrect select statement for ExternalConsent consented groups.");
+ return;
+ }
+
+ query.Bind(0, device_id);
+
+ // Fill device_data -> user_consent_records -> <app_id> ->
+ // external_consent_status_groups
+ while (query.Next()) {
+ policy_table::ConsentRecords* app_consent_records =
+ &(*records)[query.GetString(1)];
+ policy_table::ConsentGroups& external_consent_status_groups =
+ *app_consent_records->external_consent_status_groups;
+ external_consent_status_groups[query.GetString(2)] = query.GetBoolean(3);
+ policy_table::Input input;
+ policy_table::EnumFromJsonString(query.GetString(4), &input);
+ app_consent_records->ext_consent_last_updated = query.GetInteger(6);
+ }
+}
+
+bool SQLPTExtRepresentation::SaveDeviceData(
+ const policy_table::DeviceData& devices) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery drop_device_query(db());
+ const std::string drop_device = "DELETE FROM `device`";
+ if (!drop_device_query.Exec(drop_device)) {
+ LOG4CXX_WARN(logger_, "Could not clear device table.");
+ return false;
+ }
+
+ utils::dbms::SQLQuery drop_device_consents_query(db());
+ const std::string drop_device_consents = "DELETE FROM `device_consent_group`";
+ if (!drop_device_consents_query.Exec(drop_device_consents)) {
+ LOG4CXX_WARN(logger_, "Could not clear device consents.");
+ return false;
+ }
+
+ utils::dbms::SQLQuery drop_user_consents_query(db());
+ const std::string drop_user_consents = "DELETE FROM `consent_group`";
+ if (!drop_user_consents_query.Exec(drop_user_consents)) {
+ LOG4CXX_WARN(logger_, "Could not clear user consents.");
+ return false;
+ }
+
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kInsertDeviceData)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for device data.");
+ return false;
+ }
+
+ policy_table::DeviceData::const_iterator it = devices.begin();
+ policy_table::DeviceData::const_iterator it_end = devices.end();
+ for (; it != it_end; ++it) {
+ query.Bind(0, it->first);
+ query.Bind(1, *(it->second.hardware));
+ query.Bind(2, *(it->second.firmware_rev));
+ query.Bind(3, *(it->second.os));
+ query.Bind(4, *(it->second.os_version));
+ query.Bind(5, *(it->second.carrier));
+ query.Bind(6, *(it->second.max_number_rfcom_ports));
+ query.Bind(7, *(it->second.connection_type));
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into device data.");
+ return false;
+ }
+
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ if (!SaveConsentGroup(it->first, *it->second.user_consent_records)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SaveConsentGroup(
+ const std::string& device_id,
+ const policy_table::UserConsentRecords& records) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+
+ policy_table::UserConsentRecords::const_iterator it = records.begin();
+ policy_table::UserConsentRecords::const_iterator it_end = records.end();
+ for (; it != it_end; ++it) {
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ policy_table::ConsentGroups::const_iterator it_groups =
+ it->second.consent_groups->begin();
+ policy_table::ConsentGroups::const_iterator it_groups_end =
+ it->second.consent_groups->end();
+ for (; it_groups != it_groups_end; ++it_groups) {
+ if (kDeviceId == it->first) {
+ if (!query.Prepare(sql_pt_ext::kInsertDeviceConsentedGroup)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement for device consent group.");
+ return false;
+ }
+ query.Bind(0, device_id);
+ query.Bind(1, it_groups->first);
+ query.Bind(2, it_groups->second);
+ query.Bind(
+ 3,
+ std::string(policy_table::EnumToJsonString(*(it->second.input))));
+ query.Bind(4, std::string(*(it->second.time_stamp)));
+ LOG4CXX_INFO(logger_,
+ "Device:"
+ << "time stamp "
+ << std::string(*(it->second.time_stamp)) << " group "
+ << it_groups->first << " consent "
+ << it_groups->second);
+ } else {
+ if (!query.Prepare(sql_pt_ext::kInsertConsentGroups)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement for consent group.");
+ return false;
+ }
+ query.Bind(0, device_id);
+ query.Bind(1, it->first);
+ query.Bind(2, it_groups->first);
+ query.Bind(3, it_groups->second);
+ query.Bind(
+ 4,
+ std::string(policy_table::EnumToJsonString(*(it->second.input))));
+ query.Bind(5, std::string(*(it->second.time_stamp)));
+ query.Bind(6, (it->second.consent_last_updated));
+ LOG4CXX_INFO(logger_,
+ "Device:"
+ << "time stamp "
+ << std::string(*(it->second.time_stamp)) << " group "
+ << it_groups->first << " consent "
+ << it_groups->second);
+ }
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into consent group.");
+ return false;
+ }
+ }
+
+ policy_table::ConsentGroups::const_iterator it_external_consent_consent =
+ it->second.external_consent_status_groups->begin();
+ policy_table::ConsentGroups::const_iterator end_external_consent_consent =
+ it->second.external_consent_status_groups->end();
+
+ for (; end_external_consent_consent != it_external_consent_consent;
+ ++it_external_consent_consent) {
+ if (!query.Prepare(sql_pt_ext::kInsertExternalConsentStatusGroups)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement for external consent group.");
+ return false;
+ }
+ query.Bind(0, device_id);
+ query.Bind(1, it->first);
+ query.Bind(2, it_external_consent_consent->first);
+ query.Bind(3, it_external_consent_consent->second);
+ query.Bind(
+ 4, std::string(policy_table::EnumToJsonString(*(it->second.input))));
+ query.Bind(5, std::string(*(it->second.time_stamp)));
+ query.Bind(6, (it->second.ext_consent_last_updated));
+ LOG4CXX_INFO(logger_,
+ "Device:"
+ << "time stamp " << std::string(*(it->second.time_stamp))
+ << " group " << it_external_consent_consent->first
+ << " consent " << it_external_consent_consent->second);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into external consent group.");
+ return false;
+ }
+ } // external_consent_consent_group
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SavePreconsentedGroup(
+ const std::string& app_id, const policy_table::Strings& groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kInsertPreconsentedGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for preconsented groups");
+ return false;
+ }
+
+ policy_table::Strings::const_iterator it;
+ for (it = groups.begin(); it != groups.end(); ++it) {
+ query.Bind(0, app_id);
+ query.Bind(1, *it);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into preconsented groups.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void SQLPTExtRepresentation::GatherModuleMeta(
+ policy_table::ModuleMeta* meta) const {
+ LOG4CXX_INFO(logger_, "Gather Module Meta Info");
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt_ext::kSelectModuleMeta) && query.Next()) {
+ *meta->ccpu_version = query.GetString(0);
+ *meta->language = query.GetString(1);
+ *meta->wers_country_code = query.GetString(2);
+ *meta->pt_exchanged_at_odometer_x = query.GetInteger(3);
+ *meta->pt_exchanged_x_days_after_epoch = query.GetInteger(4);
+ *meta->ignition_cycles_since_last_exchange = query.GetInteger(5);
+ *meta->vin = query.GetString(6);
+ }
+}
+
+void SQLPTExtRepresentation::Increment(const std::string& type) const {
+ utils::dbms::SQLQuery query(db());
+ std::string update_counter =
+ "UPDATE `usage_and_error_count` SET `" + type + "` = `" + type + "` + 1";
+ if (!query.Exec(update_counter)) {
+ LOG4CXX_INFO(logger_, "Failed updating global counter");
+ }
+}
+
+bool SQLPTExtRepresentation::IsExistAppLevel(const std::string& app_id) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kCountAppLevel)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement of count app_level");
+ return false;
+ }
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Failed count app_level");
+ return false;
+ }
+ return query.GetInteger(0) > 0;
+}
+
+bool SQLPTExtRepresentation::GetAllAppGroups(const std::string& policy_app_id,
+ FunctionalGroupIDs& all_groups) {
+ LOG4CXX_INFO(logger_, "GetAllAppGroups for '" << policy_app_id << "'");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectAppGroupsId)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for select app groups id.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+
+ while (query.Next()) {
+ all_groups.push_back(query.GetInteger(0));
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetConsentedGroups(
+ const std::string& policy_app_id,
+ const std::string& device_id,
+ FunctionalGroupIDs& allowed_groups,
+ FunctionalGroupIDs& disallowed_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectConsentedGroupsId)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for select consent groups id.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+ query.Bind(1, device_id);
+
+ while (query.Next()) {
+ if (query.GetBoolean(1)) {
+ allowed_groups.push_back(query.GetInteger(0));
+ } else {
+ disallowed_groups.push_back(query.GetInteger(0));
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetPreconsentedGroups(
+ const std::string& policy_app_id, FunctionalGroupIDs& preconsented_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectPreconsentedGroupsId)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect statement for select preconsented groups id.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+
+ while (query.Next()) {
+ preconsented_groups.push_back(query.GetInteger(0));
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetFunctionalGroupNames(
+ FunctionalGroupNames& names) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectFunctionalGroupNames)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect statement for select functional groups names.");
+ return false;
+ }
+
+ while (query.Next()) {
+ // Some of functional grous doesn't have filled user_consent_prompt
+ if (query.IsNull(1)) {
+ names[query.GetInteger(0)] =
+ std::make_pair<std::string, std::string>("", query.GetString(2));
+ } else {
+ names[query.GetInteger(0)] = std::make_pair<std::string, std::string>(
+ query.GetString(1), query.GetString(2));
+ }
+ }
+
+ return true;
+}
+
+void SQLPTExtRepresentation::FillFunctionalGroupPermissions(
+ FunctionalGroupIDs& ids,
+ FunctionalGroupNames& names,
+ GroupConsent state,
+ std::vector<FunctionalGroupPermission>& permissions) {
+ FunctionalGroupIDs::const_iterator it = ids.begin();
+ FunctionalGroupIDs::const_iterator it_end = ids.end();
+ for (; it != it_end; ++it) {
+ FunctionalGroupPermission current_group;
+ current_group.group_id = *it;
+ current_group.group_alias = names[*it].first;
+ current_group.group_name = names[*it].second;
+ current_group.state = state;
+ permissions.push_back(current_group);
+ }
+}
+
+void SQLPTExtRepresentation::Increment(const std::string& app_id,
+ const std::string& type) const {
+ utils::dbms::SQLQuery query(db());
+ std::string sql_counter;
+ if (IsExistAppLevel(app_id)) {
+ // update
+ sql_counter = "UPDATE `app_level` SET `" + type + "` = `" + type +
+ "` + 1 WHERE `application_id` = ?";
+ } else {
+ // insert
+ sql_counter = "INSERT INTO `app_level` (`application_id`, `" + type +
+ "`) "
+ "VALUES (?, 1)";
+ }
+ if (!query.Prepare(sql_counter)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement of update app counter");
+ return;
+ }
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Failed updating app counter");
+ }
+}
+
+void SQLPTExtRepresentation::Set(const std::string& app_id,
+ const std::string& type,
+ const std::string& value) const {
+ utils::dbms::SQLQuery query(db());
+ std::string sql_info;
+ if (IsExistAppLevel(app_id)) {
+ // update
+ sql_info = "UPDATE `app_level` SET `" + type +
+ "` = ? "
+ "WHERE `application_id` = ?";
+ } else {
+ // insert
+ sql_info = "INSERT INTO `app_level` (`" + type +
+ "`, `application_id`) "
+ "VALUES (?, ?)";
+ }
+ if (!query.Prepare(sql_info)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement of update app info");
+ return;
+ }
+ query.Bind(0, value);
+ query.Bind(1, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Failed updating app info");
+ }
+}
+
+void SQLPTExtRepresentation::Add(const std::string& app_id,
+ const std::string& type,
+ int seconds) const {
+ utils::dbms::SQLQuery query(db());
+ std::string sql_stopwatch;
+ if (IsExistAppLevel(app_id)) {
+ // update
+ sql_stopwatch = "UPDATE `app_level` SET `" + type + "` = `" + type +
+ "` + ? WHERE `application_id` = ?";
+ } else {
+ // insert
+ sql_stopwatch = "INSERT INTO `app_level` (`" + type +
+ "`, `application_id`) "
+ "VALUES (?, ?)";
+ }
+ if (!query.Prepare(sql_stopwatch)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement of update app stopwatch");
+ return;
+ }
+ query.Bind(0, seconds);
+ query.Bind(1, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Failed updating app stopwatch");
+ }
+}
+
+bool SQLPTExtRepresentation::GetDefaultHMI(const std::string& policy_app_id,
+ std::string* default_hmi) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectDefaultHmi)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement for default hmi.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Error during default hmi getting.");
+ return false;
+ }
+
+ if (query.IsNull(0)) {
+ default_hmi->clear();
+ return true;
+ }
+
+ default_hmi->assign(query.GetString(0));
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::CountUnconsentedGroups(
+ const std::string& policy_app_id,
+ const std::string& device_id,
+ int* result) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kCountUnconsentedGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect select for unconsented groups.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+ query.Bind(1, device_id);
+ query.Bind(2, kDefaultId);
+ query.Bind(3, kPreDataConsentId);
+
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Error during executing unconsented groups.");
+ return false;
+ }
+ *result = query.GetInteger(0);
+ return true;
+}
+
+bool SQLPTExtRepresentation::IsMsgLanguagePresent(const std::string& message,
+ const std::string& language) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kHasMsgLanguageCode)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for message language check.");
+ return false;
+ }
+
+ query.Bind(0, message);
+ query.Bind(1, language);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed to check message language code.");
+ return false;
+ }
+
+ return query.GetInteger(0) != 0;
+}
+
+bool SQLPTExtRepresentation::SaveMessageString(
+ const std::string& type,
+ const std::string& lang,
+ const policy_table::MessageString& strings) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertMessageString)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for message.");
+ return false;
+ }
+
+ if (strings.tts.is_initialized()) {
+ query.Bind(0, *strings.tts);
+ }
+ if (strings.label.is_initialized()) {
+ query.Bind(1, *strings.label);
+ }
+ if (strings.line1.is_initialized()) {
+ query.Bind(2, *strings.line1);
+ }
+ if (strings.line2.is_initialized()) {
+ query.Bind(3, *strings.line2);
+ }
+ query.Bind(4, lang);
+ query.Bind(5, type);
+ if (strings.textBody.is_initialized()) {
+ query.Bind(6, *strings.textBody);
+ }
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into message.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SaveUsageAndErrorCounts(
+ const policy_table::UsageAndErrorCounts& counts) {
+ return SaveAppCounters(*counts.app_level) && SaveGlobalCounters(counts);
+}
+
+bool SQLPTExtRepresentation::SaveModuleMeta(
+ const policy_table::ModuleMeta& meta) {
+ utils::dbms::SQLQuery query(db());
+
+ if (!query.Prepare(sql_pt_ext::kSaveModuleMeta)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for module_meta.");
+ return false;
+ }
+ const int64_t odometer = *(meta.pt_exchanged_at_odometer_x);
+
+ query.Bind(0, *(meta.ccpu_version));
+ query.Bind(1, *(meta.language));
+ query.Bind(2, *(meta.wers_country_code));
+ query.Bind(3, odometer);
+ query.Bind(4, *(meta.pt_exchanged_x_days_after_epoch));
+ query.Bind(5, *(meta.ignition_cycles_since_last_exchange));
+ query.Bind(6, *(meta.vin));
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect update for module_meta.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SaveAppCounters(
+ const rpc::policy_table_interface_base::AppLevels& app_levels) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteAppLevel)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from app level.");
+ return false;
+ }
+ if (!query.Prepare(sql_pt::kInsertAppLevel)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for app level.");
+ return false;
+ }
+
+ policy_table::AppLevels::const_iterator it;
+ for (it = app_levels.begin(); it != app_levels.end(); ++it) {
+ query.Bind(0, it->first);
+ query.Bind(1, it->second.minutes_in_hmi_full);
+ query.Bind(2, it->second.minutes_in_hmi_limited);
+ query.Bind(3, it->second.minutes_in_hmi_background);
+ query.Bind(4, it->second.minutes_in_hmi_none);
+ query.Bind(5, it->second.count_of_user_selections);
+ query.Bind(6, it->second.count_of_rejections_sync_out_of_memory);
+ query.Bind(7, it->second.count_of_rejections_nickname_mismatch);
+ query.Bind(8, it->second.count_of_rejections_duplicate_name);
+ query.Bind(9, it->second.count_of_rejected_rpc_calls);
+ query.Bind(10, it->second.count_of_rpcs_sent_in_hmi_none);
+ query.Bind(11, it->second.count_of_removals_for_bad_behavior);
+ query.Bind(12, it->second.count_of_run_attempts_while_revoked);
+ query.Bind(13, it->second.app_registration_language_gui);
+ query.Bind(14, it->second.app_registration_language_vui);
+ query.Bind(15, it->second.count_of_tls_errors);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into app level.");
+ return false;
+ }
+ }
+ return true;
+}
+
+bool SQLPTExtRepresentation::SaveGlobalCounters(
+ const rpc::policy_table_interface_base::UsageAndErrorCounts& counts) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kUpdateGlobalCounters)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for global counters.");
+ return false;
+ }
+
+ query.Bind(0, *counts.count_of_iap_buffer_full);
+ query.Bind(1, *counts.count_sync_out_of_memory);
+ query.Bind(2, *counts.count_of_sync_reboots);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into global counters.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::CleanupUnpairedDevices(
+ const DeviceIds& device_ids) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery delete_device_query(db());
+ if (!delete_device_query.Prepare(sql_pt::kDeleteDevice)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for device delete.");
+ return true;
+ }
+
+ utils::dbms::SQLQuery delete_device_consent_query(db());
+ if (!delete_device_consent_query.Prepare(sql_pt_ext::kDeleteDeviceConsent)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for delete device consent.");
+ return false;
+ }
+
+ utils::dbms::SQLQuery delete_app_consent_query(db());
+ if (!delete_app_consent_query.Prepare(sql_pt_ext::kDeleteAppConsent)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for delete app consent.");
+ return false;
+ }
+
+ DeviceIds::const_iterator it = device_ids.begin();
+ DeviceIds::const_iterator it_end = device_ids.end();
+ for (; it != it_end; ++it) {
+ delete_device_query.Bind(0, (*it));
+ if (!delete_device_query.Exec() || !delete_device_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Failed to delete from device");
+ return false;
+ }
+
+ delete_device_consent_query.Bind(0, (*it));
+ if (!delete_device_consent_query.Exec() ||
+ !delete_device_consent_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Failed to delete from device consent.");
+ return false;
+ }
+
+ delete_app_consent_query.Bind(0, (*it));
+ if (!delete_app_consent_query.Exec() || !delete_app_consent_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Failed to delete from app consent.");
+ return false;
+ }
+ }
+ return true;
+}
+
+bool SQLPTExtRepresentation::SetDefaultPolicy(const std::string& app_id) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kDeleteAppGroupByApplicationId)) {
+ LOG4CXX_ERROR(logger_, "Incorrect statement to delete from app_group.");
+ return false;
+ }
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_ERROR(logger_, "Failed deleting from app_group.");
+ return false;
+ }
+
+ if (!query.Prepare(sql_pt_ext::kDeletePreconsentedGroupsByApplicationId)) {
+ LOG4CXX_ERROR(logger_, "Incorrect statement to delete from app_group.");
+ return false;
+ }
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_ERROR(logger_, "Failed deleting from app_group.");
+ return false;
+ }
+
+ if (!CopyApplication(kDefaultId, app_id)) {
+ return false;
+ }
+
+ SetPreloaded(false);
+
+ policy_table::Strings default_groups;
+ policy_table::Strings default_preconsented_groups;
+ GatherAppGroup(kDefaultId, &default_groups);
+ GatherPreconsentedGroup(kDefaultId, &default_preconsented_groups);
+ if (SaveAppGroup(app_id, default_groups) &&
+ SavePreconsentedGroup(app_id, default_preconsented_groups)) {
+ return SetIsDefault(app_id, true) && SetIsPredata(app_id, false);
+ }
+
+ return false;
+}
+
+bool SQLPTExtRepresentation::SetPredataPolicy(const std::string& app_id) {
+ LOG4CXX_INFO(logger_,
+ "SQLPTExtRepresentation::SetPredataPolicy for " << app_id);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kDeleteAppGroupByApplicationId)) {
+ LOG4CXX_ERROR(logger_, "Incorrect statement to delete from app_group.");
+ return false;
+ }
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_ERROR(logger_, "Failed deleting from app_group.");
+ return false;
+ }
+
+ if (!query.Prepare(sql_pt_ext::kDeletePreconsentedGroupsByApplicationId)) {
+ LOG4CXX_ERROR(logger_, "Incorrect statement to delete from app_group.");
+ return false;
+ }
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_ERROR(logger_, "Failed deleting from app_group.");
+ return false;
+ }
+
+ if (!CopyApplication(kPreDataConsentId, app_id)) {
+ return false;
+ }
+
+ SetPreloaded(false);
+
+ policy_table::Strings predataconsent_groups;
+ policy_table::Strings predataconsent_preconsented_groups;
+ GatherAppGroup(kPreDataConsentId, &predataconsent_groups);
+ GatherPreconsentedGroup(kPreDataConsentId, &predataconsent_groups);
+ if (SaveAppGroup(app_id, predataconsent_groups) &&
+ SavePreconsentedGroup(app_id, predataconsent_groups)) {
+ return SetIsDefault(app_id, false) && SetIsPredata(app_id, true);
+ }
+ return false;
+}
+
+bool SQLPTExtRepresentation::IsPredataPolicy(const std::string& app_id) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectApplicationIsPreData)) {
+ LOG4CXX_WARN(logger_, "Incorrect select application is pre_dataConsented");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed select application is pre_dataConsented");
+ return false;
+ }
+ return query.IsNull(0) ? false : query.GetBoolean(0);
+}
+
+bool SQLPTExtRepresentation::SetIsPredata(const std::string& app_id,
+ bool is_pre_data) {
+ LOG4CXX_TRACE(logger_, "Set flag is_predata of application");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kUpdateIsPredata)) {
+ LOG4CXX_WARN(logger_, "Incorect statement for updating is_predata");
+ return false;
+ }
+
+ query.Bind(0, is_pre_data);
+ query.Bind(1, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed update is_predata");
+ return false;
+ }
+ return true;
+}
+
+bool SQLPTExtRepresentation::SetUnpairedDevice(const std::string& device_id,
+ bool unpaired) const {
+ LOG4CXX_TRACE(logger_, "Set unpaired device: " << device_id);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kUpdateUnpairedDevice)) {
+ LOG4CXX_WARN(logger_, "Incorect statement for updating unpaired device");
+ return false;
+ }
+
+ query.Bind(0, unpaired);
+ query.Bind(1, device_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed update unpaired device");
+ return false;
+ }
+ return true;
+}
+
+bool SQLPTExtRepresentation::UnpairedDevicesList(DeviceIds* device_ids) const {
+ LOG4CXX_TRACE(logger_, "Get list of unpaired devices");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectUnpairedDevices)) {
+ LOG4CXX_WARN(logger_, "Incorect statement for selecting unpaired devices");
+ return false;
+ }
+
+ while (query.Next()) {
+ device_ids->push_back(query.GetString(0));
+ }
+ return true;
+}
+
+bool SQLPTExtRepresentation::SetVINValue(const std::string& value) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kUpdateModuleMetaVinParam)) {
+ LOG4CXX_WARN(logger_, "Incorect statement for updating module_meta params");
+ return false;
+ }
+
+ query.Bind(0, value);
+ const bool result = query.Exec();
+
+ if (!result) {
+ LOG4CXX_WARN(logger_, "Failed update module_meta");
+ }
+ return result;
+}
+
+bool SQLPTExtRepresentation::SaveExternalConsentStatus(
+ const ExternalConsentStatus& status) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kInsertExternalConsentStatus)) {
+ LOG4CXX_ERROR(logger_,
+ "Incorrect statement for saving external consent status.");
+ return false;
+ }
+
+ ExternalConsentStatus::const_iterator it = status.begin();
+ ExternalConsentStatus::const_iterator end = status.end();
+ for (; end != it; ++it) {
+ query.Bind(0, static_cast<int>(it->entity_type_));
+ query.Bind(1, static_cast<int>(it->entity_id_));
+ // Due to query structure need to provide that twice
+ query.Bind(2, static_cast<int>(it->entity_type_));
+ query.Bind(3, static_cast<int>(it->entity_id_));
+ query.Bind(4,
+ policy::kStatusOn == it->status_ ? std::string("ON")
+ : std::string("OFF"));
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_ERROR(logger_, "Error during ExternalConsent status saving.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+ExternalConsentStatus SQLPTExtRepresentation::GetExternalConsentStatus() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectExternalConsentStatus)) {
+ LOG4CXX_ERROR(logger_,
+ "Incorrect statement for selecting external consent status.");
+ return ExternalConsentStatus();
+ }
+
+ ExternalConsentStatus status;
+ while (query.Next()) {
+ const policy::EntityStatus on_off =
+ query.GetString(2) == "ON" ? policy::kStatusOn : policy::kStatusOff;
+ ExternalConsentStatusItem item(static_cast<uint32_t>(query.GetInteger(0)),
+ static_cast<uint32_t>(query.GetInteger(1)),
+ on_off);
+ status.insert(item);
+ }
+
+ return status;
+}
+
+bool SQLPTExtRepresentation::RemoveAppConsentForGroup(
+ const std::string& policy_app_id,
+ const std::string& functional_group_name) const {
+ utils::dbms::SQLQuery query_group_id(db());
+ if (!query_group_id.Prepare(sql_pt_ext::kSelectGroupId)) {
+ LOG4CXX_WARN(logger_, "Incorect statement for select group name.");
+ return false;
+ }
+
+ query_group_id.Bind(0, functional_group_name);
+
+ if (!query_group_id.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed to select group id.");
+ return false;
+ }
+
+ const int id = query_group_id.GetInteger(0);
+
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kDeleteAppGroupConsent)) {
+ LOG4CXX_WARN(logger_, "Incorect statement for remove app consent.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+ query.Bind(1, id);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed to remove app consent.");
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace policy
diff --git a/src/components/policy/policy_external/src/sql_pt_queries.cc b/src/components/policy/policy_external/src/sql_pt_queries.cc
new file mode 100644
index 0000000000..1cd789f00d
--- /dev/null
+++ b/src/components/policy/policy_external/src/sql_pt_queries.cc
@@ -0,0 +1,972 @@
+/*
+ Copyright (c) 2015, " Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, " with or without
+ modification, " are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, " this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, "
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, " INCLUDING, " BUT NOT LIMITED TO, " THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, " INDIRECT, " INCIDENTAL, " SPECIAL, " EXEMPLARY, " OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, " BUT NOT LIMITED TO, " PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, " DATA, " OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, " WHETHER IN
+ CONTRACT, " STRICT LIABILITY, " OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, " EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "policy/sql_pt_queries.h"
+
+namespace policy {
+namespace sql_pt {
+
+const std::string kSelectPriority =
+ "SELECT `priority_value` FROM `application` WHERE `id` = ? LIMIT 1";
+const std::string kCreateSchema =
+ "BEGIN; "
+ "CREATE TABLE IF NOT EXISTS `device`( "
+ " `id` VARCHAR(100) PRIMARY KEY NOT NULL, "
+ " `hardware` VARCHAR(45), "
+ " `firmware_rev` VARCHAR(45), "
+ " `os` VARCHAR(45), "
+ " `os_version` VARCHAR(45), "
+ " `carrier` VARCHAR(45), "
+ " `max_number_rfcom_ports` INTEGER,"
+ " `connection_type` VARCHAR(45), "
+ " `unpaired` BOOL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `usage_and_error_count`( "
+ " `count_of_iap_buffer_full` INTEGER, "
+ " `count_sync_out_of_memory` INTEGER, "
+ " `count_of_sync_reboots` INTEGER "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `module_meta`( "
+ " `ccpu_version` VARCHAR(45), "
+ " `language` VARCHAR(45), "
+ " `wers_country_code` VARCHAR(45), "
+ " `pt_exchanged_at_odometer_x` INTEGER NOT NULL DEFAULT 0, "
+ " `pt_exchanged_x_days_after_epoch` INTEGER NOT NULL DEFAULT 0, "
+ " `ignition_cycles_since_last_exchange` INTEGER NOT NULL DEFAULT 0, "
+ " `vin` VARCHAR(45),"
+ " `flag_update_required` BOOL NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `module_config`( "
+ " `preloaded_pt` BOOL NOT NULL, "
+ " `is_first_run` BOOL NOT NULL, "
+ " `exchange_after_x_ignition_cycles` INTEGER NOT NULL, "
+ " `exchange_after_x_kilometers` INTEGER NOT NULL, "
+ " `exchange_after_x_days` INTEGER NOT NULL, "
+ " `timeout_after_x_seconds` INTEGER NOT NULL, "
+ " `vehicle_make` VARCHAR(45), "
+ " `vehicle_model` VARCHAR(45), "
+ " `vehicle_year` VARCHAR(4), "
+ " `preloaded_date` VARCHAR (10), "
+ " `certificate` VARCHAR (45), "
+ " `user_consent_passengersRC` BOOL,"
+ " `country_consent_passengersRC` BOOL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `functional_group`( "
+ " `id` INTEGER PRIMARY KEY NOT NULL, "
+ " `user_consent_prompt` TEXT, "
+ " `name` VARCHAR(100) NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `external_consent_entities`( "
+ " `group_id` INTEGER NOT NULL, "
+ " `entity_type` INTEGER NOT NULL, "
+ " `entity_id` INTEGER NOT NULL, "
+ " `on_off` TEXT NOT NULL, "
+ " CONSTRAINT `fk_external_consent_entities_group_id` "
+ " FOREIGN KEY(`group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `priority`( "
+ " `value` VARCHAR(45) PRIMARY KEY NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `hmi_level`( "
+ " `value` VARCHAR(45) PRIMARY KEY NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `notifications_by_priority`( "
+ " `priority_value` VARCHAR(45) PRIMARY KEY NOT NULL, "
+ " `value` INTEGER NOT NULL, "
+ " CONSTRAINT `fk_notifications_by_priority_priority1` "
+ " FOREIGN KEY(`priority_value`) "
+ " REFERENCES `priority`(`value`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`notifications_by_priority.fk_notifications_by_priority_priority1_idx` "
+ " ON `notifications_by_priority`(`priority_value`); "
+ "CREATE TABLE IF NOT EXISTS `language`( "
+ " `code` VARCHAR(25) PRIMARY KEY NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `message_type`( "
+ " `name` VARCHAR(45) PRIMARY KEY NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `version`( "
+ " `number` VARCHAR(45) NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `rpc`( "
+ " `id` INTEGER PRIMARY KEY NOT NULL, "
+ " `name` VARCHAR(45) NOT NULL, "
+ " `parameter` VARCHAR(45), "
+ " `hmi_level_value` VARCHAR(45) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " CONSTRAINT `fk_rpc_hmi_level1` "
+ " FOREIGN KEY(`hmi_level_value`) "
+ " REFERENCES `hmi_level`(`value`), "
+ " CONSTRAINT `fk_rpc_functional_group1` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `rpc.fk_rpc_hmi_level1_idx` "
+ " ON `rpc`(`hmi_level_value`); "
+ "CREATE INDEX IF NOT EXISTS `rpc.fk_rpc_functional_group1_idx` "
+ " ON `rpc`(`functional_group_id`); "
+ "CREATE INDEX `rpc.select_rpc_name_hmi_level` "
+ " ON `rpc`(`name`,`hmi_level_value`);"
+ "CREATE TABLE IF NOT EXISTS `application`( "
+ " `id` VARCHAR(45) PRIMARY KEY NOT NULL, "
+ " `keep_context` BOOLEAN, "
+ " `steal_focus` BOOLEAN, "
+ " `default_hmi` VARCHAR(45), "
+ " `priority_value` VARCHAR(45), "
+ " `is_revoked` BOOLEAN, "
+ " `is_default` BOOLEAN, "
+ " `is_predata` BOOLEAN, "
+ " `memory_kb` INTEGER NOT NULL, "
+ " `heart_beat_timeout_ms` INTEGER NOT NULL, "
+ " `remote_control_denied` BOOLEAN NOT NULL DEFAULT 0, "
+ " CONSTRAINT `fk_application_hmi_level1` "
+ " FOREIGN KEY(`default_hmi`) "
+ " REFERENCES `hmi_level`(`value`), "
+ " CONSTRAINT `fk_application_priorities1` "
+ " FOREIGN KEY(`priority_value`) "
+ " REFERENCES `priority`(`value`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `application.fk_application_hmi_level1_idx` "
+ " ON `application`(`default_hmi`); "
+ "CREATE INDEX IF NOT EXISTS `application.fk_application_priorities1_idx` "
+ " ON `application`(`priority_value`); "
+ "CREATE TABLE IF NOT EXISTS `app_group`( "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " PRIMARY KEY(`application_id`,`functional_group_id`), "
+ " CONSTRAINT `fk_application_has_functional_group_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`), "
+ " CONSTRAINT `fk_application_has_functional_group_functional_group1` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`app_group.fk_application_has_functional_group_functional_group1_idx` "
+ " ON `app_group`(`functional_group_id`); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`app_group.fk_application_has_functional_group_application1_idx` "
+ " ON `app_group`(`application_id`); "
+ "CREATE TABLE IF NOT EXISTS `preconsented_group`( "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " PRIMARY KEY(`application_id`,`functional_group_id`), "
+ " CONSTRAINT `fk_application_has_functional_group_application2` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`), "
+ " CONSTRAINT `fk_application_has_functional_group_functional_group2` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`preconsented_group.fk_application_has_functional_group_functional_group2_"
+ "idx` "
+ " ON `preconsented_group`(`functional_group_id`); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`preconsented_group.fk_application_has_functional_group_application2_idx` "
+ " ON `preconsented_group`(`application_id`); "
+ "CREATE TABLE IF NOT EXISTS `seconds_between_retry`( "
+ " `index` INTEGER PRIMARY KEY NOT NULL, "
+ " `value` INTEGER NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `device_consent_group`( "
+ " `device_id` VARCHAR(100) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " `is_consented` BOOL NOT NULL, "
+ " `input` VARCHAR(45), "
+ " `time_stamp` VARCHAR(45), "
+ " PRIMARY KEY(`device_id`,`functional_group_id`), "
+ " CONSTRAINT `fk_device_has_functional_group_device1` "
+ " FOREIGN KEY(`device_id`) "
+ " REFERENCES `device`(`id`), "
+ " CONSTRAINT `fk_device_has_functional_group_functional_group1` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`device_consent_group.fk_device_has_functional_group_functional_group1_"
+ "idx` "
+ " ON `device_consent_group`(`functional_group_id`); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`device_consent_group.fk_device_has_functional_group_device1_idx` "
+ " ON `device_consent_group`(`device_id`); "
+ "CREATE TABLE IF NOT EXISTS `app_level`( "
+ " `application_id` VARCHAR(45) PRIMARY KEY NOT NULL, "
+ " `minutes_in_hmi_full` INTEGER DEFAULT 0, "
+ " `minutes_in_hmi_limited` INTEGER DEFAULT 0, "
+ " `minutes_in_hmi_background` INTEGER DEFAULT 0, "
+ " `minutes_in_hmi_none` INTEGER DEFAULT 0, "
+ " `count_of_user_selections` INTEGER DEFAULT 0, "
+ " `count_of_rejections_sync_out_of_memory` INTEGER DEFAULT 0, "
+ " `count_of_rejections_nickname_mismatch` INTEGER DEFAULT 0, "
+ " `count_of_rejections_duplicate_name` INTEGER DEFAULT 0, "
+ " `count_of_rejected_rpcs_calls` INTEGER DEFAULT 0, "
+ " `count_of_rpcs_sent_in_hmi_none` INTEGER DEFAULT 0, "
+ " `count_of_removals_for_bad_behavior` INTEGER DEFAULT 0, "
+ " `count_of_run_attempts_while_revoked` INTEGER DEFAULT 0, "
+ " `count_of_tls_errors` INTEGER DEFAULT 0, "
+ " `app_registration_language_gui` VARCHAR(25), "
+ " `app_registration_language_vui` VARCHAR(25), "
+ " CONSTRAINT `fk_app_levels_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`), "
+ " CONSTRAINT `fk_app_level_language1` "
+ " FOREIGN KEY(`app_registration_language_gui`) "
+ " REFERENCES `language`(`code`), "
+ " CONSTRAINT `fk_app_level_language2` "
+ " FOREIGN KEY(`app_registration_language_vui`) "
+ " REFERENCES `language`(`code`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `app_level.fk_app_levels_application1_idx` "
+ " ON `app_level`(`application_id`); "
+ "CREATE INDEX IF NOT EXISTS `app_level.fk_app_level_language1_idx` "
+ " ON `app_level`(`app_registration_language_gui`); "
+ "CREATE INDEX IF NOT EXISTS `app_level.fk_app_level_language2_idx` "
+ " ON `app_level`(`app_registration_language_vui`); "
+ "CREATE TABLE IF NOT EXISTS `nickname`( "
+ " `name` VARCHAR(100) NOT NULL, "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " PRIMARY KEY(`name`,`application_id`), "
+ " CONSTRAINT `fk_nickname_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `nickname.fk_nickname_application1_idx` "
+ " ON `nickname`(`application_id`); "
+ "CREATE TABLE IF NOT EXISTS `app_type`( "
+ " `name` VARCHAR(50) NOT NULL, "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " PRIMARY KEY(`name`,`application_id`), "
+ " CONSTRAINT `fk_app_type_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`) "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `request_type`( "
+ " `request_type` VARCHAR(50) NOT NULL, "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " PRIMARY KEY(`request_type`,`application_id`), "
+ " CONSTRAINT `fk_app_type_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `app_type.fk_app_type_application1_idx` "
+ " ON `app_type`(`application_id`); "
+ "CREATE TABLE IF NOT EXISTS `consent_group`( "
+ " `device_id` VARCHAR(100) NOT NULL, "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " `is_consented` BOOL NOT NULL, "
+ " `input` VARCHAR(45), "
+ " `time_stamp` VARCHAR(45), "
+ " `last_updated` INTEGER, "
+ " PRIMARY KEY(`application_id`,`functional_group_id`,`device_id`), "
+ " CONSTRAINT `fk_consent_group_device1` "
+ " FOREIGN KEY(`device_id`) "
+ " REFERENCES `device`(`id`), "
+ " CONSTRAINT `fk_consent_group_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`), "
+ " CONSTRAINT `fk_consent_group_functional_group1` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `external_consent_status_group`( "
+ " `device_id` VARCHAR(100) NOT NULL, "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " `is_consented` BOOL NOT NULL, "
+ " `input` VARCHAR(45), "
+ " `time_stamp` VARCHAR(45), "
+ " `last_updated` INTEGER, "
+ " PRIMARY KEY(`application_id`,`functional_group_id`,`device_id`), "
+ " CONSTRAINT `fk_external_consent_status_group_device1` "
+ " FOREIGN KEY(`device_id`) "
+ " REFERENCES `device`(`id`), "
+ " CONSTRAINT `fk_external_consent_status_group_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`), "
+ " CONSTRAINT `fk_external_consent_status_group_functional_group1` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`consent_group.fk_consent_group_device1_idx` "
+ " ON `device_consent_group`(`device_id`); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`consent_group.fk_consent_group_functional_group1_idx` "
+ " ON `consent_group`(`functional_group_id`); "
+ "CREATE TABLE IF NOT EXISTS `endpoint`( "
+ " `service` INTEGER NOT NULL, "
+ " `url` VARCHAR(100) NOT NULL, "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " CONSTRAINT `fk_endpoint_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `endpoint.fk_endpoint_application1_idx` "
+ " ON `endpoint`(`application_id`); "
+ "CREATE TABLE IF NOT EXISTS `message`( "
+ " `id` INTEGER PRIMARY KEY NOT NULL, "
+ " `tts` TEXT, "
+ " `label` TEXT, "
+ " `line1` TEXT, "
+ " `line2` TEXT, "
+ " `textBody` TEXT, "
+ " `language_code` VARCHAR(25) NOT NULL, "
+ " `message_type_name` VARCHAR(45) NOT NULL, "
+ " CONSTRAINT `fk_messages_languages1` "
+ " FOREIGN KEY(`language_code`) "
+ " REFERENCES `language`(`code`), "
+ " CONSTRAINT `fk_message_consumer_friendly_messages1` "
+ " FOREIGN KEY(`message_type_name`) "
+ " REFERENCES `message_type`(`name`) "
+ "); "
+
+ "CREATE TABLE IF NOT EXISTS `app_group_primary`( "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " PRIMARY KEY(`application_id`,`functional_group_id`), "
+ " CONSTRAINT `fk_application_has_functional_group_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`), "
+ " CONSTRAINT `fk_application_has_functional_group_functional_group1` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`app_group_primary.fk_application_has_functional_group_functional_group1_"
+ "idx` "
+ " ON `app_group_primary`(`functional_group_id`); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`app_group_primary.fk_application_has_functional_group_application1_idx` "
+ " ON `app_group_primary`(`application_id`); "
+
+ "CREATE TABLE IF NOT EXISTS `app_group_non_primary`( "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " PRIMARY KEY(`application_id`,`functional_group_id`), "
+ " CONSTRAINT `fk_application_has_functional_group_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`), "
+ " CONSTRAINT `fk_application_has_functional_group_functional_group1` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`app_group_non_primary.fk_application_has_functional_group_functional_"
+ "group1_idx` "
+ " ON `app_group_non_primary`(`functional_group_id`); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`app_group_non_primary.fk_application_has_functional_group_application1_"
+ "idx` "
+ " ON `app_group_non_primary`(`application_id`); "
+
+ /* interior_zone */
+ "CREATE TABLE `interior_zone`( "
+ " `id` INTEGER PRIMARY KEY NOT NULL, "
+ " `name` VARCHAR(100) NOT NULL, "
+ " `col` INTEGER NOT NULL, "
+ " `row` INTEGER NOT NULL, "
+ " `level` INTEGER NOT NULL "
+ "); "
+ "CREATE UNIQUE INDEX `interior_zone.room` ON "
+ "`interior_zone`(`col`,`row`,`level`); "
+
+ /* access_module */
+ "CREATE TABLE `access_module`( "
+ " `id` INTEGER PRIMARY KEY NOT NULL, "
+ " `name` VARCHAR(45) NOT NULL, "
+ " `zone_id` INTEGER NOT NULL, "
+ " `user_consent_needed` INTEGER NOT NULL, "
+ "CONSTRAINT `fk_module_1` "
+ " FOREIGN KEY(`zone_id`) "
+ " REFERENCES `interior_zone`(`id`) "
+ "); "
+ "CREATE INDEX `access_module.zone_module` ON "
+ "`access_module`(`name`,`zone_id`); "
+ "CREATE INDEX `access_module.fk_module_1_idx` ON "
+ "`access_module`(`zone_id`); "
+
+ /* remote_rpc */
+ "CREATE TABLE `remote_rpc`( "
+ " `id` INTEGER PRIMARY KEY NOT NULL, "
+ " `name` VARCHAR(255) NOT NULL, "
+ " `parameter` VARCHAR(45), "
+ " `module_id` INTEGER NOT NULL, "
+ "CONSTRAINT `fk_remote_rpc_1` "
+ " FOREIGN KEY(`module_id`) "
+ " REFERENCES `access_module`(`id`) "
+ "); "
+ "CREATE INDEX `remote_rpc.fk_remote_rpc_1_idx` ON "
+ "`remote_rpc`(`module_id`); "
+
+ /* module type */
+ "CREATE TABLE IF NOT EXISTS `module_type`( "
+ " `name` VARCHAR(50) NOT NULL, "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " PRIMARY KEY(`name`,`application_id`), "
+ " CONSTRAINT `fk_module_type_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `module_type.fk_module_type_application1_idx` "
+ " ON `module_type`(`application_id`); "
+
+ "CREATE INDEX IF NOT EXISTS `message.fk_messages_languages1_idx` "
+ " ON `message`(`language_code`);"
+ "CREATE INDEX IF NOT EXISTS "
+ "`message.fk_message_consumer_friendly_messages1_idx` "
+ " ON `message`(`message_type_name`);"
+ "CREATE TABLE IF NOT EXISTS `_internal_data`( "
+ " `db_version_hash` INTEGER "
+ " ); "
+ "CREATE TABLE IF NOT EXISTS `_internal_external_consent_status`( "
+ " `id` INTEGER PRIMARY KEY AUTOINCREMENT, "
+ " `entity_type` INTEGER NOT NULL, "
+ " `entity_id` INTEGER NOT NULL, "
+ " `on_off` TEXT NOT NULL "
+ " ); "
+ "COMMIT;";
+
+const std::string kInsertInitData =
+ "INSERT OR IGNORE INTO `usage_and_error_count` ( "
+ " `count_of_iap_buffer_full`, `count_sync_out_of_memory`, "
+ " `count_of_sync_reboots`) VALUES (0, 0, 0); "
+ "INSERT OR IGNORE INTO `module_meta` (`pt_exchanged_at_odometer_x`, "
+ " `pt_exchanged_x_days_after_epoch`, "
+ "`ignition_cycles_since_last_exchange`,"
+ " `flag_update_required`) "
+ " VALUES (0, 0, 0, 0); "
+ "INSERT OR IGNORE INTO `module_config` (`preloaded_pt`, `is_first_run`,"
+ " `exchange_after_x_ignition_cycles`, `exchange_after_x_kilometers`, "
+ " `exchange_after_x_days`, `timeout_after_x_seconds`) "
+ " VALUES(1, 0, 0, 0, 0, 0); "
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('EMERGENCY'); "
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('NAVIGATION'); "
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('VOICECOMMUNICATION'); "
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('COMMUNICATION'); "
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('NORMAL'); "
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('NONE'); "
+ "INSERT OR IGNORE INTO `hmi_level`(`value`) VALUES ('FULL'); "
+ "INSERT OR IGNORE INTO `hmi_level`(`value`) VALUES ('LIMITED'); "
+ "INSERT OR IGNORE INTO `hmi_level`(`value`) VALUES ('BACKGROUND'); "
+ "INSERT OR IGNORE INTO `hmi_level`(`value`) VALUES ('NONE'); "
+ "INSERT OR IGNORE INTO `version` (`number`) VALUES('0'); "
+ "INSERT OR IGNORE INTO `_internal_data` (`db_version_hash`) VALUES(0); "
+ "";
+
+const std::string kDeleteAppGroupPrimary = "DELETE FROM `app_group_primary`";
+
+const std::string kDeleteAppGroupNonPrimary =
+ "DELETE FROM `app_group_non_primary`";
+
+const std::string kDeleteModuleTypes = "DELETE FROM `module_type`";
+
+const std::string kDeleteAllDevices = "DELETE FROM `device`;";
+
+const std::string kSelectAppGroupsPrimary =
+ "SELECT `f`.`name` FROM `app_group_primary` AS `a`"
+ " LEFT JOIN `functional_group` AS `f` "
+ " ON (`f`.`id` = `a`.`functional_group_id`)"
+ " WHERE `a`.`application_id` = ?";
+
+const std::string kSelectAppGroupsNonPrimary =
+ "SELECT `f`.`name` FROM `app_group_non_primary` AS `a`"
+ " LEFT JOIN `functional_group` AS `f` "
+ " ON (`f`.`id` = `a`.`functional_group_id`)"
+ " WHERE `a`.`application_id` = ?";
+
+const std::string kSelectRemoteControlDenied =
+ "SELECT `remote_control_denied` FROM `application` WHERE `id` = ? LIMIT 1";
+
+const std::string kInsertAppGroupPrimary =
+ "INSERT INTO `app_group_primary` (`application_id`, `functional_group_id`)"
+ " SELECT ?, `id` FROM `functional_group` WHERE `name` = ? LIMIT 1";
+
+const std::string kInsertAppGroupNonPrimary =
+ "INSERT INTO `app_group_non_primary` (`application_id`, "
+ "`functional_group_id`)"
+ " SELECT ?, `id` FROM `functional_group` WHERE `name` = ? LIMIT 1";
+
+const std::string kUpdateRemoteControlDenied =
+ "UPDATE `application` SET `remote_control_denied` = ? WHERE `id` = ?";
+
+const std::string kCountInteriorZones =
+ "SELECT COUNT(`id`) FROM `interior_zone`";
+
+const std::string kDeleteInteriorZones = "DELETE FROM `interior_zone`";
+
+const std::string kDeleteAccessModules = "DELETE FROM `access_module`";
+
+const std::string kDeleteRemoteRpc = "DELETE FROM `remote_rpc`";
+
+const std::string kInsertInteriorZone =
+ "INSERT INTO `interior_zone` (`name`, `col`, `row`, `level`) "
+ " VALUES(?, ?, ?, ?)";
+
+const std::string kSelectInteriorZones =
+ "SELECT `id`, `name`, `col`, `row`, `level` FROM `interior_zone`";
+
+const std::string kInsertAccessModule =
+ "INSERT INTO `access_module` (`name`, `zone_id`, `user_consent_needed`) "
+ " VALUES(?, ?, ?)";
+
+const std::string kDeleteAppGroupPrimaryByApplicationId =
+ "DELETE FROM `app_group_primary` WHERE `application_id` = ?";
+
+const std::string kDeleteAppGroupNonPrimaryByApplicationId =
+ "DELETE FROM `app_group_non_primary` WHERE `application_id` = ?";
+
+const std::string kSelectAccessModules =
+ "SELECT `id`, `name` FROM `access_module` "
+ " WHERE `zone_id` = ? AND `user_consent_needed` = ?";
+
+const std::string kInsertRemoteRpc =
+ "INSERT INTO `remote_rpc` (`module_id`, `name`, `parameter`) "
+ " VALUES(?, ?, ?)";
+
+const std::string kSelectRemoteRpcs =
+ "SELECT `name`, `parameter` FROM `remote_rpc` "
+ " WHERE `module_id` = ?";
+
+const std::string kInsertModuleType =
+ "INSERT OR IGNORE INTO `module_type` (`application_id`, `name`) VALUES (?, "
+ "?)";
+
+const std::string kSelectModuleTypes =
+ "SELECT DISTINCT `name` FROM `module_type` WHERE `application_id` = ?";
+
+const std::string kDropSchema =
+ "BEGIN; "
+ "DROP INDEX IF EXISTS `module_type.fk_module_type_application1_idx`; "
+ "DROP TABLE IF EXISTS `module_type`; "
+ "DROP INDEX IF EXISTS `message.fk_messages_languages1_idx`; "
+ "DROP INDEX IF EXISTS "
+ "`message.fk_message_consumer_friendly_messages1_idx`; "
+ "DROP TABLE IF EXISTS `message`; "
+ "DROP INDEX IF EXISTS `endpoint.fk_endpoint_application1_idx`; "
+ "DROP TABLE IF EXISTS `endpoint`; "
+ "DROP INDEX IF EXISTS `consent_group.fk_consent_group_device1_idx`; "
+ "DROP INDEX IF EXISTS "
+ "`consent_group.fk_consent_group_functional_group1_idx`; "
+ "DROP TABLE IF EXISTS `consent_group`; "
+ "DROP TABLE IF EXISTS `external_consent_status_group`; "
+ "DROP TABLE IF EXISTS `external_consent_entities`; "
+ "DROP INDEX IF EXISTS `app_type.fk_app_type_application1_idx`; "
+ "DROP TABLE IF EXISTS `app_type`; "
+ "DROP TABLE IF EXISTS `request_type`; "
+ "DROP INDEX IF EXISTS `nickname.fk_nickname_application1_idx`; "
+ "DROP TABLE IF EXISTS `nickname`; "
+ "DROP INDEX IF EXISTS `app_level.fk_app_level_language2_idx`; "
+ "DROP INDEX IF EXISTS `app_level.fk_app_level_language1_idx`; "
+ "DROP INDEX IF EXISTS `app_level.fk_app_levels_application1_idx`; "
+ "DROP TABLE IF EXISTS `app_level`; "
+ "DROP INDEX IF EXISTS "
+ "`device_consent_group.fk_device_has_functional_group_device1_idx`; "
+ "DROP INDEX IF EXISTS "
+ "`device_consent_group.fk_device_has_functional_group_functional_group1_"
+ "idx`; "
+ "DROP TABLE IF EXISTS `device_consent_group`; "
+ "DROP TABLE IF EXISTS `seconds_between_retry`; "
+ "DROP INDEX IF EXISTS "
+ "`preconsented_group.fk_application_has_functional_group_application2_idx`;"
+ " "
+ "DROP INDEX IF EXISTS "
+ "`preconsented_group.fk_application_has_functional_group_functional_group2_"
+ "idx`; "
+ "DROP TABLE IF EXISTS `preconsented_group`; "
+ "DROP INDEX IF EXISTS "
+ "`app_group_primary.fk_application_has_functional_group_application1_idx`; "
+ "DROP INDEX IF EXISTS "
+ "`app_group_primary.fk_application_has_functional_group_functional_group1_"
+ "idx`; "
+ "DROP TABLE IF EXISTS `app_group_primary`; "
+ "DROP INDEX IF EXISTS "
+ "`app_group_non_primary.fk_application_has_functional_group_application1_"
+ "idx`; "
+ "DROP INDEX IF EXISTS "
+ "`app_group_non_primary.fk_application_has_functional_group_functional_"
+ "group1_idx`; "
+ "DROP TABLE IF EXISTS `app_group_non_primary`; "
+ "DROP TABLE IF EXISTS `interior_zone`; "
+ "DROP TABLE IF EXISTS `access_module`; "
+ "DROP INDEX IF EXISTS `access_module.zone_module`; "
+ "DROP INDEX IF EXISTS `access_module.fk_module_1_idx`; "
+ "DROP INDEX IF EXISTS "
+ "`app_group.fk_application_has_functional_group_application1_idx`; "
+ "DROP INDEX IF EXISTS "
+ "`app_group.fk_application_has_functional_group_functional_group1_idx`; "
+ "DROP TABLE IF EXISTS `app_group`; "
+ "DROP INDEX IF EXISTS `application.fk_application_priorities1_idx`; "
+ "DROP INDEX IF EXISTS `application.fk_application_hmi_level1_idx`; "
+ "DROP TABLE IF EXISTS `application`; "
+ "DROP INDEX IF EXISTS `rpc.select_rpc_name_hmi_level`; "
+ "DROP INDEX IF EXISTS `rpc.fk_rpc_functional_group1_idx`; "
+ "DROP INDEX IF EXISTS `rpc.fk_rpc_hmi_level1_idx`; "
+ "DROP TABLE IF EXISTS `rpc`; "
+ "DROP TABLE IF EXISTS `version`; "
+ "DROP TABLE IF EXISTS `message_type`; "
+ "DROP TABLE IF EXISTS `language`; "
+ "DROP INDEX IF EXISTS "
+ "`notifications_by_priority.fk_notifications_by_priority_priority1_idx`; "
+ "DROP TABLE IF EXISTS `notifications_by_priority`; "
+ "DROP TABLE IF EXISTS `hmi_level`; "
+ "DROP TABLE IF EXISTS `priority`; "
+ "DROP TABLE IF EXISTS `functional_group`; "
+ "DROP TABLE IF EXISTS `module_config`; "
+ "DROP TABLE IF EXISTS `remote_rpc`; "
+ "DROP INDEX IF EXISTS `remote_rpc.fk_remote_rpc_1_idx`; "
+ "DROP TABLE IF EXISTS `module_meta`; "
+ "DROP TABLE IF EXISTS `usage_and_error_count`; "
+ "DROP TABLE IF EXISTS `device`; "
+ "DROP TABLE IF EXISTS `_internal_data`; "
+ "DROP TABLE IF EXISTS `_internal_external_consent_status`; "
+ "COMMIT; "
+ "VACUUM;";
+
+const std::string kDeleteData =
+ "BEGIN; "
+ "DELETE FROM `message`; "
+ "DELETE FROM `module_type`; "
+ "DELETE FROM `endpoint`; "
+ "DELETE FROM `consent_group`; "
+ "DELETE FROM `external_consent_status_group`; "
+ "DELETE FROM `external_consent_entities`; "
+ "DELETE FROM `app_type`; "
+ "DELETE FROM `nickname`; "
+ "DELETE FROM `app_level`; "
+ "DELETE FROM `device_consent_group`; "
+ "DELETE FROM `seconds_between_retry`; "
+ "DELETE FROM `preconsented_group`; "
+ "DELETE FROM `app_group`; "
+ "DELETE FROM `application`; "
+ "DELETE FROM `rpc`; "
+ "DELETE FROM `app_group_primary`; "
+ "DELETE FROM `app_group_non_primary`; "
+ "DELETE FROM `interior_zone`; "
+ "DELETE FROM `access_module`; "
+ "DELETE FROM `version`; "
+ "DELETE FROM `message_type`; "
+ "DELETE FROM `language`; "
+ "DELETE FROM `notifications_by_priority`; "
+ "DELETE FROM `hmi_level`; "
+ "DELETE FROM `priority`; "
+ "DELETE FROM `functional_group`; "
+ "DELETE FROM `module_config`; "
+ "DELETE FROM `module_meta`; "
+ "DELETE FROM `remote_rpc`; "
+ "DELETE FROM `usage_and_error_count`; "
+ "DELETE FROM `device`; "
+ "DELETE FROM `request_type`; "
+ "COMMIT; "
+ "VACUUM;";
+
+const std::string kCheckDBIntegrity = "PRAGMA integrity_check";
+
+const std::string kCheckPgNumber = "PRAGMA page_count";
+
+const std::string kSelectRpc =
+ "SELECT DISTINCT `rpc`.`parameter` FROM `rpc` "
+ " JOIN `app_group` AS `g` ON (`g`.`functional_group_id` = "
+ "`rpc`.`functional_group_id` "
+ " AND (`g`.`application_id` = ?)) "
+ "WHERE `rpc`.`hmi_level_value` = ? AND `rpc`.`name` = ?";
+
+const std::string kSelectPreloaded =
+ "SELECT `preloaded_pt` FROM `module_config` "
+ "WHERE `preloaded_pt` = 1 LIMIT 1";
+
+const std::string kUpdatePreloaded =
+ "UPDATE `module_config` SET `preloaded_pt` = ?";
+
+const std::string kIsFirstRun = "SELECT `is_first_run` FROM `module_config` ";
+
+const std::string kSetNotFirstRun =
+ "UPDATE `module_config` SET `is_first_run`= 0 ";
+
+const std::string kSelectEndpoint =
+ "SELECT `url`, `application_id` FROM `endpoint` WHERE `service` = ? ";
+
+const std::string kSelectLockScreenIcon =
+ "SELECT `url` FROM `endpoint` WHERE `service` = ? AND `application_id` = ?";
+
+const std::string kInsertFunctionalGroup =
+ "INSERT INTO `functional_group` (`id`, `name`, `user_consent_prompt`) "
+ " VALUES (?, ?, ?)";
+
+const std::string kInsertRpc =
+ "INSERT INTO `rpc` (`name`, `hmi_level_value`, `functional_group_id`) "
+ " VALUES (?, ?, ?)";
+
+const std::string kInsertExternalConsentEntity =
+ "INSERT INTO `external_consent_entities` (`group_id`, `entity_type`, "
+ "`entity_id`, `on_off`) "
+ " VALUES (?, ?, ?, ?)";
+
+const std::string kInsertRpcWithParameter =
+ "INSERT INTO `rpc` (`name`, `hmi_level_value`, `parameter`, "
+ "`functional_group_id`) "
+ " VALUES (?, ?, ?, ?)";
+
+const std::string kInsertApplication =
+ "INSERT OR IGNORE INTO `application` (`id`, `priority_value`, "
+ "`is_revoked`, `memory_kb`,"
+ " `heart_beat_timeout_ms`) VALUES (?,?,?,?,?)";
+
+const std::string kInsertAppGroup =
+ "INSERT INTO `app_group` (`application_id`, `functional_group_id`)"
+ " SELECT ?, `id` FROM `functional_group` WHERE `name` = ? LIMIT 1";
+
+const std::string kInsertNickname =
+ "INSERT OR IGNORE INTO `nickname` (`application_id`, `name`) VALUES (?, ?)";
+
+const std::string kInsertAppType =
+ "INSERT OR IGNORE INTO `app_type` (`application_id`, `name`) VALUES (?, ?)";
+
+const std::string kInsertRequestType =
+ "INSERT OR IGNORE INTO `request_type` (`application_id`, `request_type`) "
+ "VALUES (?, ?)";
+
+const std::string kUpdateVersion = "UPDATE `version` SET `number`= ?";
+
+const std::string kInsertMessageType =
+ "INSERT OR IGNORE INTO `message_type` (`name`) VALUES (?)";
+
+const std::string kInsertLanguage =
+ "INSERT OR IGNORE INTO `language` (`code`) VALUES (?)";
+
+const std::string kInsertMessageString =
+ "INSERT INTO `message` (`tts`, `label`, `line1`, `line2`, `language_code`, "
+ " `message_type_name`, `textBody`) VALUES (?, ?, ?, ?, ?, ?, ?)";
+
+const std::string kUpdateModuleConfig =
+ "UPDATE `module_config` SET `preloaded_pt` = ?, "
+ " `exchange_after_x_ignition_cycles` = ?,"
+ " `exchange_after_x_kilometers` = ?, `exchange_after_x_days` = ?, "
+ " `timeout_after_x_seconds` = ?, `vehicle_make` = ?, "
+ " `vehicle_model` = ?, `vehicle_year` = ?, `preloaded_date` = ?, "
+ "`certificate` = ?, `user_consent_passengersRC` = ?, "
+ "`country_consent_passengersRC` = ?";
+
+const std::string kInsertEndpoint =
+ "INSERT INTO `endpoint` (`service`, `url`, `application_id`) "
+ " VALUES (?, ?, ?)";
+
+const std::string kInsertSecondsBetweenRetry =
+ "INSERT INTO `seconds_between_retry` (`index`, `value`) VALUES (?, ?)";
+
+const std::string kInsertNotificationsByPriority =
+ "INSERT OR REPLACE INTO `notifications_by_priority` (`priority_value`, "
+ "`value`) "
+ " VALUES (?, ?)";
+
+const std::string kInsertDeviceData =
+ "INSERT OR IGNORE INTO `device` (`id`) VALUES (?)";
+
+const std::string kInsertAppLevel =
+ "INSERT INTO `app_level` (`application_id`, `minutes_in_hmi_full`,"
+ "`minutes_in_hmi_limited` ,`minutes_in_hmi_background`,"
+ "`minutes_in_hmi_none`,`count_of_user_selections`,"
+ "`count_of_rejections_sync_out_of_memory`,"
+ "`count_of_rejections_nickname_mismatch`,"
+ "`count_of_rejections_duplicate_name`,`count_of_rejected_rpcs_calls`,"
+ "`count_of_rpcs_sent_in_hmi_none`,`count_of_removals_for_bad_behavior`,"
+ "`count_of_run_attempts_while_revoked`,`app_registration_language_gui`,"
+ "`app_registration_language_vui`, `count_of_tls_errors`) "
+ "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
+
+const std::string kDeleteSecondsBetweenRetries =
+ "DELETE FROM `seconds_between_retry`";
+
+const std::string kDeleteEndpoint = "DELETE FROM `endpoint`";
+
+const std::string kDeleteAppLevel = "DELETE FROM `app_level`";
+
+const std::string kDeleteMessageString = "DELETE FROM `message`";
+
+const std::string kDeleteFunctionalGroup = "DELETE FROM `functional_group`";
+
+const std::string kDeleteRpc = "DELETE FROM `rpc`";
+
+const std::string kDeleteExternalConsentEntities =
+ "DELETE FROM `external_consent_entities`";
+
+const std::string kDeleteAppGroup = "DELETE FROM `app_group`";
+
+const std::string kSelectModuleConfig =
+ "SELECT `preloaded_pt`, `exchange_after_x_ignition_cycles`, "
+ " `exchange_after_x_kilometers`, `exchange_after_x_days`, "
+ " `timeout_after_x_seconds`, `vehicle_make`,"
+ " `vehicle_model`, `vehicle_year`, `preloaded_date`, `certificate`, "
+ " `user_consent_passengersRC` , `country_consent_passengersRC` "
+ " FROM `module_config`";
+
+const std::string kSelectEndpoints =
+ "SELECT `url`, `service`, `application_id` FROM `endpoint` ";
+
+const std::string kSelectNotificationsPerMin =
+ "SELECT `priority_value`, `value` FROM notifications_by_priority";
+
+const std::string kSelectNotificationsPerPriority =
+ "SELECT `value` FROM notifications_by_priority WHERE `priority_value` = ? ";
+
+const std::string kSelectAppLevels = "SELECT `application_id` FROM `app_level`";
+
+const std::string kSelectDeviceData = "SELECT * FROM `device`";
+
+const std::string kSelectFunctionalGroups =
+ "SELECT `id`,`name`, `user_consent_prompt` "
+ "FROM `functional_group`";
+
+const std::string kSelectAllRpcs =
+ "SELECT `name`, `hmi_level_value`, `parameter` "
+ "FROM `rpc` WHERE `functional_group_id` = ? ";
+
+const std::string kSelectExternalConsentEntities =
+ "SELECT `entity_type`, `entity_id`, `on_off` "
+ "FROM `external_consent_entities` WHERE `group_id` = ? ";
+
+const std::string kSelectUserMsgsVersion =
+ "SELECT DISTINCT `number` FROM `version`";
+
+const std::string kSelectAppPolicies =
+ "SELECT `id`, `priority_value`, `memory_kb`, "
+ " `heart_beat_timeout_ms` FROM `application`";
+
+const std::string kCollectFriendlyMsg = "SELECT * FROM `message`";
+
+const std::string kSelectAppGroups =
+ "SELECT `f`.`name` FROM `app_group` AS `a`"
+ " LEFT JOIN `functional_group` AS `f` "
+ " ON (`f`.`id` = `a`.`functional_group_id`)"
+ " WHERE `a`.`application_id` = ?";
+
+const std::string kSelectNicknames =
+ "SELECT DISTINCT `name` FROM `nickname` "
+ "WHERE `application_id` = ?";
+
+const std::string kSelectAppTypes =
+ "SELECT DISTINCT `name` FROM `app_type` "
+ "WHERE `application_id` = ?";
+
+const std::string kSelectRequestTypes =
+ "SELECT DISTINCT `request_type` FROM `request_type` WHERE `application_id` "
+ "= ?";
+
+const std::string kSelectSecondsBetweenRetries =
+ "SELECT `value` FROM `seconds_between_retry` ORDER BY `index`";
+
+const std::string kSelectIgnitionCycles =
+ "SELECT `c`.`exchange_after_x_ignition_cycles`, "
+ " `m`.`ignition_cycles_since_last_exchange` "
+ " FROM `module_config` AS `c`, `module_meta` AS `m` "
+ "LIMIT 1";
+
+const std::string kSelectKilometers =
+ "SELECT `c`.`exchange_after_x_kilometers`, "
+ " `m`.`pt_exchanged_at_odometer_x` "
+ " FROM `module_config` AS `c`, `module_meta` AS `m` "
+ "LIMIT 1";
+
+const std::string kSelectDays =
+ "SELECT `c`.`exchange_after_x_days`, "
+ " `m`.`pt_exchanged_x_days_after_epoch` "
+ " FROM `module_config` AS `c`, `module_meta` AS `m` "
+ "LIMIT 1";
+
+const std::string kIncrementIgnitionCycles =
+ "UPDATE `module_meta` SET `ignition_cycles_since_last_exchange` = 1 + "
+ " `ignition_cycles_since_last_exchange`";
+
+const std::string kResetIgnitionCycles =
+ "UPDATE `module_meta` SET `ignition_cycles_since_last_exchange` = 0";
+
+const std::string kSelectTimeoutResponse =
+ "SELECT `timeout_after_x_seconds` FROM `module_config` LIMIT 1";
+
+const std::string kUpdateFlagUpdateRequired =
+ "UPDATE `module_meta` SET `flag_update_required` = ?";
+
+const std::string kSelectFlagUpdateRequired =
+ "SELECT `flag_update_required` FROM `module_meta` LIMIT 1";
+
+const std::string kUpdateCountersSuccessfulUpdate =
+ "UPDATE `module_meta` SET `pt_exchanged_at_odometer_x` = ?,"
+ "`pt_exchanged_x_days_after_epoch` = ?";
+
+const std::string kDeleteApplication = "DELETE FROM `application`";
+
+const std::string kDeleteRequestType = "DELETE FROM `request_type`";
+
+const std::string kSelectApplicationRevoked =
+ "SELECT `is_revoked` FROM `application` WHERE `id` = ?";
+
+const std::string kUpdateApplicationCustomData =
+ "UPDATE `application` SET `is_revoked` = ?, `is_default` = ?,"
+ "`is_predata` = ? WHERE `id` = ?";
+
+const std::string kSelectApplicationRepresented =
+ "SELECT COUNT(`id`) FROM `application` WHERE `id` = ?";
+
+const std::string kSelectApplicationIsDefault =
+ "SELECT `is_default` FROM `application` WHERE `id` = ?";
+
+const std::string kUpdateIsDefault =
+ "UPDATE `application` SET `is_default` = ? WHERE `id` = ?";
+
+const std::string kDeleteDevice = "DELETE FROM `device` WHERE `id` = ?";
+
+const std::string kDeleteAppGroupByApplicationId =
+ "DELETE FROM `app_group` WHERE `application_id` = ?";
+
+const std::string kInsertApplicationFull =
+ "INSERT OR IGNORE INTO `application` (`id`, `keep_context`, `steal_focus`, "
+ " `default_hmi`, `priority_value`, `is_revoked`, `is_default`, "
+ "`is_predata`, "
+ " `memory_kb`, `heart_beat_timeout_ms`) "
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+const std::string kSelectApplicationFull =
+ "SELECT `keep_context`, `steal_focus`, `default_hmi`, `priority_value`, "
+ " `is_revoked`, `is_default`, `is_predata`, `memory_kb`,"
+ " `heart_beat_timeout_ms` FROM `application` WHERE `id` = ?";
+
+const std::string kSelectDBVersion =
+ "SELECT `db_version_hash` from `_internal_data`";
+
+const std::string kUpdateDBVersion =
+ "UPDATE `_internal_data` SET `db_version_hash` = ? ";
+
+} // namespace sql_pt
+} // namespace policy
diff --git a/src/components/policy/policy_external/src/sql_pt_representation.cc b/src/components/policy/policy_external/src/sql_pt_representation.cc
new file mode 100644
index 0000000000..1732f3c774
--- /dev/null
+++ b/src/components/policy/policy_external/src/sql_pt_representation.cc
@@ -0,0 +1,1879 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sstream>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "utils/logger.h"
+#include "utils/date_time.h"
+#include "utils/sqlite_wrapper/sql_database.h"
+#include "utils/file_system.h"
+#include "utils/gen_hash.h"
+#include "policy/sql_pt_representation.h"
+#include "policy/sql_wrapper.h"
+#include "policy/sql_pt_ext_queries.h"
+#include "policy/sql_pt_queries.h"
+#include "policy/policy_helper.h"
+#include "policy/cache_manager.h"
+#include "config_profile/profile.h"
+
+namespace policy {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Policy")
+
+namespace dbms = utils::dbms;
+
+namespace {
+template <typename T, typename K>
+void InsertUnique(K value, T* array) {
+ uint32_t i = 0;
+ for (; i < array->size() && array->at(i) != value; ++i) {
+ continue;
+ }
+ if (array->size() == i) {
+ array->push_back(value);
+ }
+}
+
+#ifdef CUSTOMER_PASA
+const char* kDatabaseName = "policy.db";
+#else // CUSTOMER_PASA
+const char* kDatabaseName = "policy";
+#endif // CUSTOMER_PASA
+
+const std::string kExternalConsentEntitiesTypeStringOn = "ON";
+const std::string kExternalConsentEntitiesTypeStringOff = "OFF";
+
+} // namespace
+
+SQLPTRepresentation::SQLPTRepresentation()
+ : db_(new utils::dbms::SQLDatabase(kDatabaseName)) {
+ is_in_memory = false;
+}
+
+SQLPTRepresentation::SQLPTRepresentation(bool in_memory) {
+ is_in_memory = in_memory;
+#ifdef __QNX__
+ db_ = new utils::dbms::SQLDatabase(kDatabaseName);
+#else // __QNX__
+ if (in_memory) {
+ db_ = new utils::dbms::SQLDatabase();
+ } else {
+ db_ = new utils::dbms::SQLDatabase(kDatabaseName);
+ }
+#endif // __QNX__
+}
+
+SQLPTRepresentation::~SQLPTRepresentation() {
+ db_->Close();
+ delete db_;
+}
+
+std::string SQLPTRepresentation::GetLockScreenIconUrl() const {
+ utils::dbms::SQLQuery query(db());
+ std::string ret;
+ if (query.Prepare(sql_pt::kSelectLockScreenIcon)) {
+ query.Bind(0, std::string("lock_screen_icon_url"));
+ query.Bind(1, std::string("default"));
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect select from notifications by priority.");
+ return ret;
+ }
+
+ if (!query.IsNull(0)) {
+ ret = query.GetString(0);
+ }
+
+ } else {
+ LOG4CXX_WARN(logger_, "Invalid select endpoints statement.");
+ }
+ return ret;
+}
+
+void SQLPTRepresentation::CheckPermissions(const PTString& app_id,
+ const PTString& hmi_level,
+ const PTString& rpc,
+ CheckPermissionResult& result) {
+ utils::dbms::SQLQuery query(db());
+
+ if (!query.Prepare(sql_pt::kSelectRpc)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect select statement from rpcs"
+ << query.LastError().text());
+ return;
+ }
+ query.Bind(0, app_id);
+ query.Bind(1, hmi_level);
+ query.Bind(2, rpc);
+
+ bool ret = query.Next();
+ result.hmi_level_permitted = ret ? kRpcAllowed : kRpcDisallowed;
+ LOG4CXX_INFO(logger_,
+ "Level is " << (result.hmi_level_permitted == kRpcAllowed
+ ? "permitted"
+ : "not permitted"));
+ std::string parameter;
+ while (ret) {
+ if (!query.IsNull(0)) {
+ parameter = query.GetString(0);
+ result.list_of_allowed_params.insert(parameter);
+ }
+ ret = query.Next();
+ }
+}
+
+bool SQLPTRepresentation::IsPTPreloaded() {
+ utils::dbms::SQLQuery query(db());
+ return query.Prepare(sql_pt::kSelectPreloaded) && query.Next();
+}
+
+int SQLPTRepresentation::IgnitionCyclesBeforeExchange() {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectIgnitionCycles) || !query.Exec()) {
+ LOG4CXX_WARN(logger_, "Can not select ignition cycles");
+ return 0;
+ }
+ int limit = query.GetInteger(0);
+ int current = query.GetInteger(1);
+
+ if (limit < 0 || current < 0 || current > limit) {
+ return 0;
+ }
+
+ return limit - current;
+}
+
+int SQLPTRepresentation::KilometersBeforeExchange(int current) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectKilometers) || !query.Exec()) {
+ LOG4CXX_WARN(logger_, "Can not select kilometers");
+ return 0;
+ }
+ int limit = query.GetInteger(0);
+ int last = query.GetInteger(1);
+
+ if (limit < 0 || last < 0 || current < 0 || current < last ||
+ limit < (current - last)) {
+ return 0;
+ }
+
+ return limit - (current - last);
+}
+
+bool SQLPTRepresentation::SetCountersPassedForSuccessfulUpdate(
+ int kilometers, int days_after_epoch) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kUpdateCountersSuccessfulUpdate)) {
+ LOG4CXX_WARN(logger_,
+ "Wrong update query for counters on successful update.");
+ return false;
+ }
+ query.Bind(0, kilometers);
+ query.Bind(1, days_after_epoch);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed to update counters on successful update.");
+ return false;
+ }
+ return true;
+}
+
+int SQLPTRepresentation::DaysBeforeExchange(uint16_t current) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectDays) || !query.Exec()) {
+ LOG4CXX_WARN(logger_, "Can not select days");
+ return 0;
+ }
+ int limit = query.GetInteger(0);
+ int last = query.GetInteger(1);
+
+ if (0 == last) {
+ return limit;
+ }
+
+ if (limit < 0 || last < 0 || current < last || limit < (current - last)) {
+ return 0;
+ }
+
+ return limit - (current - last);
+}
+
+int SQLPTRepresentation::TimeoutResponse() {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectTimeoutResponse) || !query.Exec()) {
+ LOG4CXX_INFO(logger_, "Can not select timeout response for retry sequence");
+ const int defaultTimeout = 30 * date_time::DateTime::MILLISECONDS_IN_SECOND;
+ return defaultTimeout;
+ }
+ return query.GetInteger(0) * date_time::DateTime::MILLISECONDS_IN_SECOND;
+}
+
+bool SQLPTRepresentation::SecondsBetweenRetries(std::vector<int>* seconds) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectSecondsBetweenRetries)) {
+ LOG4CXX_INFO(logger_,
+ "Incorrect select statement from seconds between retries");
+ return false;
+ }
+ while (query.Next()) {
+ seconds->push_back(query.GetInteger(0));
+ }
+ return true;
+}
+
+std::vector<UserFriendlyMessage> SQLPTRepresentation::GetUserFriendlyMsg(
+ const std::vector<std::string>& msg_codes, const std::string& language) {
+ std::vector<UserFriendlyMessage> result;
+ std::vector<std::string>::const_iterator it = msg_codes.begin();
+ std::vector<std::string>::const_iterator it_end = msg_codes.end();
+ for (; it != it_end; ++it) {
+ UserFriendlyMessage msg;
+ msg.message_code = *it;
+ result.push_back(msg);
+ }
+ return result;
+}
+
+EndpointUrls SQLPTRepresentation::GetUpdateUrls(int service_type) {
+ LOG4CXX_INFO(logger_,
+ "SQLPTRepresentation::GetUpdateUrls for " << service_type);
+ utils::dbms::SQLQuery query(db());
+ EndpointUrls ret;
+ if (query.Prepare(sql_pt::kSelectEndpoint)) {
+ query.Bind(0, service_type);
+ while (query.Next()) {
+ EndpointData data;
+
+ data.url.push_back(query.GetString(0));
+ if (!query.IsNull(1)) {
+ data.app_id = query.GetString(1);
+ }
+ ret.push_back(data);
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "Invalid select endpoints statement.");
+ }
+ return ret;
+}
+
+int SQLPTRepresentation::GetNotificationsNumber(const std::string& priority) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectNotificationsPerPriority)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect select statement for priority "
+ "notification number.");
+ return 0;
+ }
+ query.Bind(0, priority);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect select from notifications by priority.");
+ return 0;
+ }
+
+ if (!query.IsNull(0)) {
+ return query.GetInteger(0);
+ }
+
+ return 0;
+}
+
+bool SQLPTRepresentation::GetPriority(const std::string& policy_app_id,
+ std::string* priority) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (NULL == priority) {
+ LOG4CXX_WARN(logger_, "Input priority parameter is null.");
+ return false;
+ }
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectPriority)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement for priority.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Error during select priority.");
+ return false;
+ }
+
+ if (query.IsNull(0)) {
+ priority->clear();
+ return true;
+ }
+
+ priority->assign(query.GetString(0));
+
+ return true;
+}
+
+InitResult SQLPTRepresentation::Init(const PolicySettings* settings) {
+ settings_ = settings;
+ LOG4CXX_AUTO_TRACE(logger_);
+#ifdef BUILD_TESTS
+ open_counter_ = 0;
+#endif // BUILD_TESTS
+#ifndef __QNX__
+ if (!is_in_memory) {
+ const std::string& path = get_settings().app_storage_folder();
+ if (!path.empty()) {
+ db_->set_path(path + "/");
+ }
+ }
+#endif // __QNX__
+ if (!db_->Open()) {
+ LOG4CXX_ERROR(logger_, "Failed opening database.");
+ LOG4CXX_INFO(logger_, "Starting opening retries.");
+ const uint16_t attempts = get_settings().attempts_to_open_policy_db();
+ LOG4CXX_DEBUG(logger_, "Total attempts number is: " << attempts);
+ bool is_opened = false;
+ const uint16_t open_attempt_timeout_ms =
+ get_settings().open_attempt_timeout_ms();
+ const useconds_t sleep_interval_mcsec = open_attempt_timeout_ms * 1000;
+ LOG4CXX_DEBUG(logger_,
+ "Open attempt timeout(ms) is: " << open_attempt_timeout_ms);
+ for (int i = 0; i < attempts; ++i) {
+ usleep(sleep_interval_mcsec);
+ LOG4CXX_INFO(logger_, "Attempt: " << i + 1);
+#ifdef BUILD_TESTS
+ ++open_counter_;
+#endif // BUILD_TESTS
+ 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 InitResult::FAIL;
+ }
+ }
+#ifndef __QNX__
+ if (!db_->IsReadWrite()) {
+ LOG4CXX_ERROR(logger_, "There are no read/write permissions for database");
+ return InitResult::FAIL;
+ }
+
+#endif // __QNX__
+ utils::dbms::SQLQuery check_pages(db());
+ if (!check_pages.Prepare(sql_pt::kCheckPgNumber) || !check_pages.Next()) {
+ LOG4CXX_WARN(logger_, "Incorrect pragma for page counting.");
+ } else {
+ if (0 < check_pages.GetInteger(0)) {
+ utils::dbms::SQLQuery db_check(db());
+ if (!db_check.Prepare(sql_pt::kCheckDBIntegrity)) {
+ LOG4CXX_WARN(logger_, "Incorrect pragma for integrity check.");
+ } else {
+ while (db_check.Next()) {
+ if (db_check.GetString(0).compare("ok") == 0) {
+ utils::dbms::SQLQuery check_first_run(db());
+ if (check_first_run.Prepare(sql_pt::kIsFirstRun) &&
+ check_first_run.Next()) {
+ LOG4CXX_INFO(logger_,
+ "Selecting is first run "
+ << check_first_run.GetBoolean(0));
+ if (check_first_run.GetBoolean(0)) {
+ utils::dbms::SQLQuery set_not_first_run(db());
+ set_not_first_run.Exec(sql_pt::kSetNotFirstRun);
+ return InitResult::SUCCESS;
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "Incorrect select is first run");
+ }
+ return InitResult::EXISTS;
+ } else {
+ LOG4CXX_ERROR(logger_,
+ "Existing policy table representation is invlaid.");
+ // TODO(PV): add handle
+ return InitResult::FAIL;
+ }
+ }
+ }
+ }
+ }
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kCreateSchema)) {
+ LOG4CXX_ERROR(
+ logger_,
+ "Failed creating schema of database: " << query.LastError().text());
+ return InitResult::FAIL;
+ }
+ if (!query.Exec(sql_pt::kInsertInitData)) {
+ LOG4CXX_ERROR(
+ logger_,
+ "Failed insert init data to database: " << query.LastError().text());
+ return InitResult::FAIL;
+ }
+ return InitResult::SUCCESS;
+}
+
+bool SQLPTRepresentation::Close() {
+ db_->Close();
+ return db_->LastError().number() == utils::dbms::OK;
+}
+
+const VehicleInfo SQLPTRepresentation::GetVehicleInfo() const {
+ policy_table::ModuleConfig module_config;
+ GatherModuleConfig(&module_config);
+ VehicleInfo vehicle_info;
+ vehicle_info.vehicle_make = *module_config.vehicle_make;
+ vehicle_info.vehicle_model = *module_config.vehicle_model;
+ vehicle_info.vehicle_year = *module_config.vehicle_year;
+ return vehicle_info;
+}
+
+bool SQLPTRepresentation::Drop() {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDropSchema)) {
+ LOG4CXX_WARN(logger_,
+ "Failed dropping database: " << query.LastError().text());
+ return false;
+ }
+ return true;
+}
+
+void SQLPTRepresentation::WriteDb() {
+ db_->Backup();
+}
+
+bool SQLPTRepresentation::Clear() {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteData)) {
+ LOG4CXX_ERROR(logger_,
+ "Failed clearing database: " << query.LastError().text());
+ return false;
+ }
+ if (!query.Exec(sql_pt::kInsertInitData)) {
+ LOG4CXX_ERROR(
+ logger_,
+ "Failed insert init data to database: " << query.LastError().text());
+ return false;
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::RefreshDB() {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDropSchema)) {
+ LOG4CXX_WARN(logger_,
+ "Failed dropping database: " << query.LastError().text());
+ return false;
+ }
+ if (!query.Exec(sql_pt::kCreateSchema)) {
+ LOG4CXX_ERROR(
+ logger_,
+ "Failed creating schema of database: " << query.LastError().text());
+ return false;
+ }
+ if (!query.Exec(sql_pt::kInsertInitData)) {
+ LOG4CXX_ERROR(
+ logger_,
+ "Failed insert init data to database: " << query.LastError().text());
+ return false;
+ }
+ return true;
+}
+
+utils::SharedPtr<policy_table::Table> SQLPTRepresentation::GenerateSnapshot()
+ const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::SharedPtr<policy_table::Table> table = new policy_table::Table();
+ GatherModuleMeta(&*table->policy_table.module_meta);
+ GatherModuleConfig(&table->policy_table.module_config);
+ GatherUsageAndErrorCounts(&*table->policy_table.usage_and_error_counts);
+ GatherDeviceData(&*table->policy_table.device_data);
+ GatherFunctionalGroupings(&table->policy_table.functional_groupings);
+ GatherConsumerFriendlyMessages(
+ &*table->policy_table.consumer_friendly_messages);
+ GatherApplicationPoliciesSection(&table->policy_table.app_policies_section);
+ return table;
+}
+
+void SQLPTRepresentation::GatherModuleMeta(
+ policy_table::ModuleMeta* meta) const {
+ LOG4CXX_INFO(logger_, "Gather Module Meta Info");
+ meta->mark_initialized();
+ // Section Module Meta is empty for SDL specific
+}
+
+void SQLPTRepresentation::GatherModuleConfig(
+ policy_table::ModuleConfig* config) const {
+ LOG4CXX_INFO(logger_, "Gather Configuration Info");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectModuleConfig) || !query.Next()) {
+ LOG4CXX_WARN(logger_, "Incorrect select statement for module config");
+ } else {
+ *config->preloaded_pt = query.GetBoolean(0);
+ config->exchange_after_x_ignition_cycles = query.GetInteger(1);
+ config->exchange_after_x_kilometers = query.GetInteger(2);
+ config->exchange_after_x_days = query.GetInteger(3);
+ config->timeout_after_x_seconds = query.GetInteger(4);
+ *config->vehicle_make = query.GetString(5);
+ *config->vehicle_model = query.GetString(6);
+ *config->vehicle_year = query.GetString(7);
+ *config->preloaded_date = query.GetString(8);
+ *config->certificate = query.GetString(9);
+ }
+
+ utils::dbms::SQLQuery endpoints(db());
+ if (!endpoints.Prepare(sql_pt::kSelectEndpoints)) {
+ LOG4CXX_WARN(logger_, "Incorrect select statement for endpoints");
+ } else {
+ while (endpoints.Next()) {
+ std::stringstream stream;
+ stream << "0x0" << endpoints.GetInteger(1);
+ config->endpoints[stream.str()][endpoints.GetString(2)].push_back(
+ endpoints.GetString(0));
+ }
+ }
+
+ utils::dbms::SQLQuery notifications(db());
+ if (!notifications.Prepare(sql_pt::kSelectNotificationsPerMin)) {
+ LOG4CXX_WARN(logger_, "Incorrect select statement for notifications");
+ } else {
+ while (notifications.Next()) {
+ config->notifications_per_minute_by_priority[notifications.GetString(0)] =
+ notifications.GetInteger(1);
+ }
+ }
+ utils::dbms::SQLQuery seconds(db());
+ if (!seconds.Prepare(sql_pt::kSelectSecondsBetweenRetries)) {
+ LOG4CXX_INFO(logger_,
+ "Incorrect select statement from seconds between retries");
+ } else {
+ while (seconds.Next()) {
+ config->seconds_between_retries.push_back(seconds.GetInteger(0));
+ }
+ }
+}
+
+bool SQLPTRepresentation::GatherUsageAndErrorCounts(
+ policy_table::UsageAndErrorCounts* counts) const {
+ LOG4CXX_INFO(logger_, "Gather Usage and Error Counts.");
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt::kSelectAppLevels)) {
+ policy_table::AppLevel app_level_empty;
+ app_level_empty.mark_initialized();
+ while (query.Next()) {
+ (*counts->app_level)[query.GetString(0)] = app_level_empty;
+ }
+ }
+ return true;
+}
+
+void SQLPTRepresentation::GatherDeviceData(
+ policy_table::DeviceData* data) const {
+ LOG4CXX_INFO(logger_, "Gather device data.");
+ data->mark_initialized();
+
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt::kSelectDeviceData)) {
+ policy_table::DeviceParams device_data_empty;
+ device_data_empty.mark_initialized();
+ while (query.Next()) {
+ (*data)[query.GetString(0)] = device_data_empty;
+ }
+ }
+}
+
+bool SQLPTRepresentation::GatherFunctionalGroupings(
+ policy_table::FunctionalGroupings* groups) const {
+ LOG4CXX_INFO(logger_, "Gather Functional Groupings info");
+ utils::dbms::SQLQuery func_group(db());
+ if (!func_group.Prepare(sql_pt::kSelectFunctionalGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from functional_groupings");
+ return false;
+ }
+
+ utils::dbms::SQLQuery rpcs(db());
+ if (!rpcs.Prepare(sql_pt::kSelectAllRpcs)) {
+ LOG4CXX_WARN(logger_, "Incorrect select all from rpc");
+ return false;
+ }
+
+ utils::dbms::SQLQuery external_consent_entities(db());
+ if (!external_consent_entities.Prepare(
+ sql_pt::kSelectExternalConsentEntities)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect select statement for 'external_consent_entities'.");
+ return false;
+ }
+
+ while (func_group.Next()) {
+ policy_table::Rpcs rpcs_tbl;
+
+ if (!func_group.IsNull(2)) {
+ *rpcs_tbl.user_consent_prompt = func_group.GetString(2);
+ }
+
+ const int group_id = func_group.GetInteger(0);
+
+ rpcs.Bind(0, group_id);
+
+ while (rpcs.Next()) {
+ if (!rpcs.IsNull(1)) {
+ policy_table::HmiLevel level;
+ if (policy_table::EnumFromJsonString(rpcs.GetString(1), &level)) {
+ InsertUnique(level, &rpcs_tbl.rpcs[rpcs.GetString(0)].hmi_levels);
+ }
+ }
+ if (!rpcs.IsNull(2)) {
+ policy_table::Parameter param;
+ if (policy_table::EnumFromJsonString(rpcs.GetString(2), &param)) {
+ // EMPTY is a special mark to specify that 'parameters' section is
+ // present, but has no parameters. It is not valid parameter value.
+ if (policy_table::P_EMPTY == param) {
+ (*rpcs_tbl.rpcs[rpcs.GetString(0)].parameters).mark_initialized();
+ continue;
+ }
+ InsertUnique(param, &(*rpcs_tbl.rpcs[rpcs.GetString(0)].parameters));
+ }
+ }
+ }
+
+ rpcs.Reset();
+
+ if (!rpcs_tbl.rpcs.is_initialized()) {
+ rpcs_tbl.rpcs.set_to_null();
+ }
+
+ // Collecting entities for disallowed_by_external_consent_entities_on/off
+ external_consent_entities.Bind(0, group_id);
+ while (external_consent_entities.Next()) {
+ policy_table::ExternalConsentEntity external_consent_entity(
+ external_consent_entities.GetInteger(0),
+ external_consent_entities.GetInteger(1));
+
+ policy_table::DisallowedByExternalConsentEntities&
+ external_consent_entities_container =
+ kExternalConsentEntitiesTypeStringOn ==
+ external_consent_entities.GetString(2)
+ ? *rpcs_tbl.disallowed_by_external_consent_entities_on
+ : *rpcs_tbl.disallowed_by_external_consent_entities_off;
+
+ external_consent_entities_container.push_back(external_consent_entity);
+ }
+ external_consent_entities.Reset();
+ (*groups)[func_group.GetString(1)] = rpcs_tbl;
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::GatherConsumerFriendlyMessages(
+ policy_table::ConsumerFriendlyMessages* messages) const {
+ LOG4CXX_INFO(logger_, "Gather Consumer Friendly Messages");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectUserMsgsVersion) || !query.Next()) {
+ LOG4CXX_WARN(logger_, "Incorrect select from consumer_friendly_messages");
+ return false;
+ }
+
+ messages->version = query.GetString(0);
+
+ if (query.Prepare(sql_pt::kCollectFriendlyMsg)) {
+ while (query.Next()) {
+ UserFriendlyMessage msg;
+ msg.message_code = query.GetString(7);
+ std::string language = query.GetString(6);
+
+ (*messages->messages)[msg.message_code].languages[language];
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "Incorrect statement for select friendly messages.");
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::GatherApplicationPoliciesSection(
+ policy_table::ApplicationPoliciesSection* policies) const {
+ LOG4CXX_INFO(logger_, "Gather applications policies");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectAppPolicies)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app_policies");
+ return false;
+ }
+
+ while (query.Next()) {
+ rpc::Nullable<policy_table::ApplicationParams> params;
+ const std::string& app_id = query.GetString(0);
+ if (IsApplicationRevoked(app_id)) {
+ params.set_to_null();
+ (*policies).apps[app_id] = params;
+ continue;
+ }
+ if (IsDefaultPolicy(app_id)) {
+ (*policies).apps[app_id].set_to_string(kDefaultId);
+ }
+ if (IsPredataPolicy(app_id)) {
+ (*policies).apps[app_id].set_to_string(kPreDataConsentId);
+ }
+ if (kDeviceId == app_id) {
+ // Priority is only SDL-specific item for device
+ policy_table::Priority priority;
+ policy_table::EnumFromJsonString(query.GetString(1), &priority);
+ (*policies).device.priority = priority;
+ continue;
+ }
+ policy_table::Priority priority;
+ policy_table::EnumFromJsonString(query.GetString(1), &priority);
+ params.priority = priority;
+
+ *params.memory_kb = query.GetInteger(2);
+ *params.heart_beat_timeout_ms = query.GetUInteger(3);
+
+ if (!GatherAppGroup(app_id, &params.groups)) {
+ return false;
+ }
+ if (!GatherNickName(app_id, &*params.nicknames)) {
+ return false;
+ }
+ if (!GatherAppType(app_id, &*params.AppHMIType)) {
+ return false;
+ }
+ if (!GatherRequestType(app_id, &*params.RequestType)) {
+ return false;
+ }
+
+ (*policies).apps[app_id] = params;
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::Save(const policy_table::Table& table) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ db_->BeginTransaction();
+ if (!SaveFunctionalGroupings(table.policy_table.functional_groupings)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ if (!SaveApplicationPoliciesSection(
+ table.policy_table.app_policies_section)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ if (!SaveModuleConfig(table.policy_table.module_config)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ if (!SaveConsumerFriendlyMessages(
+ *table.policy_table.consumer_friendly_messages)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+
+ if (!SaveDeviceData(*table.policy_table.device_data)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ if (!SaveUsageAndErrorCounts(*table.policy_table.usage_and_error_counts)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ if (!SaveModuleMeta(*table.policy_table.module_meta)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ db_->CommitTransaction();
+ return true;
+}
+
+bool SQLPTRepresentation::SaveFunctionalGroupings(
+ const policy_table::FunctionalGroupings& groups) {
+ utils::dbms::SQLQuery query_delete(db());
+ if (!query_delete.Exec(sql_pt::kDeleteRpc)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from rpc.");
+ return false;
+ }
+
+ if (!query_delete.Exec(sql_pt::kDeleteExternalConsentEntities)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from external consent entities.");
+ return false;
+ }
+
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteFunctionalGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from seconds between retries.");
+ return false;
+ }
+
+ if (!query.Prepare(sql_pt::kInsertFunctionalGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for functional groups");
+ return false;
+ }
+
+ policy_table::FunctionalGroupings::const_iterator groups_it;
+
+ for (groups_it = groups.begin(); groups_it != groups.end(); ++groups_it) {
+ // Since we uses this id in other tables, we have to be sure
+ // that id for certain group will be same in case when
+ // we drop records from the table and add them again.
+ // That's why we use hash as a primary key insted of
+ // simple auto incremental index.
+ const long int id = abs(utils::Djb2HashFromString(groups_it->first));
+ // SQLite's Bind doesn support 'long' type
+ // So we need to explicitly cast it to int64_t
+ // to avoid ambiguity.
+ query.Bind(0, static_cast<int64_t>(id));
+ query.Bind(1, groups_it->first);
+ groups_it->second.user_consent_prompt.is_initialized()
+ ? query.Bind(2, *(groups_it->second.user_consent_prompt))
+ : query.Bind(2);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into functional groups");
+ return false;
+ }
+
+ const int64_t last_group_id = query.LastInsertId();
+
+ if (!SaveRpcs(last_group_id, groups_it->second.rpcs)) {
+ return false;
+ }
+
+ if (!SaveExternalConsentEntities(
+ last_group_id,
+ *groups_it->second.disallowed_by_external_consent_entities_on,
+ kExternalConsentEntitiesTypeOn)) {
+ return false;
+ }
+
+ if (!SaveExternalConsentEntities(
+ last_group_id,
+ *groups_it->second.disallowed_by_external_consent_entities_off,
+ kExternalConsentEntitiesTypeOff)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveRpcs(int64_t group_id,
+ const policy_table::Rpc& rpcs) {
+ utils::dbms::SQLQuery query(db());
+ utils::dbms::SQLQuery query_parameter(db());
+ if (!query.Prepare(sql_pt::kInsertRpc) ||
+ !query_parameter.Prepare(sql_pt::kInsertRpcWithParameter)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for rpc");
+ return false;
+ }
+
+ policy_table::Rpc::const_iterator it;
+ for (it = rpcs.begin(); it != rpcs.end(); ++it) {
+ const policy_table::HmiLevels& hmi_levels = it->second.hmi_levels;
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ const policy_table::Parameters& parameters = *it->second.parameters;
+ policy_table::HmiLevels::const_iterator hmi_it;
+ policy_table::Parameters::const_iterator ps_it;
+ for (hmi_it = hmi_levels.begin(); hmi_it != hmi_levels.end(); ++hmi_it) {
+ if (!parameters.empty()) {
+ for (ps_it = parameters.begin(); ps_it != parameters.end(); ++ps_it) {
+ query_parameter.Bind(0, it->first);
+ query_parameter.Bind(
+ 1, std::string(policy_table::EnumToJsonString(*hmi_it)));
+ query_parameter.Bind(
+ 2, std::string(policy_table::EnumToJsonString(*ps_it)));
+ query_parameter.Bind(3, group_id);
+ if (!query_parameter.Exec() || !query_parameter.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into rpc with parameter");
+ return false;
+ }
+ }
+ } else if (parameters.is_initialized()) {
+ query_parameter.Bind(0, it->first);
+ query_parameter.Bind(
+ 1, std::string(policy_table::EnumToJsonString(*hmi_it)));
+ query_parameter.Bind(
+ 2,
+ std::string(policy_table::EnumToJsonString(policy_table::P_EMPTY)));
+ query_parameter.Bind(3, group_id);
+ if (!query_parameter.Exec() || !query_parameter.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into rpc with parameter");
+ return false;
+ }
+ } else {
+ query.Bind(0, it->first);
+ query.Bind(1, std::string(policy_table::EnumToJsonString(*hmi_it)));
+ query.Bind(2, group_id);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into rpc");
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveApplicationPoliciesSection(
+ const policy_table::ApplicationPoliciesSection& policies) {
+ utils::dbms::SQLQuery query_delete(db());
+ if (!query_delete.Exec(sql_pt::kDeleteAppGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from app_group.");
+ return false;
+ }
+ if (!query_delete.Exec(sql_pt::kDeleteApplication)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from application.");
+ return false;
+ }
+
+ if (!query_delete.Exec(sql_pt::kDeleteRequestType)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from request type.");
+ return false;
+ }
+
+ // All predefined apps (e.g. default, pre_DataConsent) should be saved first,
+ // otherwise another app with the predefined permissions can get incorrect
+ // permissions
+ policy_table::ApplicationPolicies::const_iterator it_default =
+ policies.apps.find(kDefaultId);
+ if (policies.apps.end() != it_default) {
+ if (!SaveSpecificAppPolicy(*it_default)) {
+ return false;
+ }
+ }
+ policy_table::ApplicationPolicies::const_iterator it_pre_data_consented =
+ policies.apps.find(kPreDataConsentId);
+ if (policies.apps.end() != it_pre_data_consented) {
+ if (!SaveSpecificAppPolicy(*it_pre_data_consented)) {
+ return false;
+ }
+ }
+
+ if (!SaveDevicePolicy(policies.device)) {
+ return false;
+ }
+
+ policy_table::ApplicationPolicies::const_iterator it;
+ for (it = policies.apps.begin(); it != policies.apps.end(); ++it) {
+ // Skip saving of predefined app, since they should be saved before
+ if (IsPredefinedApp(*it)) {
+ continue;
+ }
+ if (!SaveSpecificAppPolicy(*it)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveSpecificAppPolicy(
+ const policy_table::ApplicationPolicies::value_type& app) {
+ utils::dbms::SQLQuery app_query(db());
+ if (!app_query.Prepare(sql_pt::kInsertApplication)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement into application (device).");
+ return false;
+ }
+
+ app_query.Bind(0, app.first);
+ app_query.Bind(
+ 1, std::string(policy_table::EnumToJsonString(app.second.priority)));
+ app_query.Bind(2, app.second.is_null());
+ app_query.Bind(3, *app.second.memory_kb);
+ app_query.Bind(4, static_cast<int64_t>(*app.second.heart_beat_timeout_ms));
+
+ if (!app_query.Exec() || !app_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into application.");
+ return false;
+ }
+
+ if (app.second.is_string()) {
+ if (kDefaultId.compare(app.second.get_string()) == 0) {
+ if (!SetDefaultPolicy(app.first)) {
+ return false;
+ }
+ // Stop saving other params, since predefined permissions already set
+ return true;
+ }
+ }
+
+ if (!SaveAppGroup(app.first, app.second.groups)) {
+ return false;
+ }
+ if (!SaveNickname(app.first, *app.second.nicknames)) {
+ return false;
+ }
+ if (!SaveAppType(app.first, *app.second.AppHMIType)) {
+ return false;
+ }
+
+ if (!SaveRequestType(app.first, *app.second.RequestType)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool policy::SQLPTRepresentation::SaveDevicePolicy(
+ const policy_table::DevicePolicy& device) {
+ utils::dbms::SQLQuery app_query(db());
+ if (!app_query.Prepare(sql_pt::kInsertApplication)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement into application.");
+ return false;
+ }
+
+ app_query.Bind(0, kDeviceId);
+ app_query.Bind(1,
+ std::string(policy_table::EnumToJsonString(device.priority)));
+ app_query.Bind(2, false);
+ app_query.Bind(3, 0);
+ app_query.Bind(4, 0);
+ app_query.Bind(5);
+
+ if (!app_query.Exec() || !app_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into application.");
+ return false;
+ }
+
+ if (!SaveAppGroup(kDeviceId, device.groups)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveAppGroup(
+ const std::string& app_id, const policy_table::Strings& app_groups) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertAppGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for app group");
+ return false;
+ }
+ LOG4CXX_INFO(logger_, "SaveAppGroup");
+ policy_table::Strings::const_iterator it;
+ for (it = app_groups.begin(); it != app_groups.end(); ++it) {
+ std::string ssss = *it;
+ LOG4CXX_INFO(logger_, "Group: " << ssss);
+ query.Bind(0, app_id);
+ query.Bind(1, *it);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert into app group."
+ << query.LastError().text());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveNickname(const std::string& app_id,
+ const policy_table::Strings& nicknames) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertNickname)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for nickname");
+ return false;
+ }
+
+ policy_table::Strings::const_iterator it;
+ for (it = nicknames.begin(); it != nicknames.end(); ++it) {
+ query.Bind(0, app_id);
+ query.Bind(1, *it);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into nickname.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveAppType(const std::string& app_id,
+ const policy_table::AppHMITypes& types) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertAppType)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for app type");
+ return false;
+ }
+
+ policy_table::AppHMITypes::const_iterator it;
+ for (it = types.begin(); it != types.end(); ++it) {
+ query.Bind(0, app_id);
+ query.Bind(1, std::string(policy_table::EnumToJsonString(*it)));
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into app type.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveRequestType(
+ const std::string& app_id, const policy_table::RequestTypes& types) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertRequestType)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for request types.");
+ return false;
+ }
+
+ policy_table::RequestTypes::const_iterator it;
+ for (it = types.begin(); it != types.end(); ++it) {
+ query.Bind(0, app_id);
+ query.Bind(1, std::string(policy_table::EnumToJsonString(*it)));
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into request types.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveModuleMeta(const policy_table::ModuleMeta& meta) {
+ // Section Module Meta is empty for SDL specific
+ return true;
+}
+
+bool SQLPTRepresentation::SaveModuleConfig(
+ const policy_table::ModuleConfig& config) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kUpdateModuleConfig)) {
+ LOG4CXX_WARN(logger_, "Incorrect update statement for module config");
+ return false;
+ }
+
+ bool is_preloaded =
+ config.preloaded_pt.is_initialized() && *config.preloaded_pt;
+
+ query.Bind(0, is_preloaded);
+ query.Bind(1, config.exchange_after_x_ignition_cycles);
+ query.Bind(2, config.exchange_after_x_kilometers);
+ query.Bind(3, config.exchange_after_x_days);
+ query.Bind(4, config.timeout_after_x_seconds);
+ config.vehicle_make.is_initialized() ? query.Bind(5, *(config.vehicle_make))
+ : query.Bind(5);
+ config.vehicle_model.is_initialized() ? query.Bind(6, *(config.vehicle_model))
+ : query.Bind(6);
+ config.vehicle_year.is_initialized() ? query.Bind(7, *(config.vehicle_year))
+ : query.Bind(7);
+ config.preloaded_date.is_initialized()
+ ? query.Bind(8, *(config.preloaded_date))
+ : query.Bind(8);
+ config.certificate.is_initialized() ? query.Bind(9, *(config.certificate))
+ : query.Bind(9);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect update module config");
+ return false;
+ }
+
+ if (!SaveSecondsBetweenRetries(config.seconds_between_retries)) {
+ return false;
+ }
+
+ if (!SaveNumberOfNotificationsPerMinute(
+ config.notifications_per_minute_by_priority)) {
+ return false;
+ }
+
+ if (!SaveServiceEndpoints(config.endpoints)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveServiceEndpoints(
+ const policy_table::ServiceEndpoints& endpoints) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteEndpoint)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from endpoint.");
+ return false;
+ }
+
+ if (!query.Prepare(sql_pt::kInsertEndpoint)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for endpoint");
+ return false;
+ }
+
+ policy_table::ServiceEndpoints::const_iterator it;
+ for (it = endpoints.begin(); it != endpoints.end(); ++it) {
+ const policy_table::URLList& apps = it->second;
+ policy_table::URLList::const_iterator app_it;
+ for (app_it = apps.begin(); app_it != apps.end(); ++app_it) {
+ const policy_table::URL& urls = app_it->second;
+ policy_table::URL::const_iterator url_it;
+ for (url_it = urls.begin(); url_it != urls.end(); ++url_it) {
+ std::stringstream temp_stream(it->first);
+ int service;
+ temp_stream.seekg(3);
+ temp_stream >> service;
+ query.Bind(0, service);
+ query.Bind(1, *url_it);
+ query.Bind(2, app_it->first);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into endpoint");
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveConsumerFriendlyMessages(
+ const policy_table::ConsumerFriendlyMessages& messages) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ // According CRS-2419 If there is no “consumer_friendly_messages” key,
+ // the current local consumer_friendly_messages section shall be maintained in
+ // the policy table. So it won't be changed/updated
+ if (messages.messages.is_initialized()) {
+ utils::dbms::SQLQuery query(db());
+ if (!messages.messages->empty()) {
+ if (!query.Exec(sql_pt::kDeleteMessageString)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from message.");
+ return false;
+ }
+ }
+
+ if (query.Prepare(sql_pt::kUpdateVersion)) {
+ query.Bind(0, messages.version);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect update into version.");
+ return false;
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "Incorrect update statement for version.");
+ return false;
+ }
+
+ policy_table::Messages::const_iterator it;
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ for (it = messages.messages->begin(); it != messages.messages->end();
+ ++it) {
+ if (!SaveMessageType(it->first)) {
+ return false;
+ }
+ const policy_table::Languages& langs = it->second.languages;
+ policy_table::Languages::const_iterator lang_it;
+ for (lang_it = langs.begin(); lang_it != langs.end(); ++lang_it) {
+ if (!SaveLanguage(lang_it->first)) {
+ return false;
+ }
+ if (!SaveMessageString(it->first, lang_it->first, lang_it->second)) {
+ return false;
+ }
+ }
+ }
+ } else {
+ LOG4CXX_INFO(logger_, "Messages list is empty");
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveMessageType(const std::string& type) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertMessageType)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for message type.");
+ return false;
+ }
+
+ query.Bind(0, type);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into message type.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveLanguage(const std::string& code) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertLanguage)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for language.");
+ return false;
+ }
+
+ query.Bind(0, code);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into language.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveMessageString(
+ const std::string& type,
+ const std::string& lang,
+ const policy_table::MessageString& strings) {
+ // Section is empty for SDL specific
+ return true;
+}
+
+bool SQLPTRepresentation::SaveSecondsBetweenRetries(
+ const policy_table::SecondsBetweenRetries& seconds) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteSecondsBetweenRetries)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from seconds between retries.");
+ return false;
+ }
+ if (!query.Prepare(sql_pt::kInsertSecondsBetweenRetry)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement for seconds between retries.");
+ return false;
+ }
+
+ for (uint32_t i = 0; i < seconds.size(); ++i) {
+ query.Bind(0, static_cast<int>(i));
+ query.Bind(1, seconds[i]);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into seconds between retries.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveNumberOfNotificationsPerMinute(
+ const policy_table::NumberOfNotificationsPerMinute& notifications) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertNotificationsByPriority)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement for notifications by priority.");
+ return false;
+ }
+
+ policy_table::NumberOfNotificationsPerMinute::const_iterator it;
+ for (it = notifications.begin(); it != notifications.end(); ++it) {
+ query.Bind(0, it->first);
+ query.Bind(1, it->second);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into notifications by priority.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveDeviceData(
+ const policy_table::DeviceData& devices) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertDeviceData)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for device data.");
+ return false;
+ }
+
+ policy_table::DeviceData::const_iterator it;
+ for (it = devices.begin(); it != devices.end(); ++it) {
+ query.Bind(0, it->first);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into device data.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveUsageAndErrorCounts(
+ const policy_table::UsageAndErrorCounts& counts) {
+ const_cast<policy_table::UsageAndErrorCounts&>(counts).mark_initialized();
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteAppLevel)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from app level.");
+ return false;
+ }
+ if (!query.Prepare(sql_pt::kInsertAppLevel)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for app level.");
+ return false;
+ }
+
+ policy_table::AppLevels::const_iterator it;
+ const policy_table::AppLevels& app_levels = *counts.app_level;
+ const_cast<policy_table::AppLevels&>(*counts.app_level).mark_initialized();
+ for (it = app_levels.begin(); it != app_levels.end(); ++it) {
+ query.Bind(0, it->first);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into app level.");
+ return false;
+ }
+ }
+ return true;
+}
+
+void SQLPTRepresentation::IncrementIgnitionCycles() {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kIncrementIgnitionCycles)) {
+ LOG4CXX_WARN(logger_, "Failed incrementing ignition cycles");
+ }
+}
+
+void SQLPTRepresentation::ResetIgnitionCycles() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kResetIgnitionCycles)) {
+ LOG4CXX_WARN(logger_, "Failed to reset ignition cycles number.");
+ }
+}
+
+bool SQLPTRepresentation::UpdateRequired() const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectFlagUpdateRequired) || !query.Exec()) {
+ LOG4CXX_WARN(logger_,
+ "Failed select update required flag from module meta");
+ return false;
+ }
+ return query.GetBoolean(0);
+}
+
+void SQLPTRepresentation::SaveUpdateRequired(bool value) {
+ utils::dbms::SQLQuery query(db());
+ // TODO(AOleynik): Quick fix, will be reworked
+ if (!query.Prepare(/*sql_pt::kUpdateFlagUpdateRequired*/
+ "UPDATE `module_meta` SET `flag_update_required` = ?")) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect update into module meta (update_required): "
+ << strerror(errno));
+ return;
+ }
+ query.Bind(0, value);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed update module meta (update_required)");
+ }
+}
+
+bool SQLPTRepresentation::GetInitialAppData(const std::string& app_id,
+ StringArray* nicknames,
+ StringArray* app_types) {
+ LOG4CXX_INFO(logger_, "Getting initial application data.");
+ utils::dbms::SQLQuery app_names(db());
+ if (!app_names.Prepare(sql_pt::kSelectNicknames)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app nicknames");
+ return false;
+ }
+ utils::dbms::SQLQuery app_hmi_types(db());
+ if (!app_hmi_types.Prepare(sql_pt::kSelectAppTypes)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app types");
+ return false;
+ }
+ dbms::SQLQuery module_types(db());
+ if (!module_types.Prepare(sql_pt::kSelectModuleTypes)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from module types");
+ return false;
+ }
+
+ app_names.Bind(0, app_id);
+ while (app_names.Next()) {
+ nicknames->push_back(app_names.GetString(0));
+ }
+ app_names.Reset();
+ app_hmi_types.Bind(0, app_id);
+ while (app_hmi_types.Next()) {
+ app_types->push_back(app_hmi_types.GetString(0));
+ }
+ app_hmi_types.Reset();
+ module_types.Bind(0, app_id);
+ while (module_types.Next()) {
+ app_types->push_back(module_types.GetString(0));
+ }
+ module_types.Reset();
+
+ return true;
+}
+
+bool SQLPTRepresentation::GetFunctionalGroupings(
+ policy_table::FunctionalGroupings& groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return GatherFunctionalGroupings(&groups);
+}
+
+bool SQLPTRepresentation::GatherAppType(
+ const std::string& app_id, policy_table::AppHMITypes* app_types) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectAppTypes)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app types");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ while (query.Next()) {
+ policy_table::AppHMIType type;
+ if (!policy_table::EnumFromJsonString(query.GetString(0), &type)) {
+ return false;
+ }
+ app_types->push_back(type);
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::GatherRequestType(
+ const std::string& app_id,
+ policy_table::RequestTypes* request_types) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectRequestTypes)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from request types.");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ while (query.Next()) {
+ policy_table::RequestType type;
+ if (!policy_table::EnumFromJsonString(query.GetString(0), &type)) {
+ return false;
+ }
+ request_types->push_back(type);
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::GatherNickName(
+ const std::string& app_id, policy_table::Strings* nicknames) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectNicknames)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app nicknames");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ while (query.Next()) {
+ nicknames->push_back(query.GetString(0));
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::GatherAppGroup(
+ const std::string& app_id, policy_table::Strings* app_groups) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectAppGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app groups");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ while (query.Next()) {
+ app_groups->push_back(query.GetString(0));
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::SaveApplicationCustomData(const std::string& app_id,
+ bool is_revoked,
+ bool is_default,
+ bool is_predata) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kUpdateApplicationCustomData)) {
+ LOG4CXX_WARN(logger_, "Incorrect update in application");
+ return false;
+ }
+
+ query.Bind(0, is_revoked);
+ query.Bind(1, is_default);
+ query.Bind(2, is_predata);
+ query.Bind(3, app_id);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed update in application");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::IsApplicationRevoked(
+ const std::string& app_id) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectApplicationRevoked)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from is_revoked of application");
+ }
+
+ query.Bind(0, app_id);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed select is_revoked of application");
+ return false;
+ }
+ return query.IsNull(0) ? false : query.GetBoolean(0);
+}
+bool SQLPTRepresentation::IsApplicationRepresented(
+ const std::string& app_id) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectApplicationRepresented)) {
+ LOG4CXX_WARN(logger_, "Incorrect select application by id");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed select application by id");
+ return false;
+ }
+ return query.GetInteger(0) != 0;
+}
+
+bool SQLPTRepresentation::IsDefaultPolicy(const std::string& app_id) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectApplicationIsDefault)) {
+ LOG4CXX_WARN(logger_, "Incorrect select application by id");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed select application by id");
+ return false;
+ }
+ return query.IsNull(0) ? false : query.GetBoolean(0);
+}
+
+bool SQLPTRepresentation::IsPredataPolicy(const std::string& app_id) const {
+ return false;
+}
+
+bool SQLPTRepresentation::SetDefaultPolicy(const std::string& app_id) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kDeleteAppGroupByApplicationId)) {
+ LOG4CXX_ERROR(logger_, "Incorrect statement to delete from app_group.");
+ return false;
+ }
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_ERROR(logger_, "Failed deleting from app_group.");
+ return false;
+ }
+
+ if (!CopyApplication(kDefaultId, app_id)) {
+ return false;
+ }
+
+ SetPreloaded(false);
+
+ policy_table::RequestTypes request_types;
+ if (!GatherRequestType(kDefaultId, &request_types) ||
+ !SaveRequestType(app_id, request_types)) {
+ return false;
+ }
+ policy_table::AppHMITypes app_types;
+ if (!GatherAppType(kDefaultId, &app_types) ||
+ !SaveAppType(app_id, app_types)) {
+ return false;
+ }
+
+ policy_table::Strings default_groups;
+ if (GatherAppGroup(kDefaultId, &default_groups) &&
+ SaveAppGroup(app_id, default_groups)) {
+ return SetIsDefault(app_id, true);
+ }
+ return false;
+}
+
+bool SQLPTRepresentation::SetIsDefault(const std::string& app_id,
+ bool is_default) const {
+ LOG4CXX_TRACE(logger_, "Set flag is_default of application");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kUpdateIsDefault)) {
+ LOG4CXX_WARN(logger_, "Incorect statement for updating is_default");
+ return false;
+ }
+
+ query.Bind(0, is_default);
+ query.Bind(1, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed update is_default");
+ return false;
+ }
+ return true;
+}
+
+void SQLPTRepresentation::RemoveDB() const {
+ file_system::DeleteFile(db_->get_path());
+}
+
+bool SQLPTRepresentation::IsDBVersionActual() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectDBVersion) || !query.Exec()) {
+ LOG4CXX_ERROR(logger_,
+ "Failed to get DB version: " << query.LastError().text());
+ return false;
+ }
+
+ const int32_t saved_db_version = query.GetInteger(0);
+ const int32_t current_db_version = GetDBVersion();
+ LOG4CXX_DEBUG(logger_,
+ "Saved DB version is: " << saved_db_version
+ << ". Current DB vesion is: "
+ << current_db_version);
+
+ return current_db_version == saved_db_version;
+}
+
+bool SQLPTRepresentation::UpdateDBVersion() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kUpdateDBVersion)) {
+ LOG4CXX_ERROR(logger_,
+ "Incorrect DB version query: " << query.LastError().text());
+ return false;
+ }
+
+ const int32_t db_version = GetDBVersion();
+ LOG4CXX_DEBUG(logger_, "DB version will be updated to: " << db_version);
+ query.Bind(0, db_version);
+
+ if (!query.Exec()) {
+ LOG4CXX_ERROR(logger_,
+ "DB version getting failed: " << query.LastError().text());
+ return false;
+ }
+
+ return true;
+}
+
+const int32_t SQLPTRepresentation::GetDBVersion() const {
+ return utils::Djb2HashFromString(sql_pt::kCreateSchema);
+}
+
+utils::dbms::SQLDatabase* SQLPTRepresentation::db() const {
+#ifdef __QNX__
+ utils::dbms::SQLDatabase* db = new utils::dbms::SQLDatabase(kDatabaseName);
+ db->Open();
+ return db;
+#else
+ return db_;
+#endif // __QNX__
+}
+
+bool SQLPTRepresentation::CopyApplication(const std::string& source,
+ const std::string& destination) {
+ utils::dbms::SQLQuery source_app(db());
+ if (!source_app.Prepare(sql_pt::kSelectApplicationFull)) {
+ LOG4CXX_WARN(logger_, "Incorrect select statement from application.");
+ return false;
+ }
+ source_app.Bind(0, source);
+ if (!source_app.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed selecting from application.");
+ return false;
+ }
+
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertApplicationFull)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement into application.");
+ return false;
+ }
+ query.Bind(0, destination);
+ source_app.IsNull(0) ? query.Bind(1)
+ : query.Bind(1, source_app.GetBoolean(0));
+ source_app.IsNull(1) ? query.Bind(2)
+ : query.Bind(2, source_app.GetBoolean(1));
+ source_app.IsNull(2) ? query.Bind(3) : query.Bind(3, source_app.GetString(2));
+ source_app.IsNull(3) ? query.Bind(4) : query.Bind(4, source_app.GetString(3));
+ source_app.IsNull(4) ? query.Bind(5)
+ : query.Bind(5, source_app.GetBoolean(4));
+ source_app.IsNull(5) ? query.Bind(6)
+ : query.Bind(6, source_app.GetBoolean(5));
+ source_app.IsNull(6) ? query.Bind(7)
+ : query.Bind(7, source_app.GetBoolean(6));
+ query.Bind(8, source_app.GetInteger(7));
+ query.Bind(9, source_app.GetInteger(8));
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed inserting into application.");
+ return false;
+ }
+ return true;
+}
+
+void SQLPTRepresentation::SetPreloaded(bool value) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kUpdatePreloaded)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement of updating preloaded.");
+ return;
+ }
+
+ query.Bind(0, value);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed updating preloaded.");
+ return;
+ }
+}
+
+bool SQLPTRepresentation::SetVINValue(const std::string& value) {
+ return true;
+}
+
+bool SQLPTRepresentation::SaveExternalConsentEntities(
+ const int64_t group_id,
+ const policy_table::DisallowedByExternalConsentEntities& entities,
+ ExternalConsentEntitiesType type) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kInsertExternalConsentEntity)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement for external consent entities.");
+ return false;
+ }
+
+ const std::string external_consent_entity_type =
+ kExternalConsentEntitiesTypeOn == type
+ ? kExternalConsentEntitiesTypeStringOn
+ : kExternalConsentEntitiesTypeStringOff;
+
+ policy_table::DisallowedByExternalConsentEntities::const_iterator it_entity =
+ entities.begin();
+ for (; entities.end() != it_entity; ++it_entity) {
+ query.Bind(0, group_id);
+ query.Bind(1, it_entity->entity_type);
+ query.Bind(2, it_entity->entity_id);
+ query.Bind(3, external_consent_entity_type);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_ERROR(logger_,
+ "Can't insert '" << external_consent_entity_type
+ << "' external consent entity.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace policy
diff --git a/src/components/policy/policy_external/src/status.cc b/src/components/policy/policy_external/src/status.cc
new file mode 100644
index 0000000000..31fc7f110b
--- /dev/null
+++ b/src/components/policy/policy_external/src/status.cc
@@ -0,0 +1,139 @@
+/*
+ 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 "policy/status.h"
+#include "policy/update_status_manager.h"
+#include "utils/make_shared.h"
+
+policy::UpToDateStatus::UpToDateStatus()
+ : Status(kUpToDate, policy::PolicyTableStatus::StatusUpToDate) {}
+
+void policy::UpToDateStatus::ProcessEvent(UpdateStatusManager* manager,
+ policy::UpdateEvent event) {
+ switch (event) {
+ case kOnNewAppRegistered:
+ case kOnResetPolicyTableRequireUpdate:
+ case kScheduleUpdate:
+ case kScheduleManualUpdate:
+ case kOnResetRetrySequence:
+ manager->SetNextStatus(utils::MakeShared<UpdateNeededStatus>());
+ break;
+ default:
+ break;
+ }
+}
+
+policy::UpdateNeededStatus::UpdateNeededStatus()
+ : Status(kUpdateNeeded, policy::PolicyTableStatus::StatusUpdateRequired) {}
+
+void policy::UpdateNeededStatus::ProcessEvent(
+ policy::UpdateStatusManager* manager, policy::UpdateEvent event) {
+ switch (event) {
+ case kOnUpdateSentOut:
+ manager->SetNextStatus(utils::MakeShared<UpdatingStatus>());
+ break;
+ case kOnResetPolicyTableRequireUpdate:
+ manager->SetNextStatus(utils::MakeShared<UpToDateStatus>());
+ manager->SetPostponedStatus(utils::MakeShared<UpdateNeededStatus>());
+ break;
+ case kOnResetPolicyTableNoUpdate:
+ manager->SetNextStatus(utils::MakeShared<UpToDateStatus>());
+ break;
+ default:
+ break;
+ }
+}
+
+bool policy::UpdateNeededStatus::IsUpdateRequired() const {
+ return true;
+}
+
+policy::UpdatingStatus::UpdatingStatus()
+ : Status(kUpdating, policy::PolicyTableStatus::StatusUpdatePending) {}
+
+void policy::UpdatingStatus::ProcessEvent(policy::UpdateStatusManager* manager,
+ policy::UpdateEvent event) {
+ switch (event) {
+ case kOnValidUpdateReceived:
+ case kOnResetPolicyTableNoUpdate:
+ manager->SetNextStatus(utils::MakeShared<UpToDateStatus>());
+ break;
+ case kOnNewAppRegistered:
+ manager->SetPostponedStatus(utils::MakeShared<UpdateNeededStatus>());
+ break;
+ case kOnWrongUpdateReceived:
+ case kOnUpdateTimeout:
+ manager->SetNextStatus(utils::MakeShared<UpdateNeededStatus>());
+ break;
+ case kOnResetPolicyTableRequireUpdate:
+ manager->SetNextStatus(utils::MakeShared<UpToDateStatus>());
+ manager->SetPostponedStatus(utils::MakeShared<UpdateNeededStatus>());
+ break;
+ case kScheduleUpdate:
+ case kScheduleManualUpdate:
+ case kOnResetRetrySequence:
+ manager->SetPostponedStatus(utils::MakeShared<UpdateNeededStatus>());
+ break;
+ default:
+ break;
+ }
+}
+
+bool policy::UpdatingStatus::IsUpdatePending() const {
+ return true;
+}
+
+bool policy::UpdatingStatus::IsUpdateRequired() const {
+ return true;
+}
+
+policy::Status::Status(const std::string& string_status,
+ const policy::PolicyTableStatus enum_status)
+ : string_status_(string_status), enum_status_(enum_status) {}
+
+policy::Status::~Status() {}
+
+const std::string policy::Status::get_status_string() const {
+ return string_status_;
+}
+
+policy::PolicyTableStatus policy::Status::get_status() const {
+ return enum_status_;
+}
+
+bool policy::Status::IsUpdateRequired() const {
+ return false;
+}
+
+bool policy::Status::IsUpdatePending() const {
+ return false;
+}
diff --git a/src/components/policy/policy_external/src/update_status_manager.cc b/src/components/policy/policy_external/src/update_status_manager.cc
new file mode 100644
index 0000000000..087db1149b
--- /dev/null
+++ b/src/components/policy/policy_external/src/update_status_manager.cc
@@ -0,0 +1,262 @@
+/*
+ Copyright (c) 2014, 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 "policy/update_status_manager.h"
+#include "policy/policy_listener.h"
+#include "utils/logger.h"
+#include "utils/make_shared.h"
+
+namespace policy {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Policy")
+
+UpdateStatusManager::UpdateStatusManager()
+ : listener_(NULL)
+ , current_status_(utils::MakeShared<UpToDateStatus>())
+ , last_processed_event_(kNoEvent)
+ , apps_search_in_progress_(false)
+ , app_registered_from_non_consented_device_(true) {
+ update_status_thread_delegate_ = new UpdateThreadDelegate(this);
+ thread_ = threads::CreateThread("UpdateStatusThread",
+ update_status_thread_delegate_);
+ thread_->start();
+}
+
+UpdateStatusManager::~UpdateStatusManager() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ DCHECK(update_status_thread_delegate_);
+ DCHECK(thread_);
+ thread_->join();
+ delete update_status_thread_delegate_;
+ threads::DeleteThread(thread_);
+}
+
+void UpdateStatusManager::ProcessEvent(UpdateEvent event) {
+ sync_primitives::AutoLock lock(status_lock_);
+ current_status_->ProcessEvent(this, event);
+ last_processed_event_ = event;
+ DoTransition();
+}
+
+void UpdateStatusManager::SetNextStatus(utils::SharedPtr<Status> status) {
+ next_status_ = status;
+}
+
+void UpdateStatusManager::SetPostponedStatus(utils::SharedPtr<Status> status) {
+ postponed_status_ = status;
+}
+
+void UpdateStatusManager::set_listener(PolicyListener* listener) {
+ listener_ = listener;
+}
+
+void UpdateStatusManager::OnUpdateSentOut(uint32_t update_timeout) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ DCHECK(update_status_thread_delegate_);
+ update_status_thread_delegate_->updateTimeOut(update_timeout);
+ ProcessEvent(kOnUpdateSentOut);
+}
+
+void UpdateStatusManager::OnUpdateTimeoutOccurs() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ ProcessEvent(kOnUpdateTimeout);
+ DCHECK(update_status_thread_delegate_);
+ update_status_thread_delegate_->updateTimeOut(0); // Stop Timer
+}
+
+void UpdateStatusManager::OnValidUpdateReceived() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ update_status_thread_delegate_->updateTimeOut(0); // Stop Timer
+ ProcessEvent(kOnValidUpdateReceived);
+}
+
+void UpdateStatusManager::OnWrongUpdateReceived() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ update_status_thread_delegate_->updateTimeOut(0); // Stop Timer
+ ProcessEvent(kOnWrongUpdateReceived);
+}
+
+void UpdateStatusManager::OnResetDefaultPT(bool is_update_required) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (is_update_required) {
+ ProcessEvent(kOnResetPolicyTableRequireUpdate);
+ return;
+ }
+ ProcessEvent(kOnResetPolicyTableNoUpdate);
+}
+
+void UpdateStatusManager::OnResetRetrySequence() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ ProcessEvent(kOnResetRetrySequence);
+}
+
+void UpdateStatusManager::OnNewApplicationAdded(const DeviceConsent consent) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (kDeviceAllowed != consent) {
+ app_registered_from_non_consented_device_ = true;
+ return;
+ }
+ app_registered_from_non_consented_device_ = false;
+ ProcessEvent(kOnNewAppRegistered);
+}
+
+void UpdateStatusManager::OnPolicyInit(bool is_update_required) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (is_update_required) {
+ current_status_.reset(new UpToDateStatus());
+ ProcessEvent(kScheduleUpdate);
+ }
+}
+
+void UpdateStatusManager::OnDeviceConsented() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (app_registered_from_non_consented_device_) {
+ ProcessEvent(kOnNewAppRegistered);
+ }
+}
+
+bool UpdateStatusManager::IsUpdateRequired() const {
+ return current_status_->IsUpdateRequired();
+}
+
+bool UpdateStatusManager::IsUpdatePending() const {
+ return current_status_->IsUpdatePending();
+}
+
+void UpdateStatusManager::ScheduleUpdate() {
+ ProcessEvent(kScheduleUpdate);
+}
+
+void UpdateStatusManager::ScheduleManualUpdate() {
+ ProcessEvent(kScheduleManualUpdate);
+}
+
+std::string UpdateStatusManager::StringifiedUpdateStatus() const {
+ return current_status_->get_status_string();
+}
+
+void policy::UpdateStatusManager::OnAppsSearchStarted() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(apps_search_in_progress_lock_);
+ apps_search_in_progress_ = true;
+}
+
+void policy::UpdateStatusManager::OnAppsSearchCompleted() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(apps_search_in_progress_lock_);
+ apps_search_in_progress_ = false;
+}
+
+bool policy::UpdateStatusManager::IsAppsSearchInProgress() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(apps_search_in_progress_lock_);
+ return apps_search_in_progress_;
+}
+
+void UpdateStatusManager::DoTransition() {
+ DCHECK_OR_RETURN_VOID(listener_);
+ if (!next_status_) {
+ return;
+ }
+
+ current_status_ = next_status_;
+ next_status_.reset();
+
+ if (last_processed_event_ != kScheduleManualUpdate) {
+ listener_->OnUpdateStatusChanged(current_status_->get_status_string());
+ }
+
+ if (!postponed_status_) {
+ return;
+ }
+
+ current_status_ = postponed_status_;
+ if (last_processed_event_ != kScheduleManualUpdate) {
+ listener_->OnUpdateStatusChanged(current_status_->get_status_string());
+ }
+ postponed_status_.reset();
+}
+
+UpdateStatusManager::UpdateThreadDelegate::UpdateThreadDelegate(
+ UpdateStatusManager* update_status_manager)
+ : timeout_(0)
+ , stop_flag_(false)
+ , state_lock_(true)
+ , update_status_manager_(update_status_manager) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Create UpdateThreadDelegate");
+}
+
+UpdateStatusManager::UpdateThreadDelegate::~UpdateThreadDelegate() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Delete UpdateThreadDelegate");
+}
+
+void UpdateStatusManager::UpdateThreadDelegate::threadMain() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "UpdateStatusManager thread started (started normal)");
+ sync_primitives::AutoLock auto_lock(state_lock_);
+ while (false == stop_flag_) {
+ if (timeout_ > 0) {
+ LOG4CXX_DEBUG(logger_, "Timeout is greater then 0");
+ sync_primitives::ConditionalVariable::WaitStatus wait_status =
+ termination_condition_.WaitFor(auto_lock, timeout_);
+ if (sync_primitives::ConditionalVariable::kTimeout == wait_status) {
+ if (update_status_manager_) {
+ update_status_manager_->OnUpdateTimeoutOccurs();
+ }
+ }
+ } else {
+ // Time is not active, wait until timeout will be set,
+ // or UpdateStatusManager will be deleted
+ termination_condition_.Wait(auto_lock);
+ }
+ }
+}
+
+void UpdateStatusManager::UpdateThreadDelegate::exitThreadMain() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(state_lock_);
+ stop_flag_ = true;
+ LOG4CXX_DEBUG(logger_, "before notify");
+ termination_condition_.NotifyOne();
+}
+
+void UpdateStatusManager::UpdateThreadDelegate::updateTimeOut(
+ const uint32_t timeout_ms) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(state_lock_);
+ timeout_ = timeout_ms;
+ termination_condition_.NotifyOne();
+}
+
+} // namespace policy
diff --git a/src/components/policy/policy_external/src/usage_statistics/counter.cc b/src/components/policy/policy_external/src/usage_statistics/counter.cc
new file mode 100644
index 0000000000..661ea29704
--- /dev/null
+++ b/src/components/policy/policy_external/src/usage_statistics/counter.cc
@@ -0,0 +1,126 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_STATISTICS_MANAGER_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_STATISTICS_MANAGER_H_
+
+#include <cassert>
+#include "policy/usage_statistics/counter.h"
+#include "utils/date_time.h"
+#include "utils/make_shared.h"
+#include "utils/timer_task_impl.h"
+
+namespace usage_statistics {
+
+GlobalCounter::GlobalCounter(
+ utils::SharedPtr<usage_statistics::StatisticsManager> statistics_manager,
+ GlobalCounterId counter_type)
+ : counter_type_(counter_type), statistics_manager_(statistics_manager) {}
+
+void GlobalCounter::operator++() const {
+ if (statistics_manager_) {
+ statistics_manager_->Increment(counter_type_);
+ }
+}
+
+AppCounter::AppCounter(
+ utils::SharedPtr<usage_statistics::StatisticsManager> statistics_manager,
+ const std::string& app_id,
+ AppCounterId counter_type)
+ : app_id_(app_id)
+ , counter_type_(counter_type)
+ , statistics_manager_(statistics_manager) {}
+
+void AppCounter::operator++() const {
+ if (statistics_manager_) {
+ statistics_manager_->Increment(app_id_, counter_type_);
+ }
+}
+
+AppInfo::AppInfo(
+ utils::SharedPtr<usage_statistics::StatisticsManager> statistics_manager,
+ const std::string& app_id,
+ AppInfoId info_type)
+ : app_id_(app_id)
+ , info_type_(info_type)
+ , statistics_manager_(statistics_manager) {}
+
+void AppInfo::Update(const std::string& new_info) const {
+ if (statistics_manager_) {
+ statistics_manager_->Set(app_id_, info_type_, new_info);
+ }
+}
+
+AppStopwatchImpl::AppStopwatchImpl(
+ utils::SharedPtr<usage_statistics::StatisticsManager> statistics_manager,
+ const std::string& app_id)
+ : app_id_(app_id)
+ , stopwatch_type_(SECONDS_HMI_NONE)
+ , statistics_manager_(statistics_manager)
+ , timer_("HMI levels timer",
+ new timer::TimerTaskImpl<AppStopwatchImpl>(
+ this, &AppStopwatchImpl::WriteTime))
+ , time_out_(60) {}
+
+AppStopwatchImpl::AppStopwatchImpl(
+ utils::SharedPtr<StatisticsManager> statistics_manager,
+ const std::string& app_id,
+ uint32_t timeout)
+ : app_id_(app_id)
+ , stopwatch_type_(SECONDS_HMI_NONE)
+ , statistics_manager_(statistics_manager)
+ , timer_("HMI levels timer",
+ new timer::TimerTaskImpl<AppStopwatchImpl>(
+ this, &AppStopwatchImpl::WriteTime))
+ , time_out_(timeout) {}
+
+AppStopwatchImpl::~AppStopwatchImpl() {}
+
+void AppStopwatchImpl::Start(AppStopwatchId stopwatch_type) {
+ stopwatch_type_ = stopwatch_type;
+ timer_.Start(time_out_ * date_time::DateTime::MILLISECONDS_IN_SECOND,
+ timer::kPeriodic);
+}
+
+void AppStopwatchImpl::Switch(AppStopwatchId stopwatch_type) {
+ Start(stopwatch_type);
+}
+
+void AppStopwatchImpl::WriteTime() {
+ if (statistics_manager_) {
+ statistics_manager_->Add(app_id_, stopwatch_type_, time_out_);
+ }
+}
+
+} // namespace usage_statistics
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_STATISTICS_MANAGER_H_