diff options
Diffstat (limited to 'src/components/policy/src/policy/src/cache_manager.cc')
-rw-r--r-- | src/components/policy/src/policy/src/cache_manager.cc | 779 |
1 files changed, 531 insertions, 248 deletions
diff --git a/src/components/policy/src/policy/src/cache_manager.cc b/src/components/policy/src/policy/src/cache_manager.cc index 62e96ae0e..05c36223d 100644 --- a/src/components/policy/src/policy/src/cache_manager.cc +++ b/src/components/policy/src/policy/src/cache_manager.cc @@ -1,34 +1,34 @@ -/* -* 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. -*/ +/* + * 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" @@ -40,9 +40,9 @@ #include "utils/file_system.h" #include "json/reader.h" #include "json/features.h" +#include "json/writer.h" #include "utils/logger.h" -// EXTENDED_POLICY # include "policy/sql_pt_representation.h" namespace policy_table = rpc::policy_table_interface_base; @@ -65,15 +65,37 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "CacheManager") }\ } +struct LanguageFinder { + 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_; +}; CacheManager::CacheManager() : CacheManagerInterface(), backup_( -// EXTENDED_POLICY new SQLPTRepresentation() ), update_required(false) { + LOG4CXX_AUTO_TRACE(logger_); + backuper_ = new BackgroundBackuper(this); + backup_thread_ = threads::CreateThread("Backup thread", backuper_); + backup_thread_->start(); +} + +CacheManager::~CacheManager() { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(backuper_locker_); + backup_thread_->join(); + delete backup_thread_->delegate(); + threads::DeleteThread(backup_thread_); } bool CacheManager::CanAppKeepContext(const std::string &app_id) { @@ -86,9 +108,9 @@ uint16_t CacheManager::HeartBeatTimeout(const std::string &app_id) const { CACHE_MANAGER_CHECK(0); uint16_t result = 0; if (AppExists(app_id)) { - if (pt_->policy_table.app_policies[app_id].heart_beat_timeout_ms + if (pt_->policy_table.app_policies_section.apps[app_id].heart_beat_timeout_ms .is_initialized()) { - result = *(pt_->policy_table.app_policies[app_id].heart_beat_timeout_ms); + result = *(pt_->policy_table.app_policies_section.apps[app_id].heart_beat_timeout_ms); } } return result; @@ -104,12 +126,12 @@ bool CacheManager::GetDefaultHMI(const std::string &app_id, std::string& default_hmi) { CACHE_MANAGER_CHECK(false); bool result = true; - return result; } bool CacheManager::ResetUserConsent() { CACHE_MANAGER_CHECK(false); + sync_primitives::AutoLock lock (cache_lock_); return true; } @@ -118,21 +140,36 @@ bool CacheManager::GetUserPermissionsForDevice(const std::string &device_id, StringArray& consented_groups, StringArray& disallowed_groups) { - LOG4CXX_TRACE_ENTER(logger_); + LOG4CXX_AUTO_TRACE(logger_); CACHE_MANAGER_CHECK(false); - LOG4CXX_TRACE_EXIT(logger_); return true; } void CacheManager::GetAllAppGroups(const std::string& app_id, FunctionalGroupIDs& all_group_ids) { - LOG4CXX_TRACE_ENTER(logger_); + 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> ((GenerateHash(*iter))); + all_group_ids.push_back(group_id); + } + + return; + } + policy_table::ApplicationPolicies::const_iterator app_params_iter = - pt_->policy_table.app_policies.find(app_id); + pt_->policy_table.app_policies_section.apps.find(app_id); - if (pt_->policy_table.app_policies.end() != app_params_iter) { + 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 = @@ -144,15 +181,13 @@ void CacheManager::GetAllAppGroups(const std::string& app_id, all_group_ids.push_back(group_id); } } - LOG4CXX_TRACE_EXIT(logger_); } void CacheManager::GetPreConsentedGroups(const std::string &app_id, FunctionalGroupIDs& preconsented_groups) { - LOG4CXX_TRACE_ENTER(logger_); + LOG4CXX_AUTO_TRACE(logger_); CACHE_MANAGER_CHECK_VOID(); - LOG4CXX_TRACE_EXIT(logger_); } void CacheManager::GetConsentedGroups(const std::string &device_id, @@ -160,17 +195,15 @@ void CacheManager::GetConsentedGroups(const std::string &device_id, FunctionalGroupIDs& allowed_groups, FunctionalGroupIDs& disallowed_groups) { - LOG4CXX_TRACE_ENTER(logger_); + LOG4CXX_AUTO_TRACE(logger_); CACHE_MANAGER_CHECK_VOID(); - LOG4CXX_TRACE_EXIT(logger_); } void CacheManager::GetUnconsentedGroups(const std::string& device_id, const std::string& policy_app_id, FunctionalGroupIDs& unconsented_groups) { - LOG4CXX_TRACE_ENTER(logger_); + LOG4CXX_AUTO_TRACE(logger_); CACHE_MANAGER_CHECK_VOID(); - LOG4CXX_TRACE_EXIT(logger_); } void CacheManager::RemoveAppConsentForGroup(const std::string& app_id, @@ -179,65 +212,75 @@ void CacheManager::RemoveAppConsentForGroup(const std::string& app_id, } bool CacheManager::ApplyUpdate(const policy_table::Table& update_pt) { - LOG4CXX_TRACE_ENTER(logger_); + 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.begin(); + update_pt.policy_table.app_policies_section.apps.begin(); policy_table::ApplicationPolicies::const_iterator iter_end = - update_pt.policy_table.app_policies.end(); + update_pt.policy_table.app_policies_section.apps.end(); for (;iter != iter_end; ++iter) { - pt_->policy_table.app_policies[iter->first] = iter->second; + if (iter->second.is_null()) { + 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()) { + pt_->policy_table.app_policies_section.apps[iter->first] = + pt_->policy_table.app_policies_section.apps[kDefaultId]; + } else { + pt_->policy_table.app_policies_section.apps[iter->first] = iter->second; + } } - pt_->policy_table.module_config = update_pt.policy_table.module_config; + pt_->policy_table.app_policies_section.device = + update_pt.policy_table.app_policies_section.device; if (update_pt.policy_table.consumer_friendly_messages.is_initialized()) { pt_->policy_table.consumer_friendly_messages = update_pt.policy_table.consumer_friendly_messages; } - - LOG4CXX_TRACE_EXIT(logger_); + ResetCalculatedPermissions(); + Backup(); return true; } -void CacheManager::Backup() { +void CacheManager::GetHMIAppTypeAfterUpdate(std::map<std::string, StringArray>& app_hmi_types) { + LOG4CXX_AUTO_TRACE(logger_); CACHE_MANAGER_CHECK_VOID(); - sync_primitives::AutoLock auto_lock(cache_lock_); - if (backup_.valid()) { - if (pt_.valid()) { - backup_->Save(*pt_); - backup_->SaveUpdateRequired(update_required); - - - policy_table::ApplicationPolicies::const_iterator app_policy_iter = - pt_->policy_table.app_policies.begin(); - policy_table::ApplicationPolicies::const_iterator app_policy_iter_end = - pt_->policy_table.app_policies.end(); - - for (; app_policy_iter != app_policy_iter_end; ++app_policy_iter) { - - const std::string app_id = (*app_policy_iter).first; - backup_->SaveApplicationCustomData(app_id, - IsApplicationRevoked(app_id), - IsDefaultPolicy(app_id), - is_predata_[app_id]); + 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(); } - - // In case of extended policy the meta info should be backuped as well. + 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; } } } +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); - strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct); + // ISO_8601 format is expected, e.g. “2000-01-01T12:18:53Z” + strftime(buf, sizeof(buf), "%Y-%m-%dT%XZ", &tstruct); return buf; } @@ -245,21 +288,18 @@ bool CacheManager::GetPermissionsForApp(const std::string &device_id, const std::string &app_id, FunctionalIdType& group_types) { - LOG4CXX_TRACE_ENTER(logger_); + LOG4CXX_AUTO_TRACE(logger_); GetAllAppGroups(app_id, group_types[kTypeGeneral]); GetAllAppGroups(kDefaultId, group_types[kTypeDefault]); GetAllAppGroups(kPreDataConsentId, group_types[kTypePreDataConsented]); - LOG4CXX_TRACE_EXIT(logger_); return true; } bool CacheManager::GetDeviceGroupsFromPolicies( policy_table::Strings& groups, policy_table::Strings& preconsented_groups) { - - LOG4CXX_TRACE_ENTER(logger_); + LOG4CXX_AUTO_TRACE(logger_); CACHE_MANAGER_CHECK(false); - LOG4CXX_TRACE_EXIT(logger_); return true; } @@ -271,11 +311,11 @@ bool CacheManager::SetDeviceData(const std::string &device_id, 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_); - LOG4CXX_TRACE_ENTER(logger_); CACHE_MANAGER_CHECK(false); - LOG4CXX_TRACE_EXIT(logger_); + Backup(); return true; } @@ -283,19 +323,19 @@ 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_); - LOG4CXX_TRACE_ENTER(logger_); CACHE_MANAGER_CHECK(false); - LOG4CXX_TRACE_EXIT(logger_); + Backup(); return true; } bool CacheManager::ReactOnUserDevConsentForApp(const std::string &app_id, bool is_device_allowed) { - LOG4CXX_TRACE_ENTER(logger_); + LOG4CXX_AUTO_TRACE(logger_); CACHE_MANAGER_CHECK(false); bool result = true; - LOG4CXX_TRACE_EXIT(logger_); + Backup(); return result; } @@ -318,10 +358,10 @@ void CacheManager::GetGroupNameByHashID(const int32_t group_id, bool CacheManager::SetUserPermissionsForApp( const PermissionConsent &permissions) { + LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock auto_lock(cache_lock_); - LOG4CXX_TRACE_ENTER(logger_); CACHE_MANAGER_CHECK(false); - LOG4CXX_TRACE_EXIT(logger_); + Backup(); return true; } @@ -330,16 +370,16 @@ bool CacheManager::UpdateRequired() const { } void CacheManager::SaveUpdateRequired(bool status) { - update_required = status; + Backup(); } -bool CacheManager::IsApplicationRevoked(const std::string& app_id) { +bool CacheManager::IsApplicationRevoked(const std::string& app_id) const { CACHE_MANAGER_CHECK(false); bool is_revoked = false; - if (pt_->policy_table.app_policies.end() != - pt_->policy_table.app_policies.find(app_id)) { - is_revoked = pt_->policy_table.app_policies[app_id].is_null(); + if (pt_->policy_table.app_policies_section.apps.end() != + pt_->policy_table.app_policies_section.apps.find(app_id)) { + is_revoked = pt_->policy_table.app_policies_section.apps[app_id].is_null(); } return is_revoked; @@ -349,21 +389,21 @@ void CacheManager::CheckPermissions(const PTString &app_id, const PTString &hmi_level, const PTString &rpc, CheckPermissionResult &result) { - LOG4CXX_TRACE_ENTER(logger_); + LOG4CXX_AUTO_TRACE(logger_); CACHE_MANAGER_CHECK_VOID(); - if (pt_->policy_table.app_policies.end() == - pt_->policy_table.app_policies.find(app_id)) { + if (pt_->policy_table.app_policies_section.apps.end() == + pt_->policy_table.app_policies_section.apps.find(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[app_id].groups.begin(); + 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[app_id].groups.end(); + pt_->policy_table.app_policies_section.apps[app_id].groups.end(); policy_table::FunctionalGroupings::const_iterator concrete_group; @@ -399,7 +439,6 @@ void CacheManager::CheckPermissions(const PTString &app_id, } } } - LOG4CXX_TRACE_EXIT(logger_); } bool CacheManager::IsPTPreloaded() { @@ -412,7 +451,7 @@ int CacheManager::IgnitionCyclesBeforeExchange() { 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:" << limit); uint8_t current = 0; @@ -421,19 +460,22 @@ int CacheManager::IgnitionCyclesBeforeExchange() { int CacheManager::KilometersBeforeExchange(int current) { CACHE_MANAGER_CHECK(0); - const uint8_t limit = std::max( + const int limit = std::max( static_cast<int>( pt_->policy_table.module_config.exchange_after_x_kilometers), 0); - uint8_t last = 0; + LOG4CXX_DEBUG(logger_, "KilometersBeforeExchange limit:" << limit); + int last = 0; - const uint8_t actual = std::max((current - last), 0); + const int actual = std::max((current - last), 0); + LOG4CXX_DEBUG(logger_, "KilometersBeforeExchange actual:" << actual); return std::max(limit - actual, 0); } bool CacheManager::SetCountersPassedForSuccessfulUpdate(int kilometers, int days_after_epoch) { CACHE_MANAGER_CHECK(false); + Backup(); return true; } @@ -442,19 +484,23 @@ int CacheManager::DaysBeforeExchange(int current) { const uint8_t limit = std::max( static_cast<int>( pt_->policy_table.module_config.exchange_after_x_days), 0); + LOG4CXX_DEBUG(logger_, "DaysBeforeExchange limit:" << limit); uint8_t last = 0; const uint8_t actaul = std::max((current - last), 0); + LOG4CXX_DEBUG(logger_, "DaysBeforeExchange actual:" << actaul); return std::max(limit - actaul, 0); } void CacheManager::IncrementIgnitionCycles() { CACHE_MANAGER_CHECK_VOID(); + Backup(); } void CacheManager::ResetIgnitionCycles() { CACHE_MANAGER_CHECK_VOID(); + Backup(); } int CacheManager::TimeoutResponse() { @@ -486,41 +532,69 @@ VehicleData CacheManager::GetVehicleData() { std::vector<UserFriendlyMessage> CacheManager::GetUserFriendlyMsg( const std::vector<std::string> &msg_codes, const std::string &language) { - LOG4CXX_TRACE_ENTER(logger_); + LOG4CXX_AUTO_TRACE(logger_); std::vector<UserFriendlyMessage> result; CACHE_MANAGER_CHECK(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) { + policy_table::MessageLanguages msg_languages = + (*pt_->policy_table.consumer_friendly_messages->messages)[*it]; + + policy_table::MessageString message_string; + + // If message has no records with required language, fallback language + // should be used instead. + LanguageFinder finder(language); + policy_table::Languages::const_iterator it_language = + std::find_if(msg_languages.languages.begin(), + msg_languages.languages.end(), + finder); + + if (msg_languages.languages.end() == it_language) { + LOG4CXX_WARN(logger_, "Language " << language << + " haven't been found for message code: " << *it); + + LanguageFinder fallback_language_finder("en-us"); + + policy_table::Languages::const_iterator it_fallback_language = + std::find_if(msg_languages.languages.begin(), + msg_languages.languages.end(), + fallback_language_finder); + + if (msg_languages.languages.end() == it_fallback_language) { + LOG4CXX_ERROR(logger_, "No fallback language found for message code: " + << *it); + continue; + } + + message_string = it_fallback_language->second; + } else { + message_string = it_language->second; + } + UserFriendlyMessage msg; msg.message_code = *it; result.push_back(msg); } - LOG4CXX_TRACE_EXIT(logger_); return result; } -EndpointUrls CacheManager::GetUpdateUrls(int service_type) { - LOG4CXX_TRACE_ENTER(logger_); - - EndpointUrls result; - CACHE_MANAGER_CHECK(result); - char buff[32]; - sprintf(buff, "%x", service_type); - - std::string serv_type(buff); - // TODO: remove this workaround - if (service_type <= 0x9) { - serv_type.insert(0,"0x0", 3); - } else { - serv_type.insert(0,"0x", 2); +void CacheManager::GetServiceUrls(const std::string& service_type, + EndpointUrls& end_points) { + LOG4CXX_AUTO_TRACE(logger_); + CACHE_MANAGER_CHECK_VOID(); + std::string search_value; + if (!IsNumberService(service_type, search_value)) { + search_value = service_type; } + LOG4CXX_DEBUG(logger_, "Search service value is: " << search_value); + policy_table::ServiceEndpoints::const_iterator iter = - pt_->policy_table.module_config.endpoints.find(serv_type); + pt_->policy_table.module_config.endpoints.find(search_value); if (pt_->policy_table.module_config.endpoints.end() != iter) { policy_table::URLList::const_iterator url_list_iter = (*iter).second.begin(); @@ -531,11 +605,16 @@ EndpointUrls CacheManager::GetUpdateUrls(int service_type) { std::copy((*url_list_iter).second.begin(), (*url_list_iter).second.end(), std::back_inserter(data.url)); - result.push_back(data); + end_points.push_back(data); } } - LOG4CXX_TRACE_EXIT(logger_); - return result; +} + +std::string CacheManager::GetLockScreenIconUrl() const { + if (backup_) { + return backup_->GetLockScreenIconUrl(); + } + return std::string (""); } int CacheManager::GetNotificationsNumber(const std::string &priority) { @@ -554,10 +633,17 @@ int CacheManager::GetNotificationsNumber(const std::string &priority) { bool CacheManager::GetPriority(const std::string &policy_app_id, std::string &priority) { 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; + pt_->policy_table.app_policies_section.apps; - policy_table::ApplicationPolicies::const_iterator policy_iter = policies.find(policy_app_id); + 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); @@ -576,10 +662,130 @@ void CacheManager::CheckSnapshotInitialization() { *(snapshot_->policy_table.module_config.preloaded_pt) = false; } +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; + bool is_default_policy; + bool is_predata_policy; + + for (; app_policy_iter != app_policy_iter_end; ++app_policy_iter) { + + const std::string app_id = (*app_policy_iter).first; + + if (copy_pt.policy_table.app_policies_section.apps.end() != + copy_pt.policy_table.app_policies_section.apps.find(app_id)) { + is_revoked = copy_pt.policy_table.app_policies_section.apps[app_id].is_null(); + } + + is_default_policy = copy_pt.policy_table.app_policies_section.apps.end() != + copy_pt.policy_table.app_policies_section.apps.find(app_id) && + policy::kDefaultId == + copy_pt.policy_table.app_policies_section.apps[app_id].get_string(); + + // TODO(AOleynik): Remove this field from DB + is_predata_policy = copy_pt.policy_table.app_policies_section.apps.end() != + copy_pt.policy_table.app_policies_section.apps.find(app_id) && + policy::kPreDataConsentId == + copy_pt.policy_table.app_policies_section.apps[app_id].get_string(); + + backup_->SaveApplicationCustomData(app_id, + is_revoked, + is_default_policy, + is_predata_policy); + is_revoked = false; + } + + // In case of extended policy the meta info should be backuped as well. + backup_->WriteDb(); + } + } +} + +void CacheManager::ResetCalculatedPermissions() { + LOG4CXX_TRACE(logger_, "ResetCalculatedPermissions"); + sync_primitives::AutoLock lock(calculated_permissions_lock_); + calculated_permissions_.clear(); +} + +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; +} + +bool policy::CacheManager::IsNumberService(const std::string& input, + std::string& output) const { + const char* input_value = input.c_str(); + char* endptr; + const int base = 10; + errno = 0; + uint32_t service_value = strtoul(input_value, &endptr, base); + bool is_real_zero_value = + (!service_value && endptr != input_value && *endptr == '\0'); + if (!is_real_zero_value && (!service_value || errno == ERANGE)) { + return false; + } + + output = input; + if (service_value <= 9) { + output.insert(0,"0x0", 3); + } else { + output.insert(0,"0x", 2); + } + + return true; +} + utils::SharedPtr<policy_table::Table> CacheManager::GenerateSnapshot() { CACHE_MANAGER_CHECK(snapshot_); - snapshot_ = utils::SharedPtr<policy_table::Table>(new policy_table::Table(pt_->policy_table)); + sync_primitives::AutoLock lock(cache_lock_); + snapshot_ = new policy_table::Table(); + snapshot_->policy_table = pt_->policy_table; CheckSnapshotInitialization(); return snapshot_; } @@ -588,50 +794,54 @@ bool CacheManager::GetInitialAppData(const std::string& app_id, StringArray& nicknames, StringArray& app_hmi_types) { - LOG4CXX_TRACE_ENTER(logger_); + LOG4CXX_AUTO_TRACE(logger_); CACHE_MANAGER_CHECK(false); policy_table::ApplicationPolicies::const_iterator policy_iter = - pt_->policy_table.app_policies.find(app_id); + pt_->policy_table.app_policies_section.apps.find(app_id); - if (pt_->policy_table.app_policies.end() != policy_iter) { + 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(nicknames), AppHMITypeToString()); + std::back_inserter(app_hmi_types), AppHMITypeToString()); } - LOG4CXX_TRACE_EXIT(logger_); return true; } bool CacheManager::GetFunctionalGroupings( policy_table::FunctionalGroupings& groups) { - LOG4CXX_TRACE_ENTER(logger_); + 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()); - LOG4CXX_TRACE_EXIT(logger_); return true; } -bool CacheManager::CountUnconsentedGroups(const std::string& policy_app_id, - const std::string& device_id, - int& result) { - LOG4CXX_TRACE_ENTER(logger_); +int CacheManager::CountUnconsentedGroups(const std::string& policy_app_id, + const std::string& device_id) { + LOG4CXX_AUTO_TRACE(logger_); CACHE_MANAGER_CHECK(false); - LOG4CXX_TRACE_EXIT(logger_); - return true; + LOG4CXX_DEBUG(logger_, "Application id: " << policy_app_id); + int result = 0; + return result; } bool CacheManager::SetMetaInfo(const std::string &ccpu_version, const std::string &wers_country_code, const std::string &language) { CACHE_MANAGER_CHECK(false); + + // 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; } @@ -643,11 +853,12 @@ bool CacheManager::IsMetaInfoPresent() const { bool CacheManager::SetSystemLanguage(const std::string &language) { CACHE_MANAGER_CHECK(false); + Backup(); return true; } bool CacheManager::GetFunctionalGroupNames(FunctionalGroupNames &names) { - LOG4CXX_TRACE_ENTER(logger_); + LOG4CXX_AUTO_TRACE(logger_); CACHE_MANAGER_CHECK(false); rpc::policy_table_interface_base::FunctionalGroupings::iterator iter = pt_->policy_table.functional_groupings.begin(); @@ -661,39 +872,38 @@ bool CacheManager::GetFunctionalGroupNames(FunctionalGroupNames &names) { names.insert(std::pair<uint32_t, std::pair<std::string, std::string> >(id, value)); } - LOG4CXX_TRACE_EXIT(logger_); return true; } -bool CacheManager::CleanupUnpairedDevices(const DeviceIds &device_ids) { +bool CacheManager::CleanupUnpairedDevices() { CACHE_MANAGER_CHECK(false); + Backup(); return true; } void CacheManager::Increment(usage_statistics::GlobalCounterId type) { CACHE_MANAGER_CHECK_VOID(); + Backup(); } void CacheManager::Increment(const std::string &app_id, usage_statistics::AppCounterId type) { CACHE_MANAGER_CHECK_VOID(); + Backup(); } void CacheManager::Set(const std::string &app_id, usage_statistics::AppInfoId type, const std::string &value) { CACHE_MANAGER_CHECK_VOID(); + Backup(); } void CacheManager::Add(const std::string &app_id, usage_statistics::AppStopwatchId type, int seconds) { CACHE_MANAGER_CHECK_VOID(); -} - -void CacheManager::CopyInternalParams(const std::string &from, - const std::string& to) { - is_predata_[to] = is_predata_[from]; + Backup(); } long CacheManager::ConvertSecondsToMinute(int seconds) { @@ -704,41 +914,34 @@ long CacheManager::ConvertSecondsToMinute(int seconds) { bool CacheManager::SetDefaultPolicy(const std::string &app_id) { CACHE_MANAGER_CHECK(false); policy_table::ApplicationPolicies::const_iterator iter = - pt_->policy_table.app_policies.find(kDefaultId); - if (pt_->policy_table.app_policies.end() != iter) { - pt_->policy_table.app_policies[app_id] = - pt_->policy_table.app_policies[kDefaultId]; + pt_->policy_table.app_policies_section.apps.find(kDefaultId); + if (pt_->policy_table.app_policies_section.apps.end() != iter) { + pt_->policy_table.app_policies_section.apps[app_id] = + pt_->policy_table.app_policies_section.apps[kDefaultId]; - CopyInternalParams(kDefaultId, app_id); - SetIsDefault(app_id, true); - SetIsPredata(app_id, false); - - pt_->policy_table.app_policies[app_id].set_to_string(kDefaultId); + SetIsDefault(app_id); } + Backup(); return true; } bool CacheManager::IsDefaultPolicy(const std::string& app_id) { CACHE_MANAGER_CHECK(false); const bool result = - pt_->policy_table.app_policies.end() != - pt_->policy_table.app_policies.find(app_id) && - !pt_->policy_table.app_policies[app_id].get_string().empty(); + pt_->policy_table.app_policies_section.apps.end() != + pt_->policy_table.app_policies_section.apps.find(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, - bool is_default) { +bool CacheManager::SetIsDefault(const std::string& app_id) { CACHE_MANAGER_CHECK(false); policy_table::ApplicationPolicies::const_iterator iter = - pt_->policy_table.app_policies.find(app_id); - if (pt_->policy_table.app_policies.end() != iter) { - if (is_default) { - pt_->policy_table.app_policies[app_id].set_to_string("default"); - } else { - pt_->policy_table.app_policies[app_id].set_to_string(""); - } + pt_->policy_table.app_policies_section.apps.find(app_id); + if (pt_->policy_table.app_policies_section.apps.end() != iter) { + pt_->policy_table.app_policies_section.apps[app_id].set_to_string(kDefaultId); } return true; } @@ -746,67 +949,85 @@ bool CacheManager::SetIsDefault(const std::string& app_id, bool CacheManager::SetPredataPolicy(const std::string &app_id) { CACHE_MANAGER_CHECK(false); policy_table::ApplicationPolicies::const_iterator iter = - pt_->policy_table.app_policies.find(kPreDataConsentId); + pt_->policy_table.app_policies_section.apps.find(kPreDataConsentId); - if (pt_->policy_table.app_policies.end() != iter) { - pt_->policy_table.app_policies[app_id] = - pt_->policy_table.app_policies[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; + } - CopyInternalParams(kPreDataConsentId, app_id); + pt_->policy_table.app_policies_section.apps[app_id] = + pt_->policy_table.app_policies_section.apps[kPreDataConsentId]; - SetIsPredata(app_id, true); - SetIsDefault(app_id, false); - } - return true; -} + pt_->policy_table.app_policies_section.apps[app_id].set_to_string(kPreDataConsentId); -bool CacheManager::SetIsPredata(const std::string &app_id, bool is_pre_data) { - is_predata_[app_id] = is_pre_data; + Backup(); return true; } bool CacheManager::IsPredataPolicy(const std::string &app_id) { - const bool result = - (is_predata_.end() != is_predata_.find(app_id)) && is_predata_[app_id]; - return result; -} + // TODO(AOleynik): Maybe change for comparison with pre_DataConsent + // permissions or check string value from get_string() + policy_table::ApplicationParams& pre_data_app = + pt_->policy_table.app_policies_section.apps[kPreDataConsentId]; + policy_table::ApplicationParams& specific_app = + pt_->policy_table.app_policies_section.apps[app_id]; -bool CacheManager::SetUnpairedDevice(const std::string &device_id) { + policy_table::Strings res; + std::set_intersection(pre_data_app.groups.begin(), + pre_data_app.groups.end(), + specific_app.groups.begin(), + specific_app.groups.end(), + std::back_inserter(res)); - const bool result = is_unpaired_.end() != is_unpaired_.find(device_id); - if (result) { - is_unpaired_[device_id] = true; - } - return result; -} + bool is_marked_as_predata = + kPreDataConsentId == + pt_->policy_table.app_policies_section.apps[app_id].get_string(); -bool CacheManager::UnpairedDevicesList(DeviceIds& device_ids) { + return !res.empty() && is_marked_as_predata; +} - std::map<std::string, bool>::const_iterator iter = is_unpaired_.begin(); - std::map<std::string, bool>::const_iterator iter_end = is_unpaired_.end(); +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; + } - for (; iter != iter_end; ++iter) { - if ((*iter).second) { - device_ids.push_back((*iter).first); - } + 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 true; + return result; } bool CacheManager::SetVINValue(const std::string& value) { CACHE_MANAGER_CHECK(false); + Backup(); return true; } bool CacheManager::IsApplicationRepresented(const std::string& app_id) const { CACHE_MANAGER_CHECK(false); + if (kDeviceId == app_id) { + return true; + } policy_table::ApplicationPolicies::const_iterator iter = - pt_->policy_table.app_policies.find(app_id); - return pt_->policy_table.app_policies.end() != 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) { - LOG4CXX_INFO(logger_, "CacheManager::Init"); + LOG4CXX_AUTO_TRACE(logger_); InitResult init_result = backup_->Init(); @@ -829,83 +1050,73 @@ bool CacheManager::Init(const std::string& file_name) { return result; } -void CacheManager::FillAppSpecificData() { - CACHE_MANAGER_CHECK_VOID(); - policy_table::ApplicationPolicies::const_iterator iter = - pt_->policy_table.app_policies.begin(); - policy_table::ApplicationPolicies::const_iterator iter_end = - pt_->policy_table.app_policies.begin(); - - for (; iter != iter_end; ++iter) { - const std::string& app_name = (*iter).first; - - is_predata_.insert(std::make_pair(app_name, backup_->IsPredataPolicy(app_name))); - } -} - void CacheManager::FillDeviceSpecificData() { } bool CacheManager::LoadFromBackup() { + sync_primitives::AutoLock lock(cache_lock_); pt_ = backup_->GenerateSnapshot(); update_required = backup_->UpdateRequired(); - FillAppSpecificData(); FillDeviceSpecificData(); return true; } bool CacheManager::LoadFromFile(const std::string& file_name) { - - LOG4CXX_INFO(logger_, "CacheManager::LoadFromFile"); + LOG4CXX_AUTO_TRACE(logger_); BinaryMessage json_string; - bool final_result = false; - final_result = file_system::ReadBinaryFile(file_name, json_string); - if (!final_result) { - LOG4CXX_WARN(logger_, "Failed to read pt file."); - return final_result; + if (!file_system::ReadBinaryFile(file_name, json_string)) { + LOG4CXX_FATAL(logger_, "Failed to read pt file."); + return false; } Json::Value value; Json::Reader reader(Json::Features::strictMode()); std::string json(json_string.begin(), json_string.end()); - bool ok = reader.parse(json.c_str(), value); - if (ok) { - pt_ = new policy_table::Table(&value); - } else { - LOG4CXX_WARN(logger_, reader.getFormattedErrorMessages()); - } - - if (!pt_) { - LOG4CXX_WARN(logger_, "Failed to parse policy table"); + if (!reader.parse(json.c_str(), value)) { + LOG4CXX_FATAL( + logger_, + "Preloaded PT is corrupted: " << reader.getFormattedErrorMessages()); return false; } - if (!pt_->is_valid()) { + LOG4CXX_TRACE(logger_, "Start create PT"); + sync_primitives::AutoLock locker(cache_lock_); + backup_->Clear(); + + pt_ = new policy_table::Table(&value); + if (pt_->is_valid()) { + if (backup_->Save(*pt_)) { + backup_->WriteDb(); + return true; + } else { + LOG4CXX_FATAL(logger_, "Failed to save PT"); + return false; + } + } else { rpc::ValidationReport report("policy_table"); pt_->ReportErrors(&report); - LOG4CXX_WARN(logger_, "Parsed table is not valid " << - rpc::PrettyFormat(report)); + LOG4CXX_FATAL(logger_, + "Parsed table is not valid " << rpc::PrettyFormat(report)); + return false; } - - final_result = backup_->Save(*pt_); - LOG4CXX_INFO( - logger_, - "Loading from file was " << (final_result ? "successful" : "unsuccessful")); - return final_result; } bool CacheManager::ResetPT(const std::string& file_name) { bool result = true; + Backup(); return result; } bool CacheManager::AppExists(const std::string &app_id) const { CACHE_MANAGER_CHECK(false); + if (kDeviceId == app_id) { + return true; + } policy_table::ApplicationPolicies::iterator policy_iter = - pt_->policy_table.app_policies.find(app_id); - return pt_->policy_table.app_policies.end() != policy_iter; + pt_->policy_table.app_policies_section.apps.find(app_id); + return pt_->policy_table.app_policies_section.apps.end() != policy_iter; } int32_t CacheManager::GenerateHash(const std::string& str_to_hash) { @@ -924,4 +1135,76 @@ int32_t CacheManager::GenerateHash(const std::string& str_to_hash) { 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(); + 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; + } + 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; +} + +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 |