summaryrefslogtreecommitdiff
path: root/src/components/application_manager/src/state_controller_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/application_manager/src/state_controller_impl.cc')
-rw-r--r--src/components/application_manager/src/state_controller_impl.cc560
1 files changed, 325 insertions, 235 deletions
diff --git a/src/components/application_manager/src/state_controller_impl.cc b/src/components/application_manager/src/state_controller_impl.cc
index 84081a3830..3d44709657 100644
--- a/src/components/application_manager/src/state_controller_impl.cc
+++ b/src/components/application_manager/src/state_controller_impl.cc
@@ -31,24 +31,29 @@
*/
#include "application_manager/state_controller_impl.h"
+#include <tuple>
#include "application_manager/usage_statistics.h"
+#include "application_manager/rpc_service.h"
#include "utils/helpers.h"
-#include "utils/make_shared.h"
+
#include "connection_handler/connection_handler.h"
namespace application_manager {
CREATE_LOGGERPTR_GLOBAL(logger_, "StateControllerImpl")
-bool IsStatusChanged(HmiStatePtr old_state, HmiStatePtr new_state) {
- if (old_state->hmi_level() != new_state->hmi_level() ||
- old_state->audio_streaming_state() !=
- new_state->audio_streaming_state() ||
- old_state->system_context() != new_state->system_context()) {
- return true;
- }
- return false;
+namespace {
+bool IsStateChanged(const HmiState& old_state, const HmiState& new_state) {
+ return std::make_tuple(old_state.hmi_level(),
+ old_state.audio_streaming_state(),
+ old_state.video_streaming_state(),
+ old_state.system_context()) !=
+ std::make_tuple(new_state.hmi_level(),
+ new_state.audio_streaming_state(),
+ new_state.video_streaming_state(),
+ new_state.system_context());
}
+} // unnamed namespace
StateControllerImpl::StateControllerImpl(ApplicationManager& app_mngr)
: EventObserver(app_mngr.event_dispatcher()), app_mngr_(app_mngr) {
@@ -64,20 +69,20 @@ StateControllerImpl::StateControllerImpl(ApplicationManager& app_mngr)
void StateControllerImpl::SetRegularState(ApplicationSharedPtr app,
HmiStatePtr state,
const bool send_activate_app) {
- CREATE_LOGGERPTR_LOCAL(logger_, "StateControllerImpl");
LOG4CXX_AUTO_TRACE(logger_);
- if (!app) {
- LOG4CXX_ERROR(logger_, "Invalid application pointer");
- return;
- }
+ DCHECK_OR_RETURN_VOID(app);
DCHECK_OR_RETURN_VOID(state);
- DCHECK_OR_RETURN_VOID(state->state_id() == HmiState::STATE_ID_REGULAR);
+ DCHECK_OR_RETURN_VOID(HmiState::STATE_ID_REGULAR == state->state_id());
+
+ LOG4CXX_DEBUG(logger_, "Set regular state " << *state);
if (state->hmi_level() == mobile_apis::HMILevel::INVALID_ENUM ||
state->audio_streaming_state() ==
mobile_apis::AudioStreamingState::INVALID_ENUM ||
+ state->video_streaming_state() ==
+ mobile_apis::VideoStreamingState::INVALID_ENUM ||
state->system_context() == mobile_apis::SystemContext::INVALID_ENUM) {
- LOG4CXX_ERROR(logger_, "Get invalid state");
+ LOG4CXX_ERROR(logger_, "Got invalid state");
return;
}
@@ -91,7 +96,8 @@ void StateControllerImpl::SetRegularState(ApplicationSharedPtr app,
app->SetPostponedState(state);
return;
}
- hmi_apis::Common_HMILevel::eType hmi_level =
+ LOG4CXX_DEBUG(logger_, "Resolved state: " << *resolved_state);
+ const hmi_apis::Common_HMILevel::eType hmi_level =
static_cast<hmi_apis::Common_HMILevel::eType>(
resolved_state->hmi_level());
@@ -100,7 +106,7 @@ void StateControllerImpl::SetRegularState(ApplicationSharedPtr app,
if (-1 != corr_id) {
subscribe_on_event(hmi_apis::FunctionID::BasicCommunication_ActivateApp,
corr_id);
- waiting_for_activate[app->app_id()] = resolved_state;
+ waiting_for_activate_[app->app_id()] = resolved_state;
return;
}
LOG4CXX_ERROR(logger_, "Unable to send BC.ActivateApp");
@@ -113,13 +119,10 @@ void StateControllerImpl::SetRegularState(
ApplicationSharedPtr app,
const mobile_apis::HMILevel::eType hmi_level,
const mobile_apis::AudioStreamingState::eType audio_state,
+ const mobile_apis::VideoStreamingState::eType video_state,
const bool send_activate_app) {
- CREATE_LOGGERPTR_LOCAL(logger_, "StateControllerImpl");
LOG4CXX_AUTO_TRACE(logger_);
- if (!app) {
- LOG4CXX_ERROR(logger_, "Invalid application pointer");
- return;
- }
+ DCHECK_OR_RETURN_VOID(app);
HmiStatePtr prev_regular = app->RegularHmiState();
DCHECK_OR_RETURN_VOID(prev_regular);
HmiStatePtr hmi_state =
@@ -127,6 +130,7 @@ void StateControllerImpl::SetRegularState(
DCHECK_OR_RETURN_VOID(hmi_state);
hmi_state->set_hmi_level(hmi_level);
hmi_state->set_audio_streaming_state(audio_state);
+ hmi_state->set_video_streaming_state(video_state);
hmi_state->set_system_context(prev_regular->system_context());
SetRegularState(app, hmi_state, send_activate_app);
}
@@ -136,19 +140,15 @@ void StateControllerImpl::SetRegularState(
const mobile_apis::HMILevel::eType hmi_level,
const bool send_activate_app) {
using namespace mobile_apis;
- using namespace helpers;
- CREATE_LOGGERPTR_LOCAL(logger_, "StateControllerImpl");
LOG4CXX_AUTO_TRACE(logger_);
- if (!app) {
- LOG4CXX_ERROR(logger_, "Invalid application pointer");
- return;
- }
+ DCHECK_OR_RETURN_VOID(app);
const HmiStatePtr hmi_state =
CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR);
DCHECK_OR_RETURN_VOID(hmi_state);
hmi_state->set_hmi_level(hmi_level);
hmi_state->set_audio_streaming_state(CalcAudioState(app, hmi_level));
+ hmi_state->set_video_streaming_state(CalcVideoState(app, hmi_level));
hmi_state->set_system_context(SystemContext::SYSCTXT_MAIN);
SetRegularState(app, hmi_state, send_activate_app);
}
@@ -157,37 +157,32 @@ void StateControllerImpl::SetRegularState(
ApplicationSharedPtr app,
const mobile_apis::HMILevel::eType hmi_level,
const mobile_apis::AudioStreamingState::eType audio_state,
+ const mobile_apis::VideoStreamingState::eType video_state,
const mobile_apis::SystemContext::eType system_context,
const bool send_activate_app) {
- CREATE_LOGGERPTR_LOCAL(logger_, "StateControllerImpl");
LOG4CXX_AUTO_TRACE(logger_);
- if (!app) {
- LOG4CXX_ERROR(logger_, "Invalid application pointer");
- return;
- }
+ DCHECK_OR_RETURN_VOID(app);
HmiStatePtr hmi_state =
CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR);
DCHECK_OR_RETURN_VOID(hmi_state);
hmi_state->set_hmi_level(hmi_level);
hmi_state->set_audio_streaming_state(audio_state);
+ hmi_state->set_video_streaming_state(video_state);
hmi_state->set_system_context(system_context);
SetRegularState(app, hmi_state, send_activate_app);
}
void StateControllerImpl::SetRegularState(
ApplicationSharedPtr app, const mobile_apis::HMILevel::eType hmi_level) {
- CREATE_LOGGERPTR_LOCAL(logger_, "StateControllerImpl");
LOG4CXX_AUTO_TRACE(logger_);
- if (!app) {
- LOG4CXX_ERROR(logger_, "Invalid application pointer");
- return;
- }
+ DCHECK_OR_RETURN_VOID(app);
HmiStatePtr prev_state = app->RegularHmiState();
HmiStatePtr hmi_state =
CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR);
DCHECK_OR_RETURN_VOID(hmi_state);
hmi_state->set_hmi_level(hmi_level);
hmi_state->set_audio_streaming_state(CalcAudioState(app, hmi_level));
+ hmi_state->set_video_streaming_state(CalcVideoState(app, hmi_level));
hmi_state->set_system_context(prev_state
? prev_state->system_context()
: mobile_apis::SystemContext::SYSCTXT_MAIN);
@@ -197,12 +192,8 @@ void StateControllerImpl::SetRegularState(
void StateControllerImpl::SetRegularState(
ApplicationSharedPtr app,
const mobile_apis::SystemContext::eType system_context) {
- CREATE_LOGGERPTR_LOCAL(logger_, "StateControllerImpl");
LOG4CXX_AUTO_TRACE(logger_);
- if (!app) {
- LOG4CXX_ERROR(logger_, "Invalid application pointer");
- return;
- }
+ DCHECK_OR_RETURN_VOID(app);
HmiStatePtr prev_regular = app->RegularHmiState();
DCHECK_OR_RETURN_VOID(prev_regular);
HmiStatePtr hmi_state =
@@ -211,19 +202,18 @@ void StateControllerImpl::SetRegularState(
hmi_state->set_hmi_level(prev_regular->hmi_level());
hmi_state->set_audio_streaming_state(
CalcAudioState(app, prev_regular->hmi_level()));
+ hmi_state->set_video_streaming_state(
+ CalcVideoState(app, prev_regular->hmi_level()));
hmi_state->set_system_context(system_context);
SetRegularState(app, hmi_state, false);
}
void StateControllerImpl::SetRegularState(
ApplicationSharedPtr app,
- const mobile_apis::AudioStreamingState::eType audio_state) {
- CREATE_LOGGERPTR_LOCAL(logger_, "StateControllerImpl");
+ const mobile_apis::AudioStreamingState::eType audio_state,
+ const mobile_apis::VideoStreamingState::eType video_state) {
LOG4CXX_AUTO_TRACE(logger_);
- if (!app) {
- LOG4CXX_ERROR(logger_, "Invalid application pointer");
- return;
- }
+ DCHECK_OR_RETURN_VOID(app);
HmiStatePtr prev_state = app->RegularHmiState();
DCHECK_OR_RETURN_VOID(prev_state);
HmiStatePtr hmi_state =
@@ -231,18 +221,15 @@ void StateControllerImpl::SetRegularState(
DCHECK_OR_RETURN_VOID(hmi_state);
hmi_state->set_hmi_level(prev_state->hmi_level());
hmi_state->set_audio_streaming_state(audio_state);
+ hmi_state->set_video_streaming_state(video_state);
hmi_state->set_system_context(prev_state->system_context());
SetRegularState(app, hmi_state, false);
}
void StateControllerImpl::SetRegularState(ApplicationSharedPtr app,
HmiStatePtr state) {
- CREATE_LOGGERPTR_LOCAL(logger_, "StateControllerImpl");
LOG4CXX_AUTO_TRACE(logger_);
- if (!app) {
- LOG4CXX_ERROR(logger_, "Invalid application pointer");
- return;
- }
+ DCHECK_OR_RETURN_VOID(app);
DCHECK_OR_RETURN_VOID(state);
if (mobile_apis::HMILevel::HMI_FULL == state->hmi_level()) {
SetRegularState(app, state, true);
@@ -251,84 +238,178 @@ void StateControllerImpl::SetRegularState(ApplicationSharedPtr app,
}
}
-void StateControllerImpl::HmiLevelConflictResolver::operator()(
- ApplicationSharedPtr to_resolve) {
- using namespace mobile_apis;
+namespace {
+
+/**
+ * @brief IsStreamableHMILevel checks whether the HMI level
+ * supports audio/video streaming.
+ * @param val HMI level
+ * @return true if streamable, false otherwise
+ */
+bool IsStreamableHMILevel(mobile_apis::HMILevel::eType val) {
using namespace helpers;
+ return Compare<mobile_apis::HMILevel::eType, EQ, ONE>(
+ val, mobile_apis::HMILevel::HMI_FULL, mobile_apis::HMILevel::HMI_LIMITED);
+}
+
+/**
+ * @brief IsSameAudioAppType checks whether the both applications:
+ * 1) belongs to exact HMI type that may stream audio without
+ * 'isMediaApplication' parameter set to true ('NAVIGATION', 'COMMUNICATION')
+ * 2) belongs to other HMI types with parameter 'isMediaApplication'
+ * is set to true.
+ * 3) are not media.
+ * @param app1 1st application
+ * @param app2 2nd application
+ * @return true if audio applications have same application HMI type
+ */
+bool IsSameAudioAppType(const Application& app1, const Application& app2) {
+ const auto is_only_media_app_type = [](const Application& app) {
+ return app.is_media_application() && !app.is_navi() &&
+ !app.is_voice_communication_supported();
+ };
+
+ const bool both_navi = app1.is_navi() && app2.is_navi();
+ const bool both_vc = app1.is_voice_communication_supported() &&
+ app2.is_voice_communication_supported();
+ const bool both_media =
+ is_only_media_app_type(app1) && is_only_media_app_type(app2);
+ const bool both_other =
+ !app1.IsAudioApplication() && !app2.IsAudioApplication();
+ const bool same_app_audio_type =
+ both_navi || both_vc || both_media || both_other;
+
+ return same_app_audio_type;
+}
+} // unnamed namespace
+
+void StateControllerImpl::HmiLevelConflictResolver::operator()(
+ ApplicationSharedPtr app_to_resolve) {
+ DCHECK_OR_RETURN_VOID(app_to_resolve);
DCHECK_OR_RETURN_VOID(state_ctrl_);
- if (to_resolve == applied_)
+ DCHECK_OR_RETURN_VOID(applied_);
+ DCHECK_OR_RETURN_VOID(state_);
+
+ if (applied_ == app_to_resolve) {
+ // Same app. Nothing to resolve
+ return;
+ }
+
+ const HmiStatePtr state_to_resolve = app_to_resolve->RegularHmiState();
+ DCHECK_OR_RETURN_VOID(state_to_resolve);
+
+ // If applied HMI state is FULL:
+ // - all NOT audio/video applications becomes BACKGROUND
+ // - all audio/video applications with other app type
+ // (navi, vc, media, projection) in FULL becomes LIMMITED
+ // - all audio/video applications with same app type becomes BACKGROUND
+ //
+ // If applied HMI state is LIMITED:
+ // - all NOT audio/video applications saves their's HMI states
+ // - all applications with other app types saves their's HMI states
+ // - all audio/video applications with same app type becomes BACKGROUND
+
+ if (!IsStreamableHMILevel(state_->hmi_level())) {
+ LOG4CXX_DEBUG(logger_,
+ "Applied for app " << applied_->app_id() << " HMI level "
+ << state_->hmi_level()
+ << " is NOT streamable. Exit.");
return;
- HmiStatePtr cur_state = to_resolve->RegularHmiState();
-
- const bool applied_grabs_audio =
- Compare<HMILevel::eType, EQ, ONE>(
- state_->hmi_level(), HMILevel::HMI_FULL, HMILevel::HMI_LIMITED) &&
- applied_->IsAudioApplication();
- const bool applied_grabs_full = state_->hmi_level() == HMILevel::HMI_FULL;
- const bool to_resolve_handles_full =
- cur_state->hmi_level() == HMILevel::HMI_FULL;
- const bool to_resolve_handles_audio =
- Compare<HMILevel::eType, EQ, ONE>(
- cur_state->hmi_level(), HMILevel::HMI_FULL, HMILevel::HMI_LIMITED) &&
- to_resolve->IsAudioApplication();
- const bool same_app_type = state_ctrl_->IsSameAppType(applied_, to_resolve);
-
- // If applied Hmi state is FULL:
- // all not audio applications will get BACKGROUND
- // all applications with same HMI type will get BACKGROUND
- // all audio applications with other HMI type(navi, vc, media) in FULL will
- // get LIMMITED HMI level
-
- // If applied Hmi state is LIMITED:
- // all applications with other HMI types will save HMI states
- // all not audio applications will save HMI states
- // all applications with same HMI type will get BACKGROUND
-
- // If applied Hmi state is BACKGROUND:
- // all applications will save HMI states
-
- HMILevel::eType result_hmi_level = cur_state->hmi_level();
- if (applied_grabs_full && to_resolve_handles_audio && !same_app_type)
- result_hmi_level = HMILevel::HMI_LIMITED;
-
- if ((applied_grabs_full && to_resolve_handles_full &&
- !to_resolve->IsAudioApplication()) ||
- (applied_grabs_audio && to_resolve_handles_audio && same_app_type))
- result_hmi_level = HMILevel::HMI_BACKGROUND;
-
- if (cur_state->hmi_level() != result_hmi_level) {
+ }
+
+ if (!IsStreamableHMILevel(state_to_resolve->hmi_level())) {
LOG4CXX_DEBUG(logger_,
- "Application " << to_resolve->app_id()
- << " will change HMI level to "
- << result_hmi_level);
- state_ctrl_->SetupRegularHmiState(to_resolve,
+ "To resolve app " << app_to_resolve->app_id() << " HMI level "
+ << state_to_resolve->hmi_level()
+ << " is NOT streamable. Exit.");
+ return;
+ }
+
+ // Applied app constants
+ const auto applied_hmi_level = state_->hmi_level();
+
+ const bool applied_grabs_video =
+ IsStreamableHMILevel(applied_hmi_level) && applied_->IsVideoApplication();
+
+ // App to resolve constants
+ const auto to_resolve_hmi_level = state_to_resolve->hmi_level();
+
+ const bool to_resolve_grabs_audio =
+ IsStreamableHMILevel(to_resolve_hmi_level) &&
+ app_to_resolve->IsAudioApplication();
+
+ const bool to_resolve_grabs_video =
+ IsStreamableHMILevel(to_resolve_hmi_level) &&
+ app_to_resolve->IsVideoApplication();
+
+ // Compatibility constants
+ const bool same_app_audio_type =
+ IsSameAudioAppType(*applied_, *app_to_resolve);
+
+ // Result variables
+ mobile_apis::VideoStreamingState::eType result_video_state =
+ mobile_apis::VideoStreamingState::NOT_STREAMABLE;
+ mobile_apis::AudioStreamingState::eType result_audio_state =
+ mobile_apis::AudioStreamingState::NOT_AUDIBLE;
+
+ if (to_resolve_grabs_audio && !same_app_audio_type) {
+ result_audio_state = mobile_apis::AudioStreamingState::AUDIBLE;
+ }
+
+ if (to_resolve_grabs_video && !applied_grabs_video) {
+ result_video_state = mobile_apis::VideoStreamingState::STREAMABLE;
+ }
+
+ mobile_apis::HMILevel::eType result_hmi_level = state_to_resolve->hmi_level();
+
+ using namespace helpers;
+ if (mobile_apis::VideoStreamingState::STREAMABLE == result_video_state ||
+ Compare<mobile_apis::AudioStreamingState::eType, EQ, ONE>(
+ result_audio_state,
+ mobile_apis::AudioStreamingState::AUDIBLE,
+ mobile_apis::AudioStreamingState::ATTENUATED)) {
+ result_hmi_level = mobile_apis::HMILevel::HMI_LIMITED;
+ } else {
+ result_hmi_level = mobile_apis::HMILevel::HMI_BACKGROUND;
+ }
+
+ if (std::make_tuple(to_resolve_hmi_level,
+ state_to_resolve->audio_streaming_state(),
+ state_to_resolve->video_streaming_state()) !=
+ std::make_tuple(
+ result_hmi_level, result_audio_state, result_video_state)) {
+ LOG4CXX_DEBUG(logger_,
+ "Application "
+ << app_to_resolve->app_id() << " will change state to: "
+ << "HMI level " << to_resolve_hmi_level << " --> "
+ << result_hmi_level << ", audio "
+ << state_to_resolve->audio_streaming_state() << " --> "
+ << result_audio_state << ", video "
+ << state_to_resolve->video_streaming_state() << " --> "
+ << result_video_state);
+ state_ctrl_->SetupRegularHmiState(app_to_resolve,
result_hmi_level,
- result_hmi_level == HMILevel::HMI_LIMITED
- ? AudioStreamingState::AUDIBLE
- : AudioStreamingState::NOT_AUDIBLE);
+ result_audio_state,
+ result_video_state);
} else {
LOG4CXX_DEBUG(logger_,
- "Application " << to_resolve->app_id()
- << " will not change HMI level");
+ "Application " << app_to_resolve->app_id()
+ << " will NOT change HMI level");
}
}
HmiStatePtr StateControllerImpl::ResolveHmiState(ApplicationSharedPtr app,
HmiStatePtr state) const {
using namespace mobile_apis;
- using namespace helpers;
LOG4CXX_AUTO_TRACE(logger_);
- LOG4CXX_DEBUG(logger_,
- "State to resolve: hmi_level "
- << state->hmi_level() << ", audio_state "
- << state->audio_streaming_state() << ", system_context "
- << state->system_context());
+ LOG4CXX_DEBUG(logger_, "State to resolve: " << *state);
HmiStatePtr available_state =
CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR);
DCHECK_OR_RETURN(available_state, HmiStatePtr());
available_state->set_hmi_level(state->hmi_level());
available_state->set_audio_streaming_state(state->audio_streaming_state());
+ available_state->set_video_streaming_state(state->video_streaming_state());
available_state->set_system_context(state->system_context());
if (app->is_resuming()) {
@@ -337,6 +418,8 @@ HmiStatePtr StateControllerImpl::ResolveHmiState(ApplicationSharedPtr app,
available_state->set_hmi_level(available_level);
available_state->set_audio_streaming_state(
CalcAudioState(app, available_level));
+ available_state->set_video_streaming_state(
+ CalcVideoState(app, available_level));
}
return IsStateAvailable(app, available_state) ? available_state
: HmiStatePtr();
@@ -345,11 +428,8 @@ HmiStatePtr StateControllerImpl::ResolveHmiState(ApplicationSharedPtr app,
bool StateControllerImpl::IsResumptionAllowed(ApplicationSharedPtr app,
HmiStatePtr state) const {
LOG4CXX_AUTO_TRACE(logger_);
- using namespace helpers;
using namespace mobile_apis;
- if (!app->is_resuming() ||
- !Compare<HMILevel::eType, EQ, ONE>(
- state->hmi_level(), HMILevel::HMI_FULL, HMILevel::HMI_LIMITED)) {
+ if (!app->is_resuming() || !IsStreamableHMILevel(state->hmi_level())) {
LOG4CXX_DEBUG(logger_, "Application is not in resuming mode.");
return true;
}
@@ -375,27 +455,27 @@ bool StateControllerImpl::IsResumptionAllowed(ApplicationSharedPtr app,
mobile_apis::HMILevel::eType StateControllerImpl::GetAvailableHmiLevel(
ApplicationSharedPtr app, mobile_apis::HMILevel::eType hmi_level) const {
- using namespace mobile_apis;
- using namespace helpers;
LOG4CXX_AUTO_TRACE(logger_);
mobile_apis::HMILevel::eType result = hmi_level;
- if (!Compare<HMILevel::eType, EQ, ONE>(
- hmi_level, HMILevel::HMI_FULL, HMILevel::HMI_LIMITED)) {
+ LOG4CXX_DEBUG(logger_, "HMI Level: " << hmi_level);
+
+ if (!IsStreamableHMILevel(hmi_level)) {
return result;
}
const bool is_audio_app = app->IsAudioApplication();
const bool does_audio_app_with_same_type_exist =
app_mngr_.IsAppTypeExistsInFullOrLimited(app);
- if (HMILevel::HMI_LIMITED == hmi_level) {
+
+ if (mobile_apis::HMILevel::HMI_LIMITED == hmi_level) {
if (!is_audio_app || does_audio_app_with_same_type_exist) {
result = app_mngr_.GetDefaultHmiLevel(app);
}
return result;
}
- const bool is_active_app_exist = app_mngr_.active_application();
+ const bool is_active_app_exist = (bool)app_mngr_.active_application();
if (is_audio_app) {
if (does_audio_app_with_same_type_exist) {
result = app_mngr_.GetDefaultHmiLevel(app);
@@ -424,13 +504,8 @@ mobile_apis::HMILevel::eType StateControllerImpl::GetAvailableHmiLevel(
bool StateControllerImpl::IsStateAvailable(ApplicationSharedPtr app,
HmiStatePtr state) const {
using namespace mobile_apis;
- using namespace helpers;
LOG4CXX_AUTO_TRACE(logger_);
- LOG4CXX_DEBUG(logger_,
- "Checking state: hmi_level "
- << state->hmi_level() << ", audio_state "
- << state->audio_streaming_state() << ", system_context "
- << state->system_context());
+ LOG4CXX_DEBUG(logger_, "Checking state: " << *state);
if (app->is_resuming()) {
return IsStateAvailableForResumption(app, state);
@@ -454,11 +529,8 @@ bool StateControllerImpl::IsStateAvailableForResumption(
ApplicationSharedPtr app, HmiStatePtr state) const {
LOG4CXX_AUTO_TRACE(logger_);
using namespace mobile_apis;
- using namespace helpers;
- if (!app->is_resuming() ||
- !Compare<HMILevel::eType, EQ, ONE>(
- state->hmi_level(), HMILevel::HMI_FULL, HMILevel::HMI_LIMITED)) {
+ if (!app->is_resuming() || !IsStreamableHMILevel(state->hmi_level())) {
LOG4CXX_DEBUG(logger_,
"Application is not in resuming mode."
<< " Requested state is available");
@@ -492,20 +564,17 @@ bool StateControllerImpl::IsStateAvailableForResumption(
void StateControllerImpl::SetupRegularHmiState(ApplicationSharedPtr app,
HmiStatePtr state) {
- namespace HMILevel = mobile_apis::HMILevel;
- namespace AudioStreamingState = mobile_apis::AudioStreamingState;
+ using namespace mobile_apis;
LOG4CXX_AUTO_TRACE(logger_);
DCHECK_OR_RETURN_VOID(state);
- LOG4CXX_DEBUG(logger_,
- "hmi_level " << state->hmi_level() << ", audio_state "
- << state->audio_streaming_state()
- << ", system_context " << state->system_context());
+ LOG4CXX_DEBUG(logger_, "Setup regular state: " << *state);
HmiStatePtr curr_state = app->CurrentHmiState();
HmiStatePtr old_state =
CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR);
DCHECK_OR_RETURN_VOID(old_state);
old_state->set_hmi_level(curr_state->hmi_level());
old_state->set_audio_streaming_state(curr_state->audio_streaming_state());
+ old_state->set_video_streaming_state(curr_state->video_streaming_state());
old_state->set_system_context(curr_state->system_context());
app->SetRegularState(state);
@@ -524,10 +593,8 @@ void StateControllerImpl::SetupRegularHmiState(ApplicationSharedPtr app,
void StateControllerImpl::SetupRegularHmiState(
ApplicationSharedPtr app,
const mobile_apis::HMILevel::eType hmi_level,
- const mobile_apis::AudioStreamingState::eType audio_state) {
- namespace HMILevel = mobile_apis::HMILevel;
- namespace AudioStreamingState = mobile_apis::AudioStreamingState;
- using helpers::Compare;
+ const mobile_apis::AudioStreamingState::eType audio_state,
+ const mobile_apis::VideoStreamingState::eType video_state) {
LOG4CXX_AUTO_TRACE(logger_);
DCHECK_OR_RETURN_VOID(app);
HmiStatePtr prev_state = app->RegularHmiState();
@@ -537,6 +604,7 @@ void StateControllerImpl::SetupRegularHmiState(
DCHECK_OR_RETURN_VOID(new_state);
new_state->set_hmi_level(hmi_level);
new_state->set_audio_streaming_state(audio_state);
+ new_state->set_video_streaming_state(video_state);
new_state->set_system_context(prev_state->system_context());
SetupRegularHmiState(app, new_state);
}
@@ -547,28 +615,12 @@ void StateControllerImpl::ApplyRegularState(ApplicationSharedPtr app,
DCHECK_OR_RETURN_VOID(app);
DCHECK_OR_RETURN_VOID(state);
DCHECK_OR_RETURN_VOID(state->state_id() == HmiState::STATE_ID_REGULAR);
+ LOG4CXX_DEBUG(logger_,
+ "Applying to app " << app->app_id() << " state " << *state);
SetupRegularHmiState(app, state);
- ForEachApplication<HmiLevelConflictResolver>(
- HmiLevelConflictResolver(app, state, this));
-}
-
-bool StateControllerImpl::IsSameAppType(ApplicationConstSharedPtr app1,
- ApplicationConstSharedPtr app2) {
- const bool both_media =
- app1->is_media_application() && app2->is_media_application();
-
- const bool both_navi = app1->is_navi() && app2->is_navi();
-
- const bool both_vc = app1->is_voice_communication_supported() &&
- app2->is_voice_communication_supported();
-
- const bool both_simple =
- !app1->IsAudioApplication() && !app2->IsAudioApplication();
-
- const bool both_projection =
- app1->mobile_projection_enabled() && app2->mobile_projection_enabled();
-
- return both_simple || both_media || both_navi || both_vc || both_projection;
+ LOG4CXX_DEBUG(logger_,
+ "Resolving HMI level conflicts for app " << app->app_id());
+ ForEachApplication(HmiLevelConflictResolver(app, state, this));
}
void StateControllerImpl::on_event(const event_engine::Event& event) {
@@ -615,7 +667,7 @@ void StateControllerImpl::on_event(const event_engine::Event& event) {
const uint32_t id =
message[strings::msg_params][hmi_notification::event_name].asUInt();
// TODO(AOleynik): Add verification/conversion check here
- Common_EventTypes::eType state_id =
+ const Common_EventTypes::eType state_id =
static_cast<Common_EventTypes::eType>(id);
if (is_active) {
if (Common_EventTypes::AUDIO_SOURCE == state_id) {
@@ -660,6 +712,9 @@ void StateControllerImpl::on_event(const event_engine::Event& event) {
break;
}
}
+
+ LOG4CXX_WARN(logger_,
+ "Couldn't recognize state id (val='" << state_id << "')");
break;
}
default:
@@ -674,17 +729,9 @@ void StateControllerImpl::OnStateChanged(ApplicationSharedPtr app,
DCHECK_OR_RETURN_VOID(app);
DCHECK_OR_RETURN_VOID(old_state);
DCHECK_OR_RETURN_VOID(new_state);
- LOG4CXX_DEBUG(logger_,
- "old: hmi_level " << old_state->hmi_level() << ", audio_state "
- << old_state->audio_streaming_state()
- << ", system_context "
- << old_state->system_context());
- LOG4CXX_DEBUG(logger_,
- "new: hmi_level " << new_state->hmi_level() << ", audio_state "
- << new_state->audio_streaming_state()
- << ", system_context "
- << new_state->system_context());
- if (IsStatusChanged(old_state, new_state)) {
+ LOG4CXX_DEBUG(logger_, "Old state: " << *old_state);
+ LOG4CXX_DEBUG(logger_, "New state: " << *new_state);
+ if (IsStateChanged(*old_state, *new_state)) {
app_mngr_.SendHMIStatusNotification(app);
if (new_state->hmi_level() == mobile_apis::HMILevel::HMI_NONE) {
app->ResetDataInNone();
@@ -693,15 +740,13 @@ void StateControllerImpl::OnStateChanged(ApplicationSharedPtr app,
app->app_id(), old_state->hmi_level(), new_state->hmi_level());
app->usage_report().RecordHmiStateChanged(new_state->hmi_level());
} else {
- LOG4CXX_ERROR(logger_, "Status not changed");
+ LOG4CXX_ERROR(logger_, "State has NOT been changed.");
}
}
-bool StateControllerImpl::IsTempStateActive(HmiState::StateID ID) const {
+bool StateControllerImpl::IsTempStateActive(HmiState::StateID id) const {
sync_primitives::AutoLock autolock(active_states_lock_);
- StateIDList::const_iterator itr =
- std::find(active_states_.begin(), active_states_.end(), ID);
- return active_states_.end() != itr;
+ return helpers::in_range(active_states_, id);
}
void StateControllerImpl::OnApplicationRegistered(
@@ -713,23 +758,25 @@ void StateControllerImpl::OnApplicationRegistered(
LOG4CXX_AUTO_TRACE(logger_);
DCHECK_OR_RETURN_VOID(app);
- active_states_lock_.Acquire();
- StateIDList::iterator it = active_states_.begin();
- for (; it != active_states_.end(); ++it) {
- HmiStatePtr new_state = CreateHmiState(app, *it);
- DCHECK_OR_RETURN_VOID(new_state);
- DCHECK_OR_RETURN_VOID(new_state->state_id() != HmiState::STATE_ID_REGULAR);
- HmiStatePtr old_hmi_state = app->CurrentHmiState();
- new_state->set_parent(old_hmi_state);
- app->AddHMIState(new_state);
+ {
+ sync_primitives::AutoLock lck(active_states_lock_);
+ for (const auto state_id : active_states_) {
+ HmiStatePtr new_state = CreateHmiState(app, state_id);
+ DCHECK_OR_RETURN_VOID(new_state);
+ DCHECK_OR_RETURN_VOID(new_state->state_id() !=
+ HmiState::STATE_ID_REGULAR);
+ HmiStatePtr old_hmi_state = app->CurrentHmiState();
+ new_state->set_parent(old_hmi_state);
+ app->AddHMIState(new_state);
+ }
}
- active_states_lock_.Release();
HmiStatePtr default_state =
CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR);
DCHECK_OR_RETURN_VOID(default_state);
default_state->set_hmi_level(default_level);
default_state->set_audio_streaming_state(CalcAudioState(app, default_level));
+ default_state->set_video_streaming_state(CalcVideoState(app, default_level));
default_state->set_system_context(SystemContext::SYSCTXT_MAIN);
HmiStatePtr initial_state = app->RegularHmiState();
@@ -758,7 +805,7 @@ int64_t StateControllerImpl::SendBCActivateApp(
LOG4CXX_ERROR(logger_, "Unable to create BC.ActivateAppRequest");
return -1;
}
- if (!app_mngr_.ManageHMICommand(bc_activate_app_request)) {
+ if (!app_mngr_.GetRPCService().ManageHMICommand(bc_activate_app_request)) {
LOG4CXX_ERROR(logger_, "Unable to send BC.ActivateAppRequest");
return -1;
}
@@ -778,16 +825,18 @@ void StateControllerImpl::ApplyPostponedStateForApp(ApplicationSharedPtr app) {
}
}
-void StateControllerImpl::TempStateStarted(HmiState::StateID ID) {
+void StateControllerImpl::TempStateStarted(HmiState::StateID id) {
LOG4CXX_AUTO_TRACE(logger_);
- sync_primitives::AutoLock autolock(active_states_lock_);
- StateIDList::iterator it =
- std::find(active_states_.begin(), active_states_.end(), ID);
- if (it == active_states_.end()) {
- active_states_.push_back(ID);
- } else {
- LOG4CXX_ERROR(logger_, "StateID " << ID << " is already active");
+
+ {
+ sync_primitives::AutoLock autolock(active_states_lock_);
+ if (!helpers::in_range(active_states_, id)) {
+ active_states_.push_back(id);
+ return;
+ }
}
+
+ LOG4CXX_ERROR(logger_, "StateID '" << id << "' is already active");
}
void StateControllerImpl::TempStateStopped(HmiState::StateID ID) {
@@ -805,16 +854,34 @@ void StateControllerImpl::DeactivateApp(ApplicationSharedPtr app) {
LOG4CXX_AUTO_TRACE(logger_);
DCHECK_OR_RETURN_VOID(app);
- HmiStatePtr regular = app->RegularHmiState();
+ const HmiStatePtr regular = app->RegularHmiState();
DCHECK_OR_RETURN_VOID(regular);
- HmiStatePtr new_regular = utils::MakeShared<HmiState>(*regular);
+ HmiStatePtr new_regular = std::make_shared<HmiState>(*regular);
+
+ LOG4CXX_DEBUG(logger_, "Current HMI level: '" << app->hmi_level() << "'");
+ const bool is_audio_app = app->IsAudioApplication();
+ const bool is_video_app = app->IsVideoApplication();
- if (app->IsAudioApplication()) {
+ if (is_audio_app || is_video_app) {
+ // audio or video app move to HMI level limited
new_regular->set_hmi_level(HMILevel::HMI_LIMITED);
- new_regular->set_audio_streaming_state(AudioStreamingState::AUDIBLE);
+
+ if (is_audio_app) {
+ new_regular->set_audio_streaming_state(AudioStreamingState::AUDIBLE);
+ } else {
+ new_regular->set_audio_streaming_state(AudioStreamingState::NOT_AUDIBLE);
+ }
+
+ if (is_video_app) {
+ new_regular->set_video_streaming_state(VideoStreamingState::STREAMABLE);
+ } else {
+ new_regular->set_video_streaming_state(
+ VideoStreamingState::NOT_STREAMABLE);
+ }
} else {
new_regular->set_hmi_level(HMILevel::HMI_BACKGROUND);
new_regular->set_audio_streaming_state(AudioStreamingState::NOT_AUDIBLE);
+ new_regular->set_video_streaming_state(VideoStreamingState::NOT_STREAMABLE);
}
SetRegularState(app, new_regular, false);
@@ -831,7 +898,7 @@ void StateControllerImpl::OnActivateAppResponse(
ApplicationSharedPtr application =
app_mngr_.application_by_hmi_app(hmi_app_id);
if (application && hmi_apis::Common_Result::SUCCESS == code) {
- HmiStatePtr pending_state = waiting_for_activate[application->app_id()];
+ HmiStatePtr pending_state = waiting_for_activate_[application->app_id()];
DCHECK_OR_RETURN_VOID(pending_state);
ApplyRegularState(application, pending_state);
}
@@ -854,9 +921,7 @@ void StateControllerImpl::OnAppActivated(
void StateControllerImpl::OnAppDeactivated(
const smart_objects::SmartObject& message) {
- using namespace hmi_apis;
using namespace mobile_apis;
- using namespace helpers;
LOG4CXX_AUTO_TRACE(logger_);
uint32_t app_id = message[strings::msg_params][strings::app_id].asUInt();
@@ -875,12 +940,22 @@ void StateControllerImpl::OnAppDeactivated(
DeactivateApp(app);
}
-void StateControllerImpl::OnNaviStreamingStarted() {
- ApplyTempState<HmiState::STATE_ID_NAVI_STREAMING>();
+void StateControllerImpl::OnVideoStreamingStarted(
+ ApplicationConstSharedPtr app) {
+ if (app->is_navi()) {
+ ApplyTempState<HmiState::STATE_ID_NAVI_STREAMING>();
+ } else {
+ ApplyTempState<HmiState::STATE_ID_VIDEO_STREAMING>();
+ }
}
-void StateControllerImpl::OnNaviStreamingStopped() {
- CancelTempState<HmiState::STATE_ID_NAVI_STREAMING>();
+void StateControllerImpl::OnVideoStreamingStopped(
+ ApplicationConstSharedPtr app) {
+ if (app->is_navi()) {
+ CancelTempState<HmiState::STATE_ID_NAVI_STREAMING>();
+ } else {
+ CancelTempState<HmiState::STATE_ID_VIDEO_STREAMING>();
+ }
}
bool StateControllerImpl::IsStateActive(HmiState::StateID state_id) const {
@@ -896,49 +971,53 @@ bool StateControllerImpl::IsStateActive(HmiState::StateID state_id) const {
}
HmiStatePtr StateControllerImpl::CreateHmiState(
- utils::SharedPtr<Application> app, HmiState::StateID state_id) const {
+ std::shared_ptr<Application> app, HmiState::StateID state_id) const {
using namespace utils;
LOG4CXX_AUTO_TRACE(logger_);
HmiStatePtr new_state;
switch (state_id) {
case HmiState::STATE_ID_PHONE_CALL: {
- new_state = MakeShared<PhoneCallHmiState>(app, app_mngr_);
+ new_state = std::make_shared<PhoneCallHmiState>(app, app_mngr_);
break;
}
case HmiState::STATE_ID_SAFETY_MODE: {
- new_state = MakeShared<SafetyModeHmiState>(app, app_mngr_);
+ new_state = std::make_shared<SafetyModeHmiState>(app, app_mngr_);
break;
}
case HmiState::STATE_ID_VR_SESSION: {
- new_state = MakeShared<VRHmiState>(app, app_mngr_);
+ new_state = std::make_shared<VRHmiState>(app, app_mngr_);
break;
}
case HmiState::STATE_ID_TTS_SESSION: {
- new_state = MakeShared<TTSHmiState>(app, app_mngr_);
+ new_state = std::make_shared<TTSHmiState>(app, app_mngr_);
+ break;
+ }
+ case HmiState::STATE_ID_VIDEO_STREAMING: {
+ new_state = std::make_shared<VideoStreamingHmiState>(app, app_mngr_);
break;
}
case HmiState::STATE_ID_NAVI_STREAMING: {
- new_state = MakeShared<NaviStreamingHmiState>(app, app_mngr_);
+ new_state = std::make_shared<NaviStreamingHmiState>(app, app_mngr_);
break;
}
case HmiState::STATE_ID_REGULAR: {
- new_state = MakeShared<HmiState>(app, app_mngr_);
+ new_state = std::make_shared<HmiState>(app, app_mngr_);
break;
}
case HmiState::STATE_ID_POSTPONED: {
- new_state = MakeShared<HmiState>(app, app_mngr_, state_id);
+ new_state = std::make_shared<HmiState>(app, app_mngr_, state_id);
break;
}
case HmiState::STATE_ID_DEACTIVATE_HMI: {
- new_state = MakeShared<DeactivateHMI>(app, app_mngr_);
+ new_state = std::make_shared<DeactivateHMI>(app, app_mngr_);
break;
}
case HmiState::STATE_ID_AUDIO_SOURCE: {
- new_state = MakeShared<AudioSource>(app, app_mngr_);
+ new_state = std::make_shared<AudioSource>(app, app_mngr_);
break;
}
case HmiState::STATE_ID_EMBEDDED_NAVI: {
- new_state = MakeShared<EmbeddedNavi>(app, app_mngr_);
+ new_state = std::make_shared<EmbeddedNavi>(app, app_mngr_);
break;
}
default:
@@ -952,20 +1031,31 @@ HmiStatePtr StateControllerImpl::CreateHmiState(
mobile_apis::AudioStreamingState::eType StateControllerImpl::CalcAudioState(
ApplicationSharedPtr app,
const mobile_apis::HMILevel::eType hmi_level) const {
- namespace HMILevel = mobile_apis::HMILevel;
- namespace AudioStreamingState = mobile_apis::AudioStreamingState;
- using helpers::Compare;
- using helpers::EQ;
- using helpers::ONE;
-
- AudioStreamingState::eType audio_state = AudioStreamingState::NOT_AUDIBLE;
- if (Compare<HMILevel::eType, EQ, ONE>(
- hmi_level, HMILevel::HMI_FULL, HMILevel::HMI_LIMITED)) {
- if (app->IsAudioApplication()) {
- audio_state = AudioStreamingState::AUDIBLE;
- }
+ auto state = mobile_apis::AudioStreamingState::NOT_AUDIBLE;
+ if (IsStreamableHMILevel(hmi_level) && app->IsAudioApplication()) {
+ state = mobile_apis::AudioStreamingState::AUDIBLE;
}
- return audio_state;
+
+ LOG4CXX_DEBUG(logger_,
+ "Calculated audio state of app "
+ << app->app_id() << " for " << hmi_level << " HMI level is "
+ << state);
+ return state;
+}
+
+mobile_apis::VideoStreamingState::eType StateControllerImpl::CalcVideoState(
+ ApplicationSharedPtr app,
+ const mobile_apis::HMILevel::eType hmi_level) const {
+ auto state = mobile_apis::VideoStreamingState::NOT_STREAMABLE;
+ if (IsStreamableHMILevel(hmi_level) && app->IsVideoApplication()) {
+ state = mobile_apis::VideoStreamingState::STREAMABLE;
+ }
+
+ LOG4CXX_DEBUG(logger_,
+ "Calculated video state of app "
+ << app->app_id() << " for " << hmi_level << " HMI level is "
+ << state);
+ return state;
}
} // namespace application_manager