--- /dev/null
+/*
+ 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_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_POLICY_HANDLER_H_
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_POLICY_HANDLER_H_
+
+#include <string>
+#include <map>
+#include <set>
+#include <vector>
+#include "policy/policy_manager.h"
+#include "application_manager/policies/policy_event_observer.h"
+#include "application_manager/policies/pt_exchange_handler.h"
+#include "utils/logger.h"
+#include "utils/lock.h"
+#include "utils/threads/thread.h"
+#include "utils/singleton.h"
+
+namespace Json {
+class Value;
+}
+
+namespace policy {
+
+typedef std::vector<uint32_t> AppIds;
+typedef std::vector<uint32_t> DeviceHandles;
+
+class PolicyHandler : public utils::Singleton<PolicyHandler>,
+ public PolicyListener {
+ public:
+ virtual ~PolicyHandler();
+ PolicyManager* LoadPolicyLibrary();
+ PolicyManager* LoadPolicyLibrary(const std::string& path);
+ PolicyManager* policy_manager() const {
+ return policy_manager_;
+ }
+ bool InitPolicyTable();
+ bool RevertPolicyTable();
+ bool SendMessageToSDK(const BinaryMessage& pt_string);
+ bool ReceiveMessageFromSDK(const BinaryMessage& pt_string);
+ bool UnloadPolicyLibrary();
+ void OnPTExchangeNeeded();
+ void OnPermissionsUpdated(const std::string& policy_app_id,
+ const Permissions& permissions);
+ /**
+ * @brief Checks, if policy update is necessary for application
+ */
+ void CheckAppPolicyState(const std::string& application_id);
+
+ /**
+ * Starts proccess updating policy table
+ */
+ void StartPTExchange(bool skip_device_selection = false);
+
+ /**
+ * Lets client to notify PolicyHandler that more kilometers expired
+ * @param kms New value of odometer
+ */
+ void KmsChanged(int kms);
+
+ /**
+ * @brief Gather information for application and sends it to HMI
+ * @param connection_key Connection key for application
+ */
+ void OnActivateApp(const std::string& connection_key,
+ uint32_t correlation_id);
+
+ /**
+ * @brief Process user consent on mobile data connection access
+ * @param Device id or 0, if concern to all SDL functionality
+ * @param User consent from response
+ */
+ void OnAllowSDLFunctionalityNotification(bool is_allowed, uint32_t device_id =
+ 0);
+ /**
+ * @brief Send request to HMI for requesting the allowance for some
+ * application functionality
+ * @param List of permissions required by application
+ * @param Unique appication id, if omitted - allow/disallow all applications
+ */
+ void SendAllowApp(const PermissionsList& list_of_permissions,
+ uint32_t application_id = 0);
+
+ /**
+ * @brief Process application permission, which was set by user
+ * @param List of user-defined permissions for application
+ */
+ void OnAllowAppResponse(PermissionsList& list_of_permissions);
+
+ /**
+ * @brief Process application permission, which was set by user
+ * @param List of user-defined permissions for application
+ * @param Unique application id, if omitted - allow/disallow all
+ * applications
+ */
+ void OnAllowAppNotification(PermissionsList& list_of_permissions,
+ uint32_t appication_id = 0);
+
+ /**
+ * @brief Increment counter for ignition cycles
+ */
+ void OnIgnitionCycleOver();
+
+ /**
+ * @brief Send notification to HMI concerning revocation of application
+ * @param policy_app_id Unique identifier of application
+ */
+ void OnAppRevoked(const std::string& policy_app_id);
+
+ /**
+ * Initializes PT exchange at ignition if need
+ */
+ void PTExchangeAtIgnition();
+
+ /**
+ * @brief Save device info for specific device to policy table
+ * @param device_id Device mac address
+ * @param device_info Device params
+ */
+ void SetDeviceInfo(std::string& device_id, const DeviceInfo& device_info);
+
+ /**
+ * @brief Store user-changed permissions consent to DB
+ * @param permissions User-changed group permissions consent
+ */
+ void OnAppPermissionConsent(const PermissionConsent& permissions);
+
+ protected:
+ /**
+ * Starts next retry exchange policy table
+ */
+ void StartNextRetry();
+
+ /**
+ * Initializes PT exchange at odometer if need
+ * @param kilometers value from odometer in kilometers
+ */
+ void PTExchangeAtOdometer(int kilometers);
+
+ private:
+ /**
+ * @brief Choose application id to be used for snapshot sending
+ * @return Application id or 0, if there are no applications registered
+ */
+ uint32_t GetAppIdForSending();
+
+ /**
+ * @brief Choose device according to app HMI status and user consent for
+ * device
+ * @param device_info Struct with selected device parameters
+ * @return consent status for selected device
+ */
+ DeviceConsent GetDeviceForSending(DeviceParams& device_params);
+
+ private:
+ PolicyHandler();
+ static PolicyHandler* instance_;
+ static const std::string kLibrary;
+ PolicyManager* policy_manager_;
+ void* dl_handle_;
+ AppIds last_used_app_ids_;
+ static log4cxx::LoggerPtr logger_;
+ threads::Thread retry_sequence_;
+ sync_primitives::Lock retry_sequence_lock_;
+ PTExchangeHandler* exchange_handler_;
+ utils::SharedPtr<PolicyEventObserver> event_observer_;
+
+ /**
+ * @brief Contains device handles, which were sent for user consent to HMI
+ */
+ DeviceHandles pending_device_handles_;
+
+ /**
+ * @brief True, if PTS was sent, but PTU was not reseived yet,
+ * otherwise - false
+ * Used for limiting device consent request per PTS/PTU session
+ */
+ bool is_exchange_in_progress_;
+
+ inline PolicyManager* CreateManager();
+
+ DISALLOW_COPY_AND_ASSIGN(PolicyHandler);FRIEND_BASE_SINGLETON_CLASS_INSTANCE(PolicyHandler);
+ friend class RetrySequence;
+};
+
+} // namespace policy
+
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_POLICY_HANDLER_H_
--- /dev/null
+/**
+ * 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 "application_manager/commands/hmi/on_app_permission_consent_notification.h"
+#include "application_manager/application_manager_impl.h"
+#include "application_manager/message_helper.h"
+#include "application_manager/policies/policy_handler.h"
+
+namespace application_manager {
+
+namespace commands {
+
+OnAppPermissionConsent::OnAppPermissionConsent(const MessageSharedPtr& message)
+ : NotificationFromHMI(message) {
+}
+
+OnAppPermissionConsent::~OnAppPermissionConsent() {
+}
+
+void OnAppPermissionConsent::Run() {
+ LOG4CXX_INFO(logger_, "OnAppPermissionConsent::Run");
+ smart_objects::SmartObject& msg_params = (*message_)[strings::msg_params];
+
+ policy::PermissionConsent permission_consent;
+ // If user defined group permissions for specific app
+ if (msg_params.keyExists(strings::app_id)) {
+ permission_consent.policy_app_id = msg_params[strings::app_id].asString();
+
+ typedef std::set<Application*> ApplicationList;
+ const ApplicationList app_list =
+ application_manager::ApplicationManagerImpl::instance()->applications();
+
+ ApplicationList::const_iterator it_app_list = app_list.begin();
+ ApplicationList::const_iterator it_app_list_end = app_list.end();
+ for (; it_app_list != it_app_list_end; ++it_app_list) {
+ if (permission_consent.policy_app_id.compare(
+ (*it_app_list)->mobile_app_id()->asString()) == 0) {
+ policy::DeviceParams device_params;
+ application_manager::MessageHelper::GetDeviceInfoForHandle(
+ (*it_app_list)->device(),
+ &device_params);
+
+ permission_consent.device_id = device_params.device_mac_address;
+ }
+ }
+ }
+
+ smart_objects::SmartArray* user_consent =
+ msg_params["consentedFunctions"].asArray();
+
+ smart_objects::SmartArray::const_iterator it = user_consent->begin();
+ smart_objects::SmartArray::const_iterator it_end = user_consent->end();
+ for (; it != it_end; ++it) {
+ policy::FunctionalGroupPermission permissions;
+ permissions.group_id = (*it)["id"].asInt();
+ permissions.group_name = (*it)["name"].asString();
+ permissions.is_allowed = (*it)["allowed"].asBool();
+ permission_consent.group_permissions.push_back(permissions);
+ }
+
+ permission_consent.consent_source = msg_params["source"].asString();
+
+ policy::PolicyHandler::instance()->OnAppPermissionConsent(permission_consent);
+}
+
+} // namespace commands
+
+} // namespace application_manager
--- /dev/null
+/*
+ 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 <unistd.h>
+#include <dlfcn.h>
+#include <algorithm>
+#include "application_manager/policies/policy_handler.h"
+#include "application_manager/policies/policy_retry_sequence.h"
+#include "application_manager/policies/pt_exchange_handler_impl.h"
+#include "application_manager/policies/pt_exchange_handler_ext.h"
+#include "application_manager/application_manager_impl.h"
+#include "application_manager/message_helper.h"
+#include "policy/policy_manager_impl.h"
+#include "utils/macro.h"
+#include "utils/date_time.h"
+#include "json/value.h"
+#include "config_profile/profile.h"
+
+namespace policy {
+typedef std::set<application_manager::Application*> ApplicationList;
+
+PolicyHandler* PolicyHandler::instance_ = NULL;
+const std::string PolicyHandler::kLibrary = "libPolicy.so";
+
+log4cxx::LoggerPtr PolicyHandler::logger_ = log4cxx::LoggerPtr(
+ log4cxx::Logger::getLogger("PolicyHandler"));
+
+PolicyHandler::PolicyHandler()
+ : policy_manager_(0),
+ dl_handle_(0),
+ exchange_handler_(NULL),
+ is_exchange_in_progress_(false),
+ retry_sequence_("RetrySequence", new RetrySequence(this)) {
+}
+
+PolicyHandler::~PolicyHandler() {
+ UnloadPolicyLibrary();
+}
+
+PolicyManager* PolicyHandler::LoadPolicyLibrary() {
+ return LoadPolicyLibrary("./");
+}
+
+PolicyManager* PolicyHandler::LoadPolicyLibrary(const std::string& path) {
+ std::string filename = path + kLibrary;
+ dl_handle_ = dlopen(filename.c_str(), RTLD_LAZY);
+
+ char* error_string = dlerror();
+ if (error_string == NULL) {
+ policy_manager_ = CreateManager();
+ policy_manager_->set_listener(this);
+#if defined (EXTENDED_POLICY)
+ exchange_handler_ = new PTExchangeHandlerExt(this);
+#else
+ exchange_handler_ = new PTExchangeHandlerImpl(this);
+#endif
+ } else {
+ LOG4CXX_ERROR(logger_, error_string);
+ }
+
+ return policy_manager_;
+}
+
+PolicyManager* PolicyHandler::CreateManager() {
+ typedef PolicyManager* (*CreateManager)();
+ CreateManager create_manager = 0;
+ *(void**) (&create_manager) = dlsym(dl_handle_, "CreateManager");
+ char* error_string = dlerror();
+ if (error_string == NULL) {
+ policy_manager_ = (*create_manager)();
+ } else {
+ LOG4CXX_WARN(logger_, error_string);
+ }
+ return policy_manager_;
+}
+
+bool PolicyHandler::InitPolicyTable() {
+ std::string preloaded_file =
+ profile::Profile::instance()->preloaded_pt_file();
+ DCHECK(policy_manager_);
+ return policy_manager_->LoadPTFromFile(preloaded_file);
+}
+
+bool PolicyHandler::RevertPolicyTable() {
+ LOG4CXX_INFO(logger_, "Removing user consent records in policy table.");
+ DCHECK(policy_manager_);
+ return policy_manager()->ResetUserConsent();
+}
+
+uint32_t PolicyHandler::GetAppIdForSending() {
+ // Get app.list
+ const ApplicationList app_list =
+ application_manager::ApplicationManagerImpl::instance()->applications();
+
+ if (app_list.empty()) {
+ return 0;
+ }
+
+ // Choose application
+ uint32_t selected_app_id = 0;
+ AppIds app_ids_last_resort;
+ AppIds app_ids_preferred;
+
+ ApplicationList::const_iterator it_app_list = app_list.begin();
+ ApplicationList::const_iterator it_app_list_end = app_list.end();
+ for (; it_app_list != it_app_list_end; ++it_app_list) {
+ switch ((*it_app_list)->hmi_level()) {
+ case mobile_apis::HMILevel::HMI_NONE:
+ app_ids_last_resort.push_back((*it_app_list)->app_id());
+ break;
+ default:
+ app_ids_preferred.push_back((*it_app_list)->app_id());
+ break;
+ }
+ }
+
+ AppIds& app_ids_to_use =
+ app_ids_preferred.empty() ? app_ids_last_resort : app_ids_preferred;
+
+ // Checking, if some of currently known apps was not used already
+ std::sort(last_used_app_ids_.begin(), last_used_app_ids_.end());
+ std::sort(app_ids_to_use.begin(), app_ids_to_use.end());
+
+ bool is_all_used = std::includes(last_used_app_ids_.begin(),
+ last_used_app_ids_.end(),
+ app_ids_to_use.begin(),
+ app_ids_to_use.end());
+
+ if (is_all_used) {
+ last_used_app_ids_.clear();
+ }
+
+ // Leave only unused apps
+ AppIds::iterator it_apps_to_use = app_ids_to_use.begin();
+ AppIds::iterator it_apps_to_use_end = app_ids_to_use.end();
+
+ AppIds::const_iterator it_last_used_app_ids =
+ last_used_app_ids_.begin();
+ AppIds::const_iterator it_last_used_app_ids_end =
+ last_used_app_ids_.end();
+
+ for (; it_last_used_app_ids != it_last_used_app_ids_end;
+ ++it_last_used_app_ids) {
+
+ std::remove(it_apps_to_use, it_apps_to_use_end,
+ *it_last_used_app_ids);
+ }
+
+ // Random selection of filtered apps
+ std::srand(time(0));
+ selected_app_id = *(app_ids_to_use.begin()
+ + (rand() % app_ids_to_use.size()));
+
+ last_used_app_ids_.push_back(selected_app_id);
+ return selected_app_id;
+}
+
+DeviceConsent PolicyHandler::GetDeviceForSending(DeviceParams& device_params) {
+ uint32_t app_id = 0;
+ uint32_t app_id_previous = 0;
+ while (true) {
+ app_id = GetAppIdForSending();
+ if (!app_id) {
+ LOG4CXX_WARN(logger_,
+ "There is no appropriate application for sending PTS.");
+ return kDeviceDisallowed;
+ }
+
+ // If only one application is available, return its device params
+ if (app_id == app_id_previous) {
+ return kDeviceDisallowed;
+ }
+
+ app_id_previous = app_id;
+
+ char buffer[16];
+ snprintf(buffer, 16, "%d", app_id);
+ application_manager::MessageHelper::GetDeviceInfoForApp(std::string(buffer),
+ &device_params);
+
+ DeviceConsent consent =
+ policy_manager_->GetUserConsentForDevice(device_params.device_mac_address);
+ switch (consent) {
+ case kDeviceAllowed:
+ return consent;
+ case kDeviceDisallowed:
+ continue;
+ case kDeviceHasNoConsent:
+ return consent;
+ default:
+ LOG4CXX_WARN(logger_, "Consent result is not impelemented.");
+ return consent;
+ }
+ }
+ return kDeviceDisallowed;
+}
+
+void PolicyHandler::SetDeviceInfo(std::string& device_id,
+ const DeviceInfo& device_info) {
+ LOG4CXX_INFO(logger_, "SetDeviceInfo");
+ policy_manager_->SetDeviceInfo(device_id, device_info);
+}
+
+void PolicyHandler::OnAppPermissionConsent(
+ const PermissionConsent& permissions) {
+ LOG4CXX_INFO(logger_, "OnAppPermissionConsent");
+ DCHECK(policy_manager_);
+ if (!permissions.policy_app_id.empty()) {
+ policy_manager_->SetUserConsentForApp(permissions);
+ }
+
+ //TODO(AOleynik): Handle situation for all apps (policy_app_id is empty)
+}
+
+void PolicyHandler::OnAppRevoked(const std::string& policy_app_id) {
+ LOG4CXX_INFO(logger_, "OnAppRevoked");
+ const ApplicationList app_list =
+ application_manager::ApplicationManagerImpl::instance()->applications();
+ ApplicationList::const_iterator it = app_list.begin();
+ ApplicationList::const_iterator it_end = app_list.end();
+ for (; it != it_end; ++it) {
+ if ((*(*it)).mobile_app_id()->asString() == policy_app_id) {
+ LOG4CXX_INFO(logger_,
+ "Application_id " << policy_app_id << " is revoked.");
+ AppPermissions permissions(atoi(policy_app_id.c_str()));
+ permissions.appRevoked = true;
+ application_manager::MessageHelper::SendOnAppPermissionsChangedNotification(
+ (*it)->app_id(), permissions);
+ application_manager::ApplicationManagerImpl::instance()
+ ->DeactivateApplication(*it);
+ (*(*it)).set_hmi_level(mobile_apis::HMILevel::HMI_NONE);
+ return;
+ }
+ }
+ LOG4CXX_WARN(logger_,
+ "Application_id " << policy_app_id << " is not registered.");
+}
+
+bool PolicyHandler::SendMessageToSDK(const BinaryMessage& pt_string) {
+ LOG4CXX_INFO(logger_, "PolicyHandler::SendMessageToSDK");
+
+ is_exchange_in_progress_ = true;
+
+ std::string url;
+ uint32_t app_id = last_used_app_ids_.back();
+ if (policy_manager_) {
+ const std::string& mobile_app_id =
+ application_manager::ApplicationManagerImpl::instance()->application(
+ app_id)->mobile_app_id()->asString();
+ url = policy_manager_->GetUpdateUrl(mobile_app_id);
+ }
+ LOG4CXX_INFO(
+ logger_,
+ "Update url is " << url << " for application " << application_manager::ApplicationManagerImpl::instance()-> application(app_id)->name());
+
+ application_manager::MessageHelper::SendPolicySnapshotNotification(app_id,
+ pt_string,
+ url, 0);
+ return true;
+}
+
+bool PolicyHandler::ReceiveMessageFromSDK(const BinaryMessage& pt_string) {
+ if (!policy_manager_) {
+ LOG4CXX_WARN(logger_, "The shared library of policy is not loaded");
+ return false;
+ }
+
+ is_exchange_in_progress_ = false;
+
+ bool ret = policy_manager_->LoadPT(pt_string);
+ LOG4CXX_INFO(logger_, "Policy table is saved: " << std::boolalpha << ret);
+ if (ret) {
+ LOG4CXX_INFO(logger_, "PTU was successful.");
+ retry_sequence_lock_.Ackquire();
+ retry_sequence_.stop();
+ retry_sequence_lock_.Release();
+ int32_t correlation_id =
+ application_manager::ApplicationManagerImpl::instance()
+ ->GetNextHMICorrelationID();
+ event_observer_ = new PolicyEventObserver(policy_manager_);
+ event_observer_.get()->subscribe_on_event(
+ hmi_apis::FunctionID::VehicleInfo_GetVehicleData, correlation_id);
+ application_manager::MessageHelper::CreateGetDeviceData(correlation_id);
+ // TODO(KKolodiy): when we must reset counter of ignition cyles, update days
+ // and kms?
+ }
+ return ret;
+}
+
+bool PolicyHandler::UnloadPolicyLibrary() {
+ bool ret = true;
+ delete policy_manager_;
+ policy_manager_ = 0;
+ if (dl_handle_) {
+ ret = (dlclose(dl_handle_) == 0);
+ dl_handle_ = 0;
+ }
+ return ret;
+}
+
+void PolicyHandler::StartPTExchange(bool skip_device_selection) {
+ LOG4CXX_INFO(logger_, "PolicyHandler::StartPTExchange");
+ if (!policy_manager_) {
+ LOG4CXX_WARN(logger_, "The shared library of policy is not loaded");
+ return;
+ }
+
+ if (is_exchange_in_progress_) {
+ LOG4CXX_INFO(logger_, "Starting exchange skipped, since another exchange "
+ "is in progress.");
+ return;
+ }
+
+ if (!skip_device_selection) {
+ DeviceParams device_params;
+ DeviceConsent consent = GetDeviceForSending(device_params);
+ switch (consent) {
+ case kDeviceHasNoConsent:
+ // Send OnSDLConsentNeeded to HMI for user consent on device usage
+ pending_device_handles_.push_back(device_params.device_handle);
+ application_manager::MessageHelper::SendOnSDLConsentNeeded(device_params);
+ return;
+ case kDeviceDisallowed:
+ return;
+ default:
+ break;
+ }
+ }
+
+ // TODO(KKolodiy): when we must reset counter of ignition cyles,
+ // update days and kms?
+
+ retry_sequence_lock_.Ackquire();
+ retry_sequence_.stop();
+ policy_manager_->ResetRetrySequence();
+ retry_sequence_.start();
+ retry_sequence_lock_.Release();
+}
+
+void PolicyHandler::StartNextRetry() {
+ DCHECK(exchange_handler_);
+ exchange_handler_->StartExchange();
+}
+
+void PolicyHandler::OnAllowSDLFunctionalityNotification(bool is_allowed,
+ uint32_t device_id) {
+ LOG4CXX_INFO(logger_, "OnAllowSDLFunctionalityNotification");
+ if (device_id) {
+ DeviceParams device_params;
+ application_manager::MessageHelper::GetDeviceInfoForHandle(device_id,
+ &device_params);
+ policy_manager_->SetUserConsentForDevice(device_params.device_mac_address,
+ is_allowed);
+
+ DeviceHandles::iterator it = std::find(pending_device_handles_.begin(),
+ pending_device_handles_.end(),
+ device_id);
+ // If consent done from HMI menu
+ if (it == pending_device_handles_.end()) {
+ return;
+ }
+
+ pending_device_handles_.erase(it);
+ if (is_allowed) {
+ // Skip device selection, since user already consented device usage
+ StartPTExchange(true);
+ }
+
+ return;
+ }
+
+ // TODO(AOleynik): Handle situation, if general functionality is concerned
+}
+
+void PolicyHandler::SendAllowApp(const PermissionsList& list_of_permissions,
+ uint32_t application_id) {
+ LOG4CXX_INFO(logger_,
+ "Sending allow request for application id:" << application_id);
+ // TODO(PV): change
+ /*application_manager::MessageHelper::SendAllowAppRequest(list_of_permissions,
+ application_id);*/
+}
+
+void PolicyHandler::OnAllowAppResponse(PermissionsList& list_of_permissions) {
+ // TODO(AOleynik): Impelement response processing for user-defined permissions
+ // for application
+}
+
+void PolicyHandler::OnAllowAppNotification(PermissionsList& list_of_permissions,
+ uint32_t appication_id) {
+ // TODO(AOleynik): Implement notification processing for user-defined
+ // permissions for applicaiton
+}
+
+void PolicyHandler::OnIgnitionCycleOver() {
+ LOG4CXX_INFO(logger_, "OnIgnitionCycleOver");
+ policy_manager_->IncrementIgnitionCycles();
+}
+
+void PolicyHandler::KmsChanged(int kms) {
+ LOG4CXX_INFO(logger_, "PolicyHandler::KmsChanged " << kms << " kilometers");
+ PTExchangeAtOdometer(kms);
+}
+
+void PolicyHandler::OnActivateApp(const std::string& policy_app_id,
+ uint32_t correlation_id) {
+ LOG4CXX_INFO(logger_, "OnActivateApp");
+ if (!policy_manager_) {
+ LOG4CXX_WARN(logger_, "The shared library of policy is not loaded");
+ return;
+ }
+ // Should be gathered:
+ // - isSDLAllowed, i.e. device data usage consent
+
+ AppPermissions permissions(atoi(policy_app_id.c_str()));
+ DeviceConsent consent = GetDeviceForSending(permissions.deviceInfo);
+ permissions.isSDLAllowed = kDeviceAllowed == consent ? true : false;
+
+ // If isSDLAllowed is false, we should provide device params for user consent
+ if (!permissions.isSDLAllowed) {
+ pending_device_handles_.push_back(permissions.deviceInfo.device_handle);
+ }
+
+ // TODO(AOleynik): Fill following:
+ // - isPermissionsConsentNeeded, i.e. specific application permissions
+ // - isAppPermissionsRevoked
+ // - isAppRevoked
+
+ application_manager::MessageHelper::SendActivateAppResponse(permissions,
+ correlation_id);
+}
+
+void PolicyHandler::PTExchangeAtIgnition() {
+ LOG4CXX_INFO(logger_, "PTExchangeAtIgnition");
+ if (!policy_manager_) {
+ LOG4CXX_WARN(logger_, "The shared library of policy is not loaded");
+ return;
+ }
+
+ TimevalStruct current_time = date_time::DateTime::getCurrentTime();
+ const int kSecondsInDay = 60 * 60 * 24;
+ int days = current_time.tv_sec / kSecondsInDay;
+
+ // Start update on limits exhaustion, if update wasn't started already by any
+ // other event
+ LOG4CXX_INFO(
+ logger_,
+ "\nIgnition cycles exceeded: " << std::boolalpha << policy_manager_->ExceededIgnitionCycles() << "\nDays exceeded: " << std::boolalpha << policy_manager_->ExceededDays(days) << "\nStatusUpdateRequired: " << std::boolalpha << (policy_manager_->GetPolicyTableStatus() == StatusUpdateRequired));
+ if (policy_manager_->ExceededIgnitionCycles()
+ || policy_manager_->ExceededDays(days)
+ || policy_manager_->GetPolicyTableStatus() == StatusUpdateRequired) {
+ StartPTExchange();
+ }
+}
+
+void PolicyHandler::PTExchangeAtOdometer(int kilometers) {
+ if (!policy_manager_) {
+ LOG4CXX_WARN(logger_, "The shared library of policy is not loaded");
+ return;
+ }
+ if (policy_manager_->ExceededKilometers(kilometers)) {
+ LOG4CXX_INFO(logger_, "Enough kilometers passed to send for PT update.");
+ StartPTExchange();
+ }
+}
+
+void PolicyHandler::OnPTExchangeNeeded() {
+ StartPTExchange();
+}
+
+void PolicyHandler::OnPermissionsUpdated(const std::string& policy_app_id,
+ const Permissions& permissions) {
+ const ApplicationList app_list =
+ application_manager::ApplicationManagerImpl::instance()->applications();
+
+ // Find appropriate connection_key for application_id
+ ApplicationList::const_iterator it_app_list = app_list.begin();
+ ApplicationList::const_iterator it_app_list_end = app_list.end();
+ for (; it_app_list != it_app_list_end; ++it_app_list) {
+ if (policy_app_id.compare((*it_app_list)->mobile_app_id()->asString())
+ == 0) {
+ application_manager::MessageHelper::SendOnPermissionsChangeNotification(
+ (*it_app_list)->app_id(), permissions);
+
+ LOG4CXX_INFO(
+ logger_,
+ "Notification sent for application_id:" << policy_app_id << " and connection_key " << (*it_app_list)->app_id());
+
+ return;
+ }
+ }
+
+ LOG4CXX_WARN(logger_,
+ "Connection_key not found for application_id:" << policy_app_id);
+}
+
+void PolicyHandler::CheckAppPolicyState(const std::string& application_id) {
+ LOG4CXX_INFO(logger_, "CheckAppPolicyState");
+ policy_manager()->CheckAppPolicyState(application_id);
+}
+
+} // namespace policy