summaryrefslogtreecommitdiff
path: root/src/components/application_manager/src/application_manager_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/application_manager/src/application_manager_impl.cc')
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc345
1 files changed, 230 insertions, 115 deletions
diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc
index 6b0ea39804..948f7944d4 100644
--- a/src/components/application_manager/src/application_manager_impl.cc
+++ b/src/components/application_manager/src/application_manager_impl.cc
@@ -145,10 +145,6 @@ struct PolicyAppIdComparator {
const std::string& policy_app_id_;
};
-uint32_t ApplicationManagerImpl::mobile_corelation_id_ = 0;
-uint32_t ApplicationManagerImpl::corelation_id_ = 0;
-const uint32_t ApplicationManagerImpl::max_corelation_id_ = UINT_MAX;
-
namespace formatters = ns_smart_device_link::ns_json_handler::formatters;
namespace jhs = ns_smart_device_link::ns_json_handler::strings;
@@ -162,6 +158,7 @@ ApplicationManagerImpl::ApplicationManagerImpl(
std::make_shared<sync_primitives::RecursiveLock>())
, apps_to_register_list_lock_ptr_(std::make_shared<sync_primitives::Lock>())
, reregister_wait_list_lock_ptr_(std::make_shared<sync_primitives::Lock>())
+ , subscribed_to_hmi_way_points_(false)
, audio_pass_thru_active_(false)
, audio_pass_thru_app_id_(0)
, driver_distraction_state_(hmi_apis::Common_DriverDistractionState::DD_OFF)
@@ -174,8 +171,9 @@ ApplicationManagerImpl::ApplicationManagerImpl(
, policy_handler_(new policy::PolicyHandler(policy_settings, *this))
, protocol_handler_(NULL)
, request_ctrl_(am_settings)
- , hmi_so_factory_(NULL)
- , mobile_so_factory_(NULL)
+ , mobile_correlation_id_(0)
+ , correlation_id_(0)
+ , max_correlation_id_(UINT_MAX)
, hmi_capabilities_(new HMICapabilitiesImpl(*this))
, unregister_reason_(
mobile_api::AppInterfaceUnregisteredReason::INVALID_ENUM)
@@ -229,19 +227,11 @@ ApplicationManagerImpl::ApplicationManagerImpl(
ApplicationManagerImpl::~ApplicationManagerImpl() {
SDL_LOG_AUTO_TRACE();
- is_stopping_.store(true);
+ InitiateStopping();
SendOnSDLClose();
media_manager_ = NULL;
hmi_handler_ = NULL;
connection_handler_ = NULL;
- if (hmi_so_factory_) {
- delete hmi_so_factory_;
- hmi_so_factory_ = NULL;
- }
- if (mobile_so_factory_) {
- delete mobile_so_factory_;
- mobile_so_factory_ = NULL;
- }
protocol_handler_ = NULL;
SDL_LOG_DEBUG("Destroying Policy Handler");
RemovePolicyObserver(this);
@@ -673,17 +663,8 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication(
static_cast<protocol_handler::MajorProtocolVersion>(
message[strings::params][strings::protocol_version].asInt());
application->set_protocol_version(protocol_version);
-
- if (protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_UNKNOWN !=
- protocol_version) {
- connection_handler().BindProtocolVersionWithSession(
- connection_key, static_cast<uint8_t>(protocol_version));
- }
- if ((protocol_version ==
- protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_3) &&
- (get_settings().heart_beat_timeout() != 0)) {
- connection_handler().StartSessionHeartBeat(connection_key);
- }
+ connection_handler_->BindProtocolVersionWithSession(connection_key,
+ protocol_version);
// Keep HMI add id in case app is present in "waiting for registration" list
apps_to_register_list_lock_ptr_->Acquire();
@@ -1382,23 +1363,23 @@ ApplicationManagerImpl::GetCloudAppConnectionStatus(
}
uint32_t ApplicationManagerImpl::GetNextMobileCorrelationID() {
- if (mobile_corelation_id_ < max_corelation_id_) {
- mobile_corelation_id_++;
+ if (mobile_correlation_id_ < max_correlation_id_) {
+ mobile_correlation_id_++;
} else {
- mobile_corelation_id_ = 0;
+ mobile_correlation_id_ = 0;
}
- return mobile_corelation_id_;
+ return mobile_correlation_id_;
}
uint32_t ApplicationManagerImpl::GetNextHMICorrelationID() {
- if (corelation_id_ < max_corelation_id_) {
- corelation_id_++;
+ if (correlation_id_ < max_correlation_id_) {
+ correlation_id_++;
} else {
- corelation_id_ = 0;
+ correlation_id_ = 0;
}
- return corelation_id_;
+ return correlation_id_;
}
bool ApplicationManagerImpl::BeginAudioPassThru(uint32_t app_id) {
@@ -1616,6 +1597,58 @@ void ApplicationManagerImpl::OnDeviceListUpdated(
RefreshCloudAppInformation();
}
+bool ApplicationManagerImpl::WaitForHmiIsReady() {
+ sync_primitives::AutoLock lock(wait_for_hmi_lock_);
+ if (!IsStopping() && !IsHMICooperating()) {
+ SDL_LOG_DEBUG("Waiting for the HMI cooperation...");
+ wait_for_hmi_condvar_.Wait(lock);
+ }
+
+ if (IsStopping()) {
+ SDL_LOG_WARN("System is terminating...");
+ return false;
+ }
+
+ return IsHMICooperating();
+}
+
+bool ApplicationManagerImpl::GetProtocolVehicleData(
+ connection_handler::ProtocolVehicleData& data) {
+ SDL_LOG_AUTO_TRACE();
+ using namespace protocol_handler::strings;
+
+ if (!WaitForHmiIsReady()) {
+ SDL_LOG_ERROR("Failed to wait for HMI readiness");
+ return false;
+ }
+
+ const auto vehicle_type_ptr = hmi_capabilities_->vehicle_type();
+ if (vehicle_type_ptr) {
+ if (vehicle_type_ptr->keyExists(vehicle_make)) {
+ data.vehicle_make = vehicle_type_ptr->getElement(vehicle_make).asString();
+ }
+
+ if (vehicle_type_ptr->keyExists(vehicle_model)) {
+ data.vehicle_model =
+ vehicle_type_ptr->getElement(vehicle_model).asString();
+ }
+
+ if (vehicle_type_ptr->keyExists(vehicle_model_year)) {
+ data.vehicle_year =
+ vehicle_type_ptr->getElement(vehicle_model_year).asString();
+ }
+
+ if (vehicle_type_ptr->keyExists(vehicle_trim)) {
+ data.vehicle_trim = vehicle_type_ptr->getElement(vehicle_trim).asString();
+ }
+ }
+
+ data.vehicle_system_software_version = hmi_capabilities_->ccpu_version();
+ data.vehicle_system_hardware_version = hmi_capabilities_->hardware_version();
+
+ return true;
+}
+
void ApplicationManagerImpl::OnFindNewApplicationsRequest() {
connection_handler().ConnectToAllDevices();
SDL_LOG_DEBUG("Starting application list update timer");
@@ -1731,11 +1764,11 @@ void ApplicationManagerImpl::SwitchApplication(ApplicationSharedPtr app,
bool is_subscribed_to_way_points = IsAppSubscribedForWayPoints(*app);
if (is_subscribed_to_way_points) {
- UnsubscribeAppFromWayPoints(app);
+ UnsubscribeAppFromWayPoints(app, false);
}
SwitchApplicationParameters(app, connection_key, device_id, mac_address);
if (is_subscribed_to_way_points) {
- SubscribeAppForWayPoints(app);
+ SubscribeAppForWayPoints(app, false);
}
// Normally this is done during registration, however since switched apps are
@@ -2555,7 +2588,7 @@ bool ApplicationManagerImpl::Init(
bool ApplicationManagerImpl::Stop() {
SDL_LOG_AUTO_TRACE();
- is_stopping_.store(true);
+ InitiateStopping();
application_list_update_timer_.Stop();
try {
if (unregister_reason_ ==
@@ -2681,25 +2714,16 @@ bool ApplicationManagerImpl::ConvertSOtoMessage(
}
hmi_apis::HMI_API& ApplicationManagerImpl::hmi_so_factory() {
- if (!hmi_so_factory_) {
- hmi_so_factory_ = new hmi_apis::HMI_API;
- if (!hmi_so_factory_) {
- SDL_LOG_ERROR("Out of memory");
- NOTREACHED();
- }
- }
- return *hmi_so_factory_;
+ return hmi_so_factory_;
}
mobile_apis::MOBILE_API& ApplicationManagerImpl::mobile_so_factory() {
- if (!mobile_so_factory_) {
- mobile_so_factory_ = new mobile_apis::MOBILE_API;
- if (!mobile_so_factory_) {
- SDL_LOG_ERROR("Out of memory");
- NOTREACHED();
- }
- }
- return *mobile_so_factory_;
+ return mobile_so_factory_;
+}
+
+ns_smart_device_link_rpc::V1::v4_protocol_v1_2_no_extra&
+ApplicationManagerImpl::mobile_v4_protocol_so_factory() {
+ return mobile_v4_protocol_so_factory_;
}
HMICapabilities& ApplicationManagerImpl::hmi_capabilities() {
@@ -2979,7 +3003,7 @@ void ApplicationManagerImpl::SetUnregisterAllApplicationsReason(
void ApplicationManagerImpl::HeadUnitReset(
mobile_api::AppInterfaceUnregisteredReason::eType reason) {
SDL_LOG_AUTO_TRACE();
- is_stopping_.store(true);
+ InitiateStopping();
switch (reason) {
case mobile_api::AppInterfaceUnregisteredReason::MASTER_RESET: {
SDL_LOG_TRACE("Performing MASTER_RESET");
@@ -3231,6 +3255,7 @@ void ApplicationManagerImpl::UnregisterApplication(
}
ApplicationSharedPtr app_to_remove;
connection_handler::DeviceHandle handle = 0;
+
{
sync_primitives::AutoLock lock(applications_list_lock_ptr_);
auto it_app = applications_.begin();
@@ -3243,64 +3268,65 @@ void ApplicationManagerImpl::UnregisterApplication(
++it_app;
}
}
- if (!app_to_remove) {
- SDL_LOG_ERROR("Cant find application with app_id = " << app_id);
-
- // Just to terminate RAI in case of connection is dropped (rare case)
- // App won't be unregistered since RAI has not been started yet
- SDL_LOG_DEBUG("Trying to terminate possible RAI request.");
- request_ctrl_.terminateAppRequests(app_id);
-
- return;
- }
+ }
+ if (!app_to_remove) {
+ SDL_LOG_ERROR("Cant find application with app_id = " << app_id);
- if (is_resuming) {
- resume_controller().SaveApplication(app_to_remove);
- } else {
- resume_controller().RemoveApplicationFromSaved(app_to_remove);
- }
+ // Just to terminate RAI in case of connection is dropped (rare case)
+ // App won't be unregistered since RAI has not been started yet
+ SDL_LOG_DEBUG("Trying to terminate possible RAI request.");
+ request_ctrl_.terminateAppRequests(app_id);
- if (IsAppSubscribedForWayPoints(app_id)) {
- UnsubscribeAppFromWayPoints(app_id);
- if (!IsAnyAppSubscribedForWayPoints()) {
- SDL_LOG_DEBUG("Send UnsubscribeWayPoints");
- auto request = MessageHelper::CreateUnsubscribeWayPointsRequest(
- GetNextHMICorrelationID());
- rpc_service_->ManageHMICommand(request);
- }
- }
+ return;
+ }
- (hmi_capabilities_->get_hmi_language_handler())
- .OnUnregisterApplication(app_id);
+ resume_controller().RemoveFromResumption(app_id);
- if (connection_handler().GetDeviceID(app_to_remove->mac_address(),
- &handle)) {
- AppV4DevicePredicate finder(handle);
- ApplicationSharedPtr app = FindApp(applications(), finder);
- if (!app) {
- SDL_LOG_DEBUG(
- "There is no more SDL4 apps with device handle: " << handle);
+ if (is_resuming) {
+ resume_controller().SaveApplication(app_to_remove);
+ } else {
+ resume_controller().RemoveApplicationFromSaved(app_to_remove);
+ }
- RemoveAppsWaitingForRegistration(handle);
- }
+ if (IsAppSubscribedForWayPoints(app_id)) {
+ UnsubscribeAppFromWayPoints(app_id, true);
+ if (!IsAnyAppSubscribedForWayPoints()) {
+ SDL_LOG_DEBUG("Send UnsubscribeWayPoints");
+ auto request = MessageHelper::CreateUnsubscribeWayPointsRequest(
+ GetNextHMICorrelationID());
+ rpc_service_->ManageHMICommand(request);
}
+ }
- MessageHelper::SendOnAppUnregNotificationToHMI(
- app_to_remove, is_unexpected_disconnect, *this);
- commands_holder_->Clear(app_to_remove);
+ (hmi_capabilities_->get_hmi_language_handler())
+ .OnUnregisterApplication(app_id);
- const auto enabled_local_apps = policy_handler_->GetEnabledLocalApps();
- if (helpers::in_range(enabled_local_apps, app_to_remove->policy_app_id())) {
+ if (connection_handler().GetDeviceID(app_to_remove->mac_address(), &handle)) {
+ AppV4DevicePredicate finder(handle);
+ ApplicationSharedPtr app = FindApp(applications(), finder);
+ if (!app) {
SDL_LOG_DEBUG(
- "Enabled local app has been unregistered. Re-create "
- "pending application");
- CreatePendingLocalApplication(app_to_remove->policy_app_id());
+ "There is no more SDL4 apps with device handle: " << handle);
+
+ RemoveAppsWaitingForRegistration(handle);
}
+ }
- RefreshCloudAppInformation();
- SendUpdateAppList();
+ MessageHelper::SendOnAppUnregNotificationToHMI(
+ app_to_remove, is_unexpected_disconnect, *this);
+ commands_holder_->Clear(app_to_remove);
+
+ const auto enabled_local_apps = policy_handler_->GetEnabledLocalApps();
+ if (helpers::in_range(enabled_local_apps, app_to_remove->policy_app_id())) {
+ SDL_LOG_DEBUG(
+ "Enabled local app has been unregistered. Re-create "
+ "pending application");
+ CreatePendingLocalApplication(app_to_remove->policy_app_id());
}
+ RefreshCloudAppInformation();
+ SendUpdateAppList();
+
if (EndAudioPassThru(app_id)) {
// May be better to put this code in MessageHelper?
StopAudioPassThru(app_id);
@@ -3583,6 +3609,27 @@ void ApplicationManagerImpl::ForbidStreaming(
}
void ApplicationManagerImpl::OnAppStreaming(
+ uint32_t app_id, protocol_handler::ServiceType service_type, bool state) {
+ SDL_LOG_AUTO_TRACE();
+
+ ApplicationSharedPtr app = application(app_id);
+ if (!app || (!app->is_navi() && !app->mobile_projection_enabled())) {
+ SDL_LOG_DEBUG(
+ " There is no navi or projection application with id: " << app_id);
+ return;
+ }
+ DCHECK_OR_RETURN_VOID(media_manager_);
+
+ if (state) {
+ state_ctrl_.OnVideoStreamingStarted(app);
+ media_manager_->StartStreaming(app_id, service_type);
+ } else {
+ media_manager_->StopStreaming(app_id, service_type);
+ state_ctrl_.OnVideoStreamingStopped(app);
+ }
+}
+
+void ApplicationManagerImpl::OnAppStreaming(
uint32_t app_id,
protocol_handler::ServiceType service_type,
const Application::StreamingState new_state) {
@@ -4132,7 +4179,17 @@ bool ApplicationManagerImpl::IsHMICooperating() const {
}
void ApplicationManagerImpl::SetHMICooperating(const bool hmi_cooperating) {
+ SDL_LOG_AUTO_TRACE();
+ sync_primitives::AutoLock lock(wait_for_hmi_lock_);
hmi_cooperating_ = hmi_cooperating;
+ wait_for_hmi_condvar_.Broadcast();
+}
+
+void ApplicationManagerImpl::InitiateStopping() {
+ SDL_LOG_AUTO_TRACE();
+ sync_primitives::AutoLock lock(wait_for_hmi_lock_);
+ is_stopping_.store(true);
+ wait_for_hmi_condvar_.Broadcast();
}
void ApplicationManagerImpl::OnApplicationListUpdateTimer() {
@@ -4266,6 +4323,10 @@ ResetGlobalPropertiesResult ApplicationManagerImpl::ResetGlobalProperties(
result.keyboard_properties = true;
break;
}
+ case mobile_apis::GlobalProperty::USER_LOCATION: {
+ result.user_location = true;
+ break;
+ }
default: {
SDL_LOG_TRACE("Unknown global property: " << global_property);
break;
@@ -4316,7 +4377,9 @@ ApplicationManagerImpl::CreateAllAppGlobalPropsIDList(
if (application->keyboard_props()) {
(*global_properties)[i++] = GlobalProperty::KEYBOARDPROPERTIES;
}
-
+ if (!application->get_user_location().empty()) {
+ (*global_properties)[i++] = GlobalProperty::USER_LOCATION;
+ }
return global_properties;
}
@@ -4725,42 +4788,69 @@ bool ApplicationManagerImpl::IsAppSubscribedForWayPoints(
return IsAppSubscribedForWayPoints(app.app_id());
}
-void ApplicationManagerImpl::SubscribeAppForWayPoints(uint32_t app_id) {
+void ApplicationManagerImpl::SubscribeAppForWayPoints(uint32_t app_id,
+ bool response_from_hmi) {
SDL_LOG_AUTO_TRACE();
sync_primitives::AutoLock lock(subscribed_way_points_apps_lock_);
SDL_LOG_DEBUG("Subscribing " << app_id);
subscribed_way_points_apps_list_.insert(app_id);
+ if (response_from_hmi) {
+ subscribed_to_hmi_way_points_ = true;
+ }
SDL_LOG_DEBUG("There are applications subscribed: "
<< subscribed_way_points_apps_list_.size());
- if (way_points_data_) {
- smart_objects::SmartObjectSPtr way_point_notification_ =
- std::make_shared<smart_objects::SmartObject>(*way_points_data_);
- (*way_point_notification_)[strings::params][strings::connection_key] =
+ if (GetAppServiceManager().FindWayPointsHandler() != nullptr) {
+ auto service = GetAppServiceManager().ActiveServiceForType(
+ EnumToString(mobile_apis::AppServiceType::NAVIGATION));
+ auto it = mobile_way_points_data_.find(service->connection_key);
+ if (mobile_way_points_data_.end() == it) {
+ SDL_LOG_DEBUG("No waypoint data provided by app service provider yet");
+ return;
+ }
+ smart_objects::SmartObjectSPtr way_point_notification =
+ std::make_shared<smart_objects::SmartObject>(it->second);
+ (*way_point_notification)[strings::params][strings::connection_key] =
+ app_id;
+ GetRPCService().SendMessageToMobile(way_point_notification);
+ } else if (hmi_way_points_data_) {
+ smart_objects::SmartObjectSPtr way_point_notification =
+ std::make_shared<smart_objects::SmartObject>(*hmi_way_points_data_);
+ (*way_point_notification)[strings::params][strings::connection_key] =
app_id;
- GetRPCService().SendMessageToMobile(way_point_notification_);
+ GetRPCService().SendMessageToMobile(way_point_notification);
}
}
-void ApplicationManagerImpl::SubscribeAppForWayPoints(
- ApplicationSharedPtr app) {
- SubscribeAppForWayPoints(app->app_id());
+void ApplicationManagerImpl::SubscribeAppForWayPoints(ApplicationSharedPtr app,
+ bool response_from_hmi) {
+ SubscribeAppForWayPoints(app->app_id(), response_from_hmi);
}
-void ApplicationManagerImpl::UnsubscribeAppFromWayPoints(uint32_t app_id) {
+void ApplicationManagerImpl::UnsubscribeAppFromWayPoints(
+ uint32_t app_id, bool response_from_hmi) {
SDL_LOG_AUTO_TRACE();
sync_primitives::AutoLock lock(subscribed_way_points_apps_lock_);
SDL_LOG_DEBUG("Unsubscribing " << app_id);
subscribed_way_points_apps_list_.erase(app_id);
+ if (response_from_hmi) {
+ subscribed_to_hmi_way_points_ = false;
+ }
SDL_LOG_DEBUG("There are applications subscribed: "
<< subscribed_way_points_apps_list_.size());
if (subscribed_way_points_apps_list_.empty()) {
- way_points_data_.reset();
+ hmi_way_points_data_.reset();
+ mobile_way_points_data_.clear();
}
}
void ApplicationManagerImpl::UnsubscribeAppFromWayPoints(
- ApplicationSharedPtr app) {
- UnsubscribeAppFromWayPoints(app->app_id());
+ ApplicationSharedPtr app, bool response_from_hmi) {
+ UnsubscribeAppFromWayPoints(app->app_id(), response_from_hmi);
+}
+
+bool ApplicationManagerImpl::IsSubscribedToHMIWayPoints() const {
+ SDL_LOG_AUTO_TRACE();
+ return subscribed_to_hmi_way_points_;
}
bool ApplicationManagerImpl::IsAnyAppSubscribedForWayPoints() const {
@@ -4772,9 +4862,17 @@ bool ApplicationManagerImpl::IsAnyAppSubscribedForWayPoints() const {
}
void ApplicationManagerImpl::SaveWayPointsMessage(
- std::shared_ptr<smart_objects::SmartObject> way_points_message) {
+ std::shared_ptr<smart_objects::SmartObject> way_points_message,
+ uint32_t app_id) {
sync_primitives::AutoLock lock(subscribed_way_points_apps_lock_);
- way_points_data_ = way_points_message;
+ // Notification from HMI
+ if (0 == app_id) {
+ hmi_way_points_data_ = way_points_message;
+ }
+ // Notification from app service provider
+ else {
+ mobile_way_points_data_[app_id] = *way_points_message;
+ }
}
const std::set<uint32_t> ApplicationManagerImpl::GetAppsSubscribedForWayPoints()
@@ -4890,6 +4988,23 @@ bool ApplicationManagerImpl::IsSOStructValid(
return false;
}
+bool ApplicationManagerImpl::UnsubscribeAppFromSoftButtons(
+ const commands::MessageSharedPtr response) {
+ using namespace mobile_apis;
+
+ const uint32_t connection_key =
+ (*response)[strings::params][strings::connection_key].asUInt();
+ const auto function_id = static_cast<FunctionID::eType>(
+ (*response)[strings::params][strings::function_id].asInt());
+
+ ApplicationSharedPtr app = application(connection_key);
+ DCHECK_OR_RETURN(app, false);
+ app->UnsubscribeFromSoftButtons(function_id);
+ SDL_LOG_DEBUG("Application has unsubscribed from softbuttons. FunctionID: "
+ << function_id << ", app_id:" << app->app_id());
+ return true;
+}
+
#ifdef BUILD_TESTS
void ApplicationManagerImpl::AddMockApplication(ApplicationSharedPtr mock_app) {
applications_list_lock_ptr_->Acquire();