summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Keeler <jacob.keeler@livioradio.com>2020-09-04 11:19:49 -0400
committerGitHub <noreply@github.com>2020-09-04 11:19:49 -0400
commit9e52441ab19e273ef66df6d316c14ab0dcf2a5b3 (patch)
treed9dbe89989e33d6adad8269adbae59d6d53ddc78
parent99a74995974cd658f06e7b69e9531f2959f31fd1 (diff)
downloadsdl_core-9e52441ab19e273ef66df6d316c14ab0dcf2a5b3.tar.gz
Overhaul state manager to handle regular state changes during hmi events (#3476)
* Overhaul state manager to handle regular state changes during hmi events * Add parent check for all calls
-rw-r--r--src/components/application_manager/include/application_manager/application_state.h20
-rw-r--r--src/components/application_manager/include/application_manager/hmi_state.h177
-rw-r--r--src/components/application_manager/src/application_state.cc118
-rw-r--r--src/components/application_manager/src/hmi_state.cc243
-rw-r--r--src/components/application_manager/src/state_controller_impl.cc17
-rw-r--r--src/components/application_manager/test/application_impl_test.cc15
-rw-r--r--src/components/application_manager/test/application_state_test.cc122
-rw-r--r--src/components/application_manager/test/state_controller/state_controller_test.cc149
8 files changed, 613 insertions, 248 deletions
diff --git a/src/components/application_manager/include/application_manager/application_state.h b/src/components/application_manager/include/application_manager/application_state.h
index 8c4d2d49d6..9d80df0590 100644
--- a/src/components/application_manager/include/application_manager/application_state.h
+++ b/src/components/application_manager/include/application_manager/application_state.h
@@ -45,6 +45,7 @@ namespace application_manager {
typedef std::vector<WindowID> WindowIds;
typedef std::vector<HmiStatePtr> HmiStates;
typedef std::map<WindowID, HmiStates> HmiStatesMap;
+typedef std::map<WindowID, HmiStatePtr> HmiStateMap;
typedef std::vector<std::string> WindowNames;
typedef std::map<WindowID, std::string> WindowNamesMap;
@@ -143,6 +144,15 @@ class ApplicationState {
void RemoveHMIState(const WindowID window_id, HmiState::StateID state_id);
/**
+ * @brief EraseHMIState safely erases an HMI State from a window's HMIStates
+ * list
+ *
+ * @param hmi_states HMI States list.
+ * @param it Iterator pointing to element to be removed.
+ */
+ void EraseHMIState(HmiStates& hmi_states, HmiStates::iterator it);
+
+ /**
* @brief RemoveWindowHMIStates removes all HMI states related to specified
* window
* @param window_id window ID to remove
@@ -202,6 +212,16 @@ class ApplicationState {
*/
mutable sync_primitives::Lock hmi_states_map_lock_;
+ /**
+ * @brief Postponed states of application
+ */
+ HmiStateMap postponed_states_map_;
+
+ /**
+ * @brief postponed_states_map_lock_
+ */
+ mutable sync_primitives::Lock postponed_states_map_lock_;
+
DISALLOW_COPY_AND_ASSIGN(ApplicationState);
};
} // namespace application_manager
diff --git a/src/components/application_manager/include/application_manager/hmi_state.h b/src/components/application_manager/include/application_manager/hmi_state.h
index 5b9e201391..e3a9784346 100644
--- a/src/components/application_manager/include/application_manager/hmi_state.h
+++ b/src/components/application_manager/include/application_manager/hmi_state.h
@@ -117,10 +117,27 @@ class HmiState {
*/
virtual mobile_apis::HMILevel::eType hmi_level() const {
if (parent_) {
- return parent_->hmi_level();
+ if (mobile_apis::HMILevel::INVALID_ENUM == hmi_level_) {
+ return parent_->hmi_level();
+ }
+ // Higher values correlate to lower states
+ // (FULL = 0, LIMITED = 1, etc.)
+ return std::max(parent_->max_hmi_level(), hmi_level_);
}
return hmi_level_;
}
+
+ /**
+ * @brief max_hmi_level
+ * @return return maximum hmi level for app
+ */
+ virtual mobile_apis::HMILevel::eType max_hmi_level() const {
+ if (parent_) {
+ return parent_->max_hmi_level();
+ }
+ return mobile_apis::HMILevel::HMI_FULL;
+ }
+
/**
* @brief set_hmi_level set hmi_level member
* @param hmi_level hmi level to setup
@@ -136,24 +153,62 @@ class HmiState {
virtual mobile_apis::AudioStreamingState::eType audio_streaming_state()
const {
if (parent_) {
- return parent_->audio_streaming_state();
+ if (mobile_apis::AudioStreamingState::INVALID_ENUM ==
+ audio_streaming_state_) {
+ return parent_->audio_streaming_state();
+ }
+ // Higher values correlate to lower states
+ // (AUDIBLE = 0, ATTENUATED = 1, etc.)
+ return std::max(parent_->max_audio_streaming_state(),
+ audio_streaming_state_);
}
return audio_streaming_state_;
}
/**
+ * @brief max_audio_streaming_state
+ * @return return maximum audio streaming state for app
+ */
+ virtual mobile_apis::AudioStreamingState::eType max_audio_streaming_state()
+ const {
+ if (parent_) {
+ return parent_->max_audio_streaming_state();
+ }
+ return mobile_apis::AudioStreamingState::AUDIBLE;
+ }
+
+ /**
* @brief video_streaming_state
* @return return video streaming state member
*/
virtual mobile_apis::VideoStreamingState::eType video_streaming_state()
const {
if (parent_) {
- return parent_->video_streaming_state();
+ if (mobile_apis::VideoStreamingState::INVALID_ENUM ==
+ video_streaming_state_) {
+ return parent_->video_streaming_state();
+ }
+ // Higher values correlate to lower states
+ // (STREAMABLE = 0, NOT_STREAMABLE = 1)
+ return std::max(parent_->max_video_streaming_state(),
+ video_streaming_state_);
}
return video_streaming_state_;
}
/**
+ * @brief max_video_streaming_state
+ * @return return maximum video streaming state for app
+ */
+ virtual mobile_apis::VideoStreamingState::eType max_video_streaming_state()
+ const {
+ if (parent_) {
+ return parent_->max_video_streaming_state();
+ }
+ return mobile_apis::VideoStreamingState::STREAMABLE;
+ }
+
+ /**
* @brief set_video_streaming_state set set_video_streaming_state member
* @param video_state video_state to setup
*/
@@ -176,7 +231,9 @@ class HmiState {
* @return return system context member
*/
virtual mobile_apis::SystemContext::eType system_context() const {
- if (parent_) {
+ // Parent's context should be used if not available for current state
+ if (parent_ &&
+ system_context_ == mobile_apis::SystemContext::INVALID_ENUM) {
return parent_->system_context();
}
return system_context_;
@@ -238,6 +295,12 @@ class HmiState {
bool is_navi_app() const;
/**
+ * @brief is_projection_app check if app is projection
+ * @return true if app is projection, otherwise return false
+ */
+ bool is_projection_app() const;
+
+ /**
* @brief is_media_app check if app is media
* @return true if media_app, otherwise return false
*/
@@ -256,6 +319,48 @@ class HmiState {
*/
bool is_mobile_projection_app() const;
+ /**
+ * @brief parent_hmi_level
+ * @return return hmi level for parent state if available, otherwise return
+ * HMI_NONE
+ */
+ mobile_apis::HMILevel::eType parent_hmi_level() const;
+
+ /**
+ * @brief parent_max_hmi_level
+ * @return return maximum hmi level for parent state if available, otherwise
+ * return HMI_FULL
+ */
+ mobile_apis::HMILevel::eType parent_max_hmi_level() const;
+
+ /**
+ * @brief parent_audio_state
+ * @return return audio streaming state for parent state if available,
+ * otherwise return NOT_AUDIBLE
+ */
+ mobile_apis::AudioStreamingState::eType parent_audio_state() const;
+
+ /**
+ * @brief parent_max_audio_state
+ * @return return maximum audio streaming state for parent state if available,
+ * otherwise return AUDIBLE
+ */
+ mobile_apis::AudioStreamingState::eType parent_max_audio_state() const;
+
+ /**
+ * @brief parent_video_state
+ * @return return video streaming state for parent state if available,
+ * otherwise return NOT_STREAMABLE
+ */
+ mobile_apis::VideoStreamingState::eType parent_video_state() const;
+
+ /**
+ * @brief parent_max_video_state
+ * @return return maximum video streaming statefor parent state if available,
+ * otherwise return STREAMABLE
+ */
+ mobile_apis::VideoStreamingState::eType parent_max_video_state() const;
+
private:
void operator=(const HmiState&);
};
@@ -267,6 +372,8 @@ class VRHmiState : public HmiState {
public:
virtual mobile_apis::AudioStreamingState::eType audio_streaming_state()
const OVERRIDE;
+ virtual mobile_apis::AudioStreamingState::eType max_audio_streaming_state()
+ const OVERRIDE;
VRHmiState(std::shared_ptr<Application> app,
const ApplicationManager& app_mngr);
};
@@ -281,6 +388,9 @@ class TTSHmiState : public HmiState {
virtual mobile_apis::AudioStreamingState::eType audio_streaming_state()
const OVERRIDE;
+
+ virtual mobile_apis::AudioStreamingState::eType max_audio_streaming_state()
+ const OVERRIDE;
};
/**
@@ -294,6 +404,9 @@ class VideoStreamingHmiState : public HmiState {
mobile_apis::VideoStreamingState::eType video_streaming_state()
const OVERRIDE;
+
+ mobile_apis::VideoStreamingState::eType max_video_streaming_state()
+ const OVERRIDE;
};
/**
@@ -307,6 +420,9 @@ class NaviStreamingHmiState : public VideoStreamingHmiState {
mobile_apis::AudioStreamingState::eType audio_streaming_state()
const OVERRIDE;
+
+ mobile_apis::AudioStreamingState::eType max_audio_streaming_state()
+ const OVERRIDE;
};
/**
@@ -323,6 +439,12 @@ class PhoneCallHmiState : public HmiState {
const OVERRIDE {
return mobile_apis::AudioStreamingState::NOT_AUDIBLE;
}
+
+ mobile_apis::HMILevel::eType max_hmi_level() const OVERRIDE;
+ mobile_apis::AudioStreamingState::eType max_audio_streaming_state()
+ const OVERRIDE {
+ return audio_streaming_state();
+ }
};
/**
@@ -342,6 +464,15 @@ class SafetyModeHmiState : public HmiState {
const OVERRIDE {
return mobile_apis::VideoStreamingState::NOT_STREAMABLE;
}
+
+ mobile_apis::AudioStreamingState::eType max_audio_streaming_state()
+ const OVERRIDE {
+ return audio_streaming_state();
+ }
+ mobile_apis::VideoStreamingState::eType max_video_streaming_state()
+ const OVERRIDE {
+ return video_streaming_state();
+ }
};
/**
@@ -362,6 +493,16 @@ class DeactivateHMI : public HmiState {
const OVERRIDE {
return mobile_apis::VideoStreamingState::NOT_STREAMABLE;
}
+
+ mobile_apis::HMILevel::eType max_hmi_level() const OVERRIDE;
+ mobile_apis::AudioStreamingState::eType max_audio_streaming_state()
+ const OVERRIDE {
+ return audio_streaming_state();
+ }
+ mobile_apis::VideoStreamingState::eType max_video_streaming_state()
+ const OVERRIDE {
+ return video_streaming_state();
+ }
};
/**
@@ -375,13 +516,15 @@ class AudioSource : public HmiState {
mobile_apis::HMILevel::eType hmi_level() const OVERRIDE;
mobile_apis::AudioStreamingState::eType audio_streaming_state()
- const OVERRIDE {
- return mobile_apis::AudioStreamingState::NOT_AUDIBLE;
- }
+ const OVERRIDE;
mobile_apis::VideoStreamingState::eType video_streaming_state()
- const OVERRIDE {
- return mobile_apis::VideoStreamingState::NOT_STREAMABLE;
- }
+ const OVERRIDE;
+
+ mobile_apis::HMILevel::eType max_hmi_level() const OVERRIDE;
+ mobile_apis::AudioStreamingState::eType max_audio_streaming_state()
+ const OVERRIDE;
+ mobile_apis::VideoStreamingState::eType max_video_streaming_state()
+ const OVERRIDE;
private:
bool keep_context_;
@@ -399,13 +542,15 @@ class EmbeddedNavi : public HmiState {
mobile_apis::HMILevel::eType hmi_level() const OVERRIDE;
mobile_apis::AudioStreamingState::eType audio_streaming_state()
- const OVERRIDE {
- return mobile_apis::AudioStreamingState::NOT_AUDIBLE;
- }
+ const OVERRIDE;
mobile_apis::VideoStreamingState::eType video_streaming_state()
- const OVERRIDE {
- return mobile_apis::VideoStreamingState::NOT_STREAMABLE;
- }
+ const OVERRIDE;
+
+ mobile_apis::HMILevel::eType max_hmi_level() const OVERRIDE;
+ mobile_apis::AudioStreamingState::eType max_audio_streaming_state()
+ const OVERRIDE;
+ mobile_apis::VideoStreamingState::eType max_video_streaming_state()
+ const OVERRIDE;
};
/**
diff --git a/src/components/application_manager/src/application_state.cc b/src/components/application_manager/src/application_state.cc
index 6b440fad89..2fb583ab3e 100644
--- a/src/components/application_manager/src/application_state.cc
+++ b/src/components/application_manager/src/application_state.cc
@@ -173,10 +173,14 @@ void ApplicationState::AddHMIState(const WindowID window_id,
if (hmi_states.end() != it) {
SDL_LOG_WARN("Hmi state with ID "
<< state->state_id() << "has been already applied for window "
- << window_id << " of this application. Ignoring");
- return;
+ << window_id << " of this application. Overwriting");
+ EraseHMIState(hmi_states, it);
}
+ if (!hmi_states.empty()) {
+ HmiStatePtr back_state = hmi_states.back();
+ state->set_parent(back_state);
+ }
hmi_states.push_back(state);
}
@@ -185,6 +189,8 @@ void ApplicationState::RemoveHMIState(const WindowID window_id,
SDL_LOG_AUTO_TRACE();
sync_primitives::AutoLock auto_lock(hmi_states_map_lock_);
HmiStates& hmi_states = hmi_states_map_[window_id];
+ // unable to remove regular state
+ DCHECK_OR_RETURN_VOID(state_id != HmiState::StateID::STATE_ID_REGULAR);
HmiStates::iterator it = std::find_if(
hmi_states.begin(), hmi_states.end(), StateIDComparator(state_id));
if (hmi_states.end() == it) {
@@ -193,17 +199,24 @@ void ApplicationState::RemoveHMIState(const WindowID window_id,
return;
}
- // unable to remove regular state
- DCHECK_OR_RETURN_VOID(hmi_states.begin() != it);
- HmiStates::iterator next = it;
- HmiStates::iterator prev = it;
- next++;
- prev--;
-
- if (next != hmi_states.end()) {
- HmiStatePtr next_state = *next;
- HmiStatePtr prev_state = *prev;
- next_state->set_parent(prev_state);
+ EraseHMIState(hmi_states, it);
+}
+
+void ApplicationState::EraseHMIState(HmiStates& hmi_states,
+ HmiStates::iterator it) {
+ if (hmi_states.begin() == it) {
+ (*it)->set_parent(nullptr);
+ } else {
+ HmiStates::iterator next = it;
+ HmiStates::iterator prev = it;
+ next++;
+ prev--;
+
+ if (hmi_states.end() != next) {
+ HmiStatePtr next_state = *next;
+ HmiStatePtr prev_state = *prev;
+ next_state->set_parent(prev_state);
+ }
}
hmi_states.erase(it);
@@ -223,21 +236,11 @@ void ApplicationState::RemoveWindowHMIStates(const WindowID window_id) {
void ApplicationState::RemovePostponedState(const WindowID window_id) {
SDL_LOG_AUTO_TRACE();
- sync_primitives::AutoLock auto_lock(hmi_states_map_lock_);
- HmiStates& hmi_states = hmi_states_map_[window_id];
- DCHECK_OR_RETURN_VOID(!hmi_states.empty());
-
- StateIDComparator finder(HmiState::StateID::STATE_ID_POSTPONED);
-
- HmiStates::iterator postponed_state =
- std::find_if(hmi_states.begin(), hmi_states.end(), finder);
-
- if (hmi_states.end() == postponed_state) {
+ sync_primitives::AutoLock auto_lock(postponed_states_map_lock_);
+ size_t deleted_elements = postponed_states_map_.erase(window_id);
+ if (0 == deleted_elements) {
SDL_LOG_ERROR("No postponed state is set for window " << window_id);
- return;
}
-
- hmi_states.erase(postponed_state);
}
void ApplicationState::SetRegularState(const WindowID window_id,
@@ -250,27 +253,21 @@ void ApplicationState::SetRegularState(const WindowID window_id,
HmiStates& hmi_states = hmi_states_map_[window_id];
DCHECK_OR_RETURN_VOID(!hmi_states.empty());
- HmiStatePtr front_state = hmi_states.front();
- HmiState::StateID front_state_id = front_state->state_id();
- if (HmiState::StateID::STATE_ID_POSTPONED == front_state_id) {
- // Drop postponed state
- hmi_states.erase(hmi_states.begin());
- }
-
// Drop regular state
- hmi_states.erase(hmi_states.begin());
+ HmiStates::iterator it =
+ std::find_if(hmi_states.begin(),
+ hmi_states.end(),
+ StateIDComparator(HmiState::StateID::STATE_ID_REGULAR));
+ DCHECK_OR_RETURN_VOID(hmi_states.end() != it);
+ EraseHMIState(hmi_states, it);
if (!hmi_states.empty()) {
- HmiStatePtr front_state = hmi_states.front();
- front_state->set_parent(state);
+ HmiStatePtr back_state = hmi_states.back();
+ state->set_parent(back_state);
}
// Insert new regular state
- hmi_states.insert(hmi_states.begin(), state);
- if (HmiState::StateID::STATE_ID_POSTPONED == front_state_id) {
- // Restore postponed state if it was before
- hmi_states.insert(hmi_states.begin(), front_state);
- }
+ hmi_states.push_back(state);
}
void ApplicationState::SetPostponedState(const WindowID window_id,
@@ -280,15 +277,8 @@ void ApplicationState::SetPostponedState(const WindowID window_id,
DCHECK_OR_RETURN_VOID(state->state_id() ==
HmiState::StateID::STATE_ID_POSTPONED);
- sync_primitives::AutoLock auto_lock(hmi_states_map_lock_);
- HmiStates& hmi_states = hmi_states_map_[window_id];
- DCHECK_OR_RETURN_VOID(!hmi_states.empty());
- HmiStatePtr front_state = hmi_states.front();
- if (front_state->state_id() == HmiState::StateID::STATE_ID_POSTPONED) {
- hmi_states.erase(hmi_states.begin());
- }
-
- hmi_states.insert(hmi_states.begin(), state);
+ sync_primitives::AutoLock auto_lock(postponed_states_map_lock_);
+ postponed_states_map_[window_id] = state;
}
HmiStatePtr ApplicationState::CurrentHmiState(const WindowID window_id) const {
@@ -300,9 +290,6 @@ HmiStatePtr ApplicationState::CurrentHmiState(const WindowID window_id) const {
DCHECK_OR_RETURN(!hmi_states.empty(), HmiStatePtr());
HmiStatePtr back_state = hmi_states.back();
- DCHECK_OR_RETURN(
- back_state->state_id() != HmiState::StateID::STATE_ID_POSTPONED,
- HmiStatePtr());
return back_state;
}
@@ -314,28 +301,21 @@ HmiStatePtr ApplicationState::RegularHmiState(const WindowID window_id) const {
const HmiStates& hmi_states = it_states->second;
DCHECK_OR_RETURN(!hmi_states.empty(), HmiStatePtr());
+ auto it =
+ std::find_if(hmi_states.begin(),
+ hmi_states.end(),
+ StateIDComparator(HmiState::StateID::STATE_ID_REGULAR));
+ DCHECK_OR_RETURN(hmi_states.end() != it, HmiStatePtr());
- HmiStates::const_iterator front_itr = hmi_states.begin();
- if ((*front_itr)->state_id() == HmiState::StateID::STATE_ID_POSTPONED) {
- ++front_itr;
- }
-
- return *front_itr;
+ return *it;
}
HmiStatePtr ApplicationState::PostponedHmiState(
const WindowID window_id) const {
- sync_primitives::AutoLock auto_lock(hmi_states_map_lock_);
- auto it_states = hmi_states_map_.find(window_id);
- DCHECK_OR_RETURN(it_states != hmi_states_map_.end(), HmiStatePtr());
-
- const HmiStates& hmi_states = it_states->second;
- DCHECK_OR_RETURN(!hmi_states.empty(), HmiStatePtr());
+ sync_primitives::AutoLock auto_lock(postponed_states_map_lock_);
- HmiStatePtr front_state = hmi_states.front();
- return front_state->state_id() == HmiState::StateID::STATE_ID_POSTPONED
- ? front_state
- : HmiStatePtr();
+ auto it = postponed_states_map_.find(window_id);
+ return it != postponed_states_map_.end() ? it->second : HmiStatePtr();
}
} // namespace application_manager
diff --git a/src/components/application_manager/src/hmi_state.cc b/src/components/application_manager/src/hmi_state.cc
index d9ae6631a3..3dadd8c193 100644
--- a/src/components/application_manager/src/hmi_state.cc
+++ b/src/components/application_manager/src/hmi_state.cc
@@ -32,9 +32,11 @@
*/
#include "application_manager/hmi_state.h"
+
#include <boost/assign.hpp>
#include <boost/bimap.hpp>
#include <ostream>
+
#include "application_manager/application_manager.h"
#include "utils/helpers.h"
@@ -70,7 +72,6 @@ HmiState::HmiState(std::shared_ptr<Application> app,
}
void HmiState::set_parent(HmiStatePtr parent) {
- DCHECK_OR_RETURN_VOID(parent);
parent_ = parent;
}
@@ -80,6 +81,12 @@ bool HmiState::is_navi_app() const {
return app ? app->is_navi() : false;
}
+bool HmiState::is_projection_app() const {
+ const ApplicationSharedPtr app =
+ app_mngr_.application_by_hmi_app(hmi_app_id_);
+ return app ? app->mobile_projection_enabled() : false;
+}
+
bool HmiState::is_media_app() const {
const ApplicationSharedPtr app =
app_mngr_.application_by_hmi_app(hmi_app_id_);
@@ -98,6 +105,42 @@ bool HmiState::is_mobile_projection_app() const {
return app ? app->mobile_projection_enabled() : false;
}
+mobile_apis::HMILevel::eType HmiState::parent_hmi_level() const {
+ using namespace mobile_apis;
+ return parent() ? parent()->hmi_level() : HMILevel::HMI_NONE;
+}
+
+mobile_apis::HMILevel::eType HmiState::parent_max_hmi_level() const {
+ using namespace mobile_apis;
+ return parent() ? parent()->max_hmi_level() : HMILevel::HMI_FULL;
+}
+
+mobile_apis::AudioStreamingState::eType HmiState::parent_audio_state() const {
+ using namespace mobile_apis;
+ return parent() ? parent()->audio_streaming_state()
+ : AudioStreamingState::NOT_AUDIBLE;
+}
+
+mobile_apis::AudioStreamingState::eType HmiState::parent_max_audio_state()
+ const {
+ using namespace mobile_apis;
+ return parent() ? parent()->max_audio_streaming_state()
+ : AudioStreamingState::AUDIBLE;
+}
+
+mobile_apis::VideoStreamingState::eType HmiState::parent_video_state() const {
+ using namespace mobile_apis;
+ return parent() ? parent()->video_streaming_state()
+ : VideoStreamingState::NOT_STREAMABLE;
+}
+
+mobile_apis::VideoStreamingState::eType HmiState::parent_max_video_state()
+ const {
+ using namespace mobile_apis;
+ return parent() ? parent()->max_video_streaming_state()
+ : VideoStreamingState::STREAMABLE;
+}
+
mobile_apis::WindowType::eType HmiState::window_type() const {
return window_type_;
}
@@ -113,6 +156,12 @@ mobile_apis::AudioStreamingState::eType VRHmiState::audio_streaming_state()
return AudioStreamingState::NOT_AUDIBLE;
}
+mobile_apis::AudioStreamingState::eType VRHmiState::max_audio_streaming_state()
+ const {
+ using namespace mobile_apis;
+ return AudioStreamingState::NOT_AUDIBLE;
+}
+
VRHmiState::VRHmiState(std::shared_ptr<Application> app,
const ApplicationManager& app_mngr)
: HmiState(app, app_mngr, STATE_ID_VR_SESSION) {}
@@ -126,14 +175,21 @@ mobile_apis::AudioStreamingState::eType TTSHmiState::audio_streaming_state()
using namespace helpers;
using namespace mobile_apis;
- AudioStreamingState::eType expected_state = AudioStreamingState::NOT_AUDIBLE;
- if (app_mngr_.is_attenuated_supported() &&
- AudioStreamingState::NOT_AUDIBLE != parent()->audio_streaming_state() &&
- Compare<HMILevel::eType, EQ, ONE>(
+ if (Compare<HMILevel::eType, EQ, ONE>(
hmi_level(), HMILevel::HMI_FULL, HMILevel::HMI_LIMITED)) {
- expected_state = AudioStreamingState::ATTENUATED;
+ return std::max(parent_audio_state(), max_audio_streaming_state());
+ }
+ return AudioStreamingState::NOT_AUDIBLE;
+}
+
+mobile_apis::AudioStreamingState::eType TTSHmiState::max_audio_streaming_state()
+ const {
+ using namespace mobile_apis;
+
+ if (app_mngr_.is_attenuated_supported()) {
+ return std::max(parent_max_audio_state(), AudioStreamingState::ATTENUATED);
}
- return expected_state;
+ return AudioStreamingState::NOT_AUDIBLE;
}
VideoStreamingHmiState::VideoStreamingHmiState(
@@ -142,13 +198,19 @@ VideoStreamingHmiState::VideoStreamingHmiState(
mobile_apis::VideoStreamingState::eType
VideoStreamingHmiState::video_streaming_state() const {
+ return std::max(parent_video_state(), max_video_streaming_state());
+}
+
+mobile_apis::VideoStreamingState::eType
+VideoStreamingHmiState::max_video_streaming_state() const {
+ using namespace mobile_apis;
const ApplicationSharedPtr app =
app_mngr_.application_by_hmi_app(hmi_app_id_);
if (app && app->IsVideoApplication()) {
- return parent()->video_streaming_state();
+ return std::max(parent_max_video_state(), VideoStreamingState::STREAMABLE);
}
- return mobile_apis::VideoStreamingState::NOT_STREAMABLE;
+ return VideoStreamingState::NOT_STREAMABLE;
}
NaviStreamingHmiState::NaviStreamingHmiState(std::shared_ptr<Application> app,
@@ -159,22 +221,20 @@ NaviStreamingHmiState::NaviStreamingHmiState(std::shared_ptr<Application> app,
mobile_apis::AudioStreamingState::eType
NaviStreamingHmiState::audio_streaming_state() const {
- using namespace helpers;
- using namespace mobile_apis;
+ return std::max(parent_audio_state(), max_audio_streaming_state());
+}
- AudioStreamingState::eType expected_state = parent()->audio_streaming_state();
- if (!is_navi_app() && Compare<AudioStreamingState::eType, EQ, ONE>(
- expected_state,
- AudioStreamingState::AUDIBLE,
- AudioStreamingState::ATTENUATED)) {
- if (app_mngr_.is_attenuated_supported()) {
- expected_state = AudioStreamingState::ATTENUATED;
- } else {
- expected_state = AudioStreamingState::NOT_AUDIBLE;
- }
+mobile_apis::AudioStreamingState::eType
+NaviStreamingHmiState::max_audio_streaming_state() const {
+ using namespace mobile_apis;
+ auto expected = AudioStreamingState::AUDIBLE;
+ if (!is_navi_app()) {
+ expected = app_mngr_.is_attenuated_supported()
+ ? AudioStreamingState::ATTENUATED
+ : AudioStreamingState::NOT_AUDIBLE;
}
- return expected_state;
+ return std::max(expected, parent_max_audio_state());
}
PhoneCallHmiState::PhoneCallHmiState(std::shared_ptr<Application> app,
@@ -182,28 +242,25 @@ PhoneCallHmiState::PhoneCallHmiState(std::shared_ptr<Application> app,
: HmiState(app, app_mngr, STATE_ID_PHONE_CALL) {}
mobile_apis::HMILevel::eType PhoneCallHmiState::hmi_level() const {
+ return std::max(parent_hmi_level(), max_hmi_level());
+}
+
+mobile_apis::HMILevel::eType PhoneCallHmiState::max_hmi_level() const {
using namespace helpers;
using namespace mobile_apis;
if (WindowType::WIDGET == window_type()) {
- return parent()->hmi_level();
- }
-
- if (Compare<HMILevel::eType, EQ, ONE>(parent()->hmi_level(),
- HMILevel::HMI_BACKGROUND,
- HMILevel::HMI_NONE)) {
- return parent()->hmi_level();
+ return std::max(HMILevel::HMI_FULL, parent_max_hmi_level());
}
+ auto expected = HMILevel::HMI_FULL;
if (is_navi_app() || is_mobile_projection_app()) {
- return HMILevel::HMI_LIMITED;
- }
-
- if (!is_media_app()) {
- return parent()->hmi_level();
+ expected = HMILevel::HMI_LIMITED;
+ } else if (is_media_app()) {
+ expected = HMILevel::HMI_BACKGROUND;
}
- return HMILevel::HMI_BACKGROUND;
+ return std::max(expected, parent_max_hmi_level());
}
SafetyModeHmiState::SafetyModeHmiState(std::shared_ptr<Application> app,
@@ -215,20 +272,18 @@ DeactivateHMI::DeactivateHMI(std::shared_ptr<Application> app,
: HmiState(app, app_mngr, STATE_ID_DEACTIVATE_HMI) {}
mobile_apis::HMILevel::eType DeactivateHMI::hmi_level() const {
+ return std::max(parent_hmi_level(), max_hmi_level());
+}
+
+mobile_apis::HMILevel::eType DeactivateHMI::max_hmi_level() const {
using namespace helpers;
using namespace mobile_apis;
if (WindowType::WIDGET == window_type()) {
- return parent()->hmi_level();
+ return std::max(HMILevel::HMI_FULL, parent_max_hmi_level());
}
- if (Compare<HMILevel::eType, EQ, ONE>(parent()->hmi_level(),
- HMILevel::HMI_BACKGROUND,
- HMILevel::HMI_NONE)) {
- return parent()->hmi_level();
- }
-
- return HMILevel::HMI_BACKGROUND;
+ return std::max(HMILevel::HMI_BACKGROUND, parent_max_hmi_level());
}
AudioSource::AudioSource(std::shared_ptr<Application> app,
@@ -241,38 +296,116 @@ AudioSource::AudioSource(std::shared_ptr<Application> app,
mobile_apis::HMILevel::eType AudioSource::hmi_level() const {
using namespace mobile_apis;
+ if (WindowType::WIDGET == window_type() || keep_context_) {
+ return std::max(parent_hmi_level(), max_hmi_level());
+ }
+
+ auto expected = HMILevel::HMI_BACKGROUND;
+ if (is_navi_app() || is_projection_app() || is_voice_communication_app()) {
+ expected = HMILevel::HMI_LIMITED;
+ }
+
+ return std::max(std::max(expected, max_hmi_level()), parent_hmi_level());
+}
+
+mobile_apis::AudioStreamingState::eType AudioSource::audio_streaming_state()
+ const {
+ return is_media_app() && !is_navi_app()
+ ? mobile_apis::AudioStreamingState::NOT_AUDIBLE
+ : parent_audio_state();
+}
+
+mobile_apis::VideoStreamingState::eType AudioSource::video_streaming_state()
+ const {
+ return parent_video_state();
+}
+
+mobile_apis::HMILevel::eType AudioSource::max_hmi_level() const {
+ using namespace mobile_apis;
+
if (WindowType::WIDGET == window_type()) {
- return parent()->hmi_level();
+ return std::max(HMILevel::HMI_FULL, parent_max_hmi_level());
}
- // Checking for NONE is necessary to avoid issue during
- // calculation of HMI level during setting default HMI level
- if (keep_context_ || HMILevel::HMI_NONE == parent()->hmi_level()) {
- return parent()->hmi_level();
+ auto expected = HMILevel::HMI_FULL;
+ if (!keep_context_ && is_media_app() && !is_navi_app() &&
+ !is_projection_app()) {
+ expected = HMILevel::HMI_BACKGROUND;
}
- return HMILevel::HMI_BACKGROUND;
+ return std::max(expected, parent_max_hmi_level());
+}
+
+mobile_apis::AudioStreamingState::eType AudioSource::max_audio_streaming_state()
+ const {
+ return is_media_app() && !is_navi_app()
+ ? mobile_apis::AudioStreamingState::NOT_AUDIBLE
+ : parent_max_audio_state();
+}
+
+mobile_apis::VideoStreamingState::eType AudioSource::max_video_streaming_state()
+ const {
+ return parent() ? parent()->max_video_streaming_state()
+ : mobile_apis::VideoStreamingState::STREAMABLE;
}
EmbeddedNavi::EmbeddedNavi(std::shared_ptr<Application> app,
const ApplicationManager& app_mngr)
: HmiState(app, app_mngr, STATE_ID_EMBEDDED_NAVI) {}
+mobile_apis::AudioStreamingState::eType EmbeddedNavi::audio_streaming_state()
+ const {
+ return is_navi_app() ? mobile_apis::AudioStreamingState::NOT_AUDIBLE
+ : parent_audio_state();
+}
+
+mobile_apis::VideoStreamingState::eType EmbeddedNavi::video_streaming_state()
+ const {
+ return mobile_apis::VideoStreamingState::NOT_STREAMABLE;
+}
+
mobile_apis::HMILevel::eType EmbeddedNavi::hmi_level() const {
using namespace mobile_apis;
using namespace helpers;
if (WindowType::WIDGET == window_type()) {
- return parent()->hmi_level();
+ return std::max(parent_hmi_level(), max_hmi_level());
+ }
+
+ auto expected = HMILevel::HMI_BACKGROUND;
+ if ((is_media_app() || is_voice_communication_app()) && !is_navi_app()) {
+ expected = HMILevel::HMI_LIMITED;
+ }
+
+ return std::max(std::max(expected, max_hmi_level()), parent_hmi_level());
+}
+
+mobile_apis::AudioStreamingState::eType
+EmbeddedNavi::max_audio_streaming_state() const {
+ return is_navi_app() ? mobile_apis::AudioStreamingState::NOT_AUDIBLE
+ : parent_max_audio_state();
+}
+
+mobile_apis::VideoStreamingState::eType
+EmbeddedNavi::max_video_streaming_state() const {
+ return is_navi_app() ? mobile_apis::VideoStreamingState::NOT_STREAMABLE
+ : parent_max_video_state();
+}
+
+mobile_apis::HMILevel::eType EmbeddedNavi::max_hmi_level() const {
+ using namespace mobile_apis;
+ using namespace helpers;
+
+ if (WindowType::WIDGET == window_type()) {
+ return std::max(HMILevel::HMI_FULL, parent_max_hmi_level());
}
- if (Compare<HMILevel::eType, EQ, ONE>(parent()->hmi_level(),
- HMILevel::HMI_BACKGROUND,
- HMILevel::HMI_NONE)) {
- return parent()->hmi_level();
+ auto expected = HMILevel::HMI_FULL;
+ if (is_navi_app()) {
+ expected = HMILevel::HMI_BACKGROUND;
}
- return HMILevel::HMI_BACKGROUND;
+ return std::max(expected, parent_max_hmi_level());
}
namespace {
diff --git a/src/components/application_manager/src/state_controller_impl.cc b/src/components/application_manager/src/state_controller_impl.cc
index 3cebc74a4a..a34149ef34 100644
--- a/src/components/application_manager/src/state_controller_impl.cc
+++ b/src/components/application_manager/src/state_controller_impl.cc
@@ -549,11 +549,18 @@ bool StateControllerImpl::IsStateAvailable(ApplicationSharedPtr app,
return IsStateAvailableForResumption(app, state);
}
- if (IsTempStateActive(HmiState::StateID::STATE_ID_AUDIO_SOURCE) ||
- IsTempStateActive(HmiState::StateID::STATE_ID_EMBEDDED_NAVI)) {
- if (HMILevel::HMI_FULL == state->hmi_level()) {
- SDL_LOG_DEBUG("AUDIO_SOURCE or EMBEDDED_NAVI is active."
- << " Requested state is not available");
+ if (HMILevel::HMI_FULL == state->hmi_level()) {
+ if (IsTempStateActive(HmiState::StateID::STATE_ID_AUDIO_SOURCE) &&
+ app->is_media_application()) {
+ SDL_LOG_DEBUG("Media app is not allowed to activate due"
+ << " to AUDIO_SOURCE event is active");
+ return false;
+ }
+
+ if (IsTempStateActive(HmiState::StateID::STATE_ID_EMBEDDED_NAVI) &&
+ app->is_navi()) {
+ SDL_LOG_DEBUG("Navi app is not allowed to activate due"
+ << " to EMBEDDED_NAVI event is active");
return false;
}
}
diff --git a/src/components/application_manager/test/application_impl_test.cc b/src/components/application_manager/test/application_impl_test.cc
index 1977044ce3..8411d1741e 100644
--- a/src/components/application_manager/test/application_impl_test.cc
+++ b/src/components/application_manager/test/application_impl_test.cc
@@ -260,8 +260,8 @@ TEST_F(ApplicationImplTest, AddStates_RemoveNotLastNotFirstState) {
app_impl->RemoveHMIState(kDefaultWindowId, state2->state_id());
HmiStatePtr current_state = app_impl->CurrentHmiState(kDefaultWindowId);
EXPECT_EQ(state3, current_state);
- // HMI level is equal to parent hmi_level
- EXPECT_EQ(HMILevel::HMI_FULL, current_state->hmi_level());
+ // HMI level is equal to state3 hmi_level
+ EXPECT_EQ(HMILevel::HMI_LIMITED, current_state->hmi_level());
EXPECT_EQ(HmiState::STATE_ID_TTS_SESSION, current_state->state_id());
EXPECT_EQ(state1, current_state->parent());
}
@@ -270,10 +270,9 @@ TEST_F(ApplicationImplTest, AddStates_RemoveFirstState) {
HmiStatePtr state1 = TestAddHmiState(HMILevel::HMI_FULL,
HmiState::STATE_ID_PHONE_CALL,
&ApplicationImpl::AddHMIState);
- // Second state
- TestAddHmiState(HMILevel::HMI_NONE,
- HmiState::STATE_ID_VIDEO_STREAMING,
- &ApplicationImpl::AddHMIState);
+ HmiStatePtr state2 = TestAddHmiState(HMILevel::HMI_NONE,
+ HmiState::STATE_ID_VIDEO_STREAMING,
+ &ApplicationImpl::AddHMIState);
HmiStatePtr state3 = TestAddHmiState(HMILevel::HMI_LIMITED,
HmiState::STATE_ID_TTS_SESSION,
&ApplicationImpl::AddHMIState);
@@ -286,7 +285,7 @@ TEST_F(ApplicationImplTest, AddStates_RemoveFirstState) {
// Last state does not have a parent
EXPECT_EQ(HMILevel::HMI_LIMITED, current_state->hmi_level());
EXPECT_EQ(HmiState::STATE_ID_TTS_SESSION, current_state->state_id());
- EXPECT_EQ(nullptr, current_state->parent());
+ EXPECT_EQ(state2, current_state->parent());
}
TEST_F(ApplicationImplTest, SetRegularState_RemoveFirstState) {
@@ -307,7 +306,7 @@ TEST_F(ApplicationImplTest, SetRegularState_RemoveFirstState) {
HmiStatePtr current_state = app_impl->CurrentHmiState(kDefaultWindowId);
EXPECT_EQ(state3, current_state);
// Last state has a parent
- EXPECT_EQ(HMILevel::HMI_FULL, current_state->hmi_level());
+ EXPECT_EQ(HMILevel::HMI_LIMITED, current_state->hmi_level());
EXPECT_EQ(HmiState::STATE_ID_TTS_SESSION, current_state->state_id());
EXPECT_EQ(state2, current_state->parent());
}
diff --git a/src/components/application_manager/test/application_state_test.cc b/src/components/application_manager/test/application_state_test.cc
index 22d111f926..b45b078ab3 100644
--- a/src/components/application_manager/test/application_state_test.cc
+++ b/src/components/application_manager/test/application_state_test.cc
@@ -47,6 +47,7 @@ namespace application_manager_test {
using namespace application_manager;
using namespace mobile_apis;
+using ::testing::Return;
typedef HmiState::StateID StateID;
namespace {
@@ -57,6 +58,7 @@ const std::string kDefaultWindowName = "DefaultName";
std::vector<StateID> GenerateCurrentStates() {
std::vector<StateID> states;
+ states.push_back(StateID::STATE_ID_REGULAR);
states.push_back(StateID::STATE_ID_PHONE_CALL);
states.push_back(StateID::STATE_ID_SAFETY_MODE);
states.push_back(StateID::STATE_ID_VR_SESSION);
@@ -71,11 +73,13 @@ class ApplicationStateTest : public ::testing::Test {
public:
void SetUp() OVERRIDE {
mock_app_.reset(new MockApplication);
+ EXPECT_CALL(*mock_app_, hmi_app_id()).WillRepeatedly(Return(0));
}
protected:
static std::vector<StateID> added_states_;
ApplicationState app_state;
+ HmiStatePtr initial_state_;
const StateID current_id = StateID::STATE_ID_CURRENT;
const StateID postponed_id = StateID::STATE_ID_POSTPONED;
std::shared_ptr<MockApplication> mock_app_;
@@ -87,6 +91,12 @@ std::vector<StateID> ApplicationStateTest::added_states_ =
TEST_F(ApplicationStateTest, AddStates_GetCurrentStates) {
std::vector<StateID>::iterator new_state = added_states_.begin();
+ initial_state_ = std::make_shared<HmiState>(
+ static_cast<std::shared_ptr<Application> >(mock_app_),
+ app_mngr_,
+ *new_state);
+ app_state.InitState(kDefaultWindowId, std::string(), initial_state_);
+ ++new_state;
for (; new_state != added_states_.end(); ++new_state) {
HmiStatePtr state = std::make_shared<HmiState>(
static_cast<std::shared_ptr<Application> >(mock_app_),
@@ -99,6 +109,12 @@ TEST_F(ApplicationStateTest, AddStates_GetCurrentStates) {
TEST_F(ApplicationStateTest, AddStates_RemoveStates_GetCurrentState) {
std::vector<StateID>::iterator new_state = added_states_.begin();
+ initial_state_ = std::make_shared<HmiState>(
+ static_cast<std::shared_ptr<Application> >(mock_app_),
+ app_mngr_,
+ *new_state);
+ app_state.InitState(kDefaultWindowId, std::string(), initial_state_);
+ ++new_state;
for (; new_state != added_states_.end(); ++new_state) {
HmiStatePtr state = std::make_shared<HmiState>(
static_cast<std::shared_ptr<Application> >(mock_app_),
@@ -122,6 +138,12 @@ TEST_F(ApplicationStateTest, AddStates_RemoveStates_GetCurrentState) {
TEST_F(ApplicationStateTest, AddStatesAddPostponedState_GetPostponedState) {
// Added some states
std::vector<StateID>::iterator new_state = added_states_.begin();
+ initial_state_ = std::make_shared<HmiState>(
+ static_cast<std::shared_ptr<Application> >(mock_app_),
+ app_mngr_,
+ *new_state);
+ app_state.InitState(kDefaultWindowId, std::string(), initial_state_);
+ ++new_state;
for (; new_state != added_states_.end(); ++new_state) {
HmiStatePtr state = std::make_shared<HmiState>(
static_cast<std::shared_ptr<Application> >(mock_app_),
@@ -147,16 +169,16 @@ TEST_F(ApplicationStateTest, AddStatesAddPostponedState_GetPostponedState) {
TEST_F(ApplicationStateTest, AddStates_GetRegularState) {
// Add state
std::vector<StateID>::iterator new_state = added_states_.begin();
- HmiStatePtr state = std::make_shared<HmiState>(
+ initial_state_ = std::make_shared<HmiState>(
static_cast<std::shared_ptr<Application> >(mock_app_),
app_mngr_,
*new_state);
- state->set_hmi_level(HMILevel::HMI_FULL);
- app_state.AddState(kDefaultWindowId, state);
+ initial_state_->set_hmi_level(HMILevel::HMI_FULL);
+ app_state.InitState(kDefaultWindowId, std::string(), initial_state_);
++new_state;
// Add some other
for (; new_state != added_states_.end(); ++new_state) {
- state = std::make_shared<HmiState>(
+ HmiStatePtr state = std::make_shared<HmiState>(
static_cast<std::shared_ptr<Application> >(mock_app_),
app_mngr_,
*new_state);
@@ -165,24 +187,25 @@ TEST_F(ApplicationStateTest, AddStates_GetRegularState) {
}
// Regular state will be the first added state
- new_state = added_states_.begin();
HmiStatePtr reg_state =
app_state.GetState(kDefaultWindowId, StateID::STATE_ID_REGULAR);
- EXPECT_EQ(*new_state, reg_state->state_id());
+ EXPECT_EQ(StateID::STATE_ID_REGULAR, reg_state->state_id());
EXPECT_EQ(HMILevel::HMI_FULL, reg_state->hmi_level());
}
-TEST_F(ApplicationStateTest, AddRegularState_RemoveFirstState_GetRegularState) {
+TEST_F(ApplicationStateTest,
+ AddRegularState_ReplaceFirstState_GetRegularState) {
std::vector<StateID>::iterator new_state = added_states_.begin();
- HmiStatePtr state = std::make_shared<HmiState>(
+ initial_state_ = std::make_shared<HmiState>(
static_cast<std::shared_ptr<Application> >(mock_app_),
app_mngr_,
*new_state);
- app_state.AddState(kDefaultWindowId, state);
+ initial_state_->set_hmi_level(HMILevel::HMI_FULL);
+ app_state.InitState(kDefaultWindowId, std::string(), initial_state_);
++new_state;
// Add postponed state
- state = std::make_shared<HmiState>(
+ HmiStatePtr state = std::make_shared<HmiState>(
static_cast<std::shared_ptr<Application> >(mock_app_),
app_mngr_,
postponed_id);
@@ -201,91 +224,92 @@ TEST_F(ApplicationStateTest, AddRegularState_RemoveFirstState_GetRegularState) {
}
// Regular state will be the first added state
- new_state = added_states_.begin();
HmiStatePtr reg_state =
app_state.GetState(kDefaultWindowId, StateID::STATE_ID_REGULAR);
- ASSERT_EQ(*new_state, reg_state->state_id());
+ ASSERT_EQ(StateID::STATE_ID_REGULAR, reg_state->state_id());
+ EXPECT_EQ(HMILevel::HMI_FULL, reg_state->hmi_level());
- app_state.RemoveState(kDefaultWindowId, *new_state);
+ state = std::make_shared<HmiState>(
+ static_cast<std::shared_ptr<Application> >(mock_app_),
+ app_mngr_,
+ StateID::STATE_ID_REGULAR);
+ state->set_hmi_level(HMILevel::HMI_BACKGROUND);
+ app_state.AddState(kDefaultWindowId, state);
- ++new_state;
- // Now regular state is the next state except postponed
+ // Regular state was replaced
reg_state = app_state.GetState(kDefaultWindowId, StateID::STATE_ID_REGULAR);
- EXPECT_EQ(*new_state, reg_state->state_id());
+ EXPECT_EQ(StateID::STATE_ID_REGULAR, reg_state->state_id());
+ EXPECT_EQ(HMILevel::HMI_BACKGROUND, reg_state->hmi_level());
}
TEST_F(ApplicationStateTest, AddRegularState_PreviousStatePostponed) {
- // Add some state
- StateID first_state = StateID::STATE_ID_PHONE_CALL;
- HmiStatePtr state = std::make_shared<HmiState>(
+ // Add initial state
+ StateID first_state = StateID::STATE_ID_REGULAR;
+ initial_state_ = std::make_shared<HmiState>(
static_cast<std::shared_ptr<Application> >(mock_app_),
app_mngr_,
first_state);
- app_state.AddState(kDefaultWindowId, state);
+ initial_state_->set_hmi_level(HMILevel::HMI_BACKGROUND);
+ app_state.InitState(kDefaultWindowId, std::string(), initial_state_);
// Add postponed state
- state = std::make_shared<HmiState>(
+ HmiStatePtr state = std::make_shared<HmiState>(
static_cast<std::shared_ptr<Application> >(mock_app_),
app_mngr_,
postponed_id);
+ state->set_hmi_level(HMILevel::HMI_LIMITED);
app_state.AddState(kDefaultWindowId, state);
// Add new postponed state
- std::shared_ptr<MockApplication> mock_app_2(new MockApplication);
state = std::make_shared<HmiState>(
static_cast<std::shared_ptr<Application> >(mock_app_),
app_mngr_,
postponed_id);
+ state->set_hmi_level(HMILevel::HMI_FULL);
app_state.AddState(kDefaultWindowId, state);
- // Add regular state
- state = std::make_shared<HmiState>(
- static_cast<std::shared_ptr<Application> >(mock_app_),
- app_mngr_,
- StateID::STATE_ID_REGULAR);
- app_state.AddState(kDefaultWindowId, state);
-
- // Postponed state is the first
- HmiStatePtr reg_state =
- app_state.GetState(kDefaultWindowId, StateID::STATE_ID_POSTPONED);
+ // Postponed state is returned
+ HmiStatePtr reg_state = app_state.GetState(kDefaultWindowId, postponed_id);
ASSERT_EQ(postponed_id, reg_state->state_id());
+ EXPECT_EQ(HMILevel::HMI_FULL, reg_state->hmi_level());
- // Regular state is the second one
+ // Regular state is returned
reg_state = app_state.GetState(kDefaultWindowId, StateID::STATE_ID_REGULAR);
EXPECT_EQ(StateID::STATE_ID_REGULAR, reg_state->state_id());
+ EXPECT_EQ(HMILevel::HMI_BACKGROUND, reg_state->hmi_level());
}
TEST_F(ApplicationStateTest, InitState_GetRegularState) {
StateID init_state = StateID::STATE_ID_REGULAR;
- HmiStatePtr state = std::make_shared<HmiState>(
+ initial_state_ = std::make_shared<HmiState>(
static_cast<std::shared_ptr<Application> >(mock_app_),
app_mngr_,
init_state);
- app_state.InitState(kDefaultWindowId, kDefaultWindowName, state);
+ app_state.InitState(kDefaultWindowId, kDefaultWindowName, initial_state_);
HmiStatePtr reg_state =
app_state.GetState(kDefaultWindowId, StateID::STATE_ID_REGULAR);
- EXPECT_EQ(state, reg_state);
+ EXPECT_EQ(initial_state_, reg_state);
HmiStatePtr curr_state =
app_state.GetState(kDefaultWindowId, StateID::STATE_ID_CURRENT);
- EXPECT_EQ(state, curr_state);
+ EXPECT_EQ(initial_state_, curr_state);
}
-TEST_F(ApplicationStateTest, AddPosponedState_DeletePosponedState) {
+TEST_F(ApplicationStateTest, AddPostponedState_DeletePosponedState) {
// Precondition
StateID init_state = StateID::STATE_ID_REGULAR;
- HmiStatePtr state = std::make_shared<HmiState>(
+ initial_state_ = std::make_shared<HmiState>(
static_cast<std::shared_ptr<Application> >(mock_app_),
app_mngr_,
init_state);
- state->set_hmi_level(mobile_apis::HMILevel::HMI_FULL);
+ initial_state_->set_hmi_level(mobile_apis::HMILevel::HMI_FULL);
- app_state.InitState(kDefaultWindowId, kDefaultWindowName, state);
+ app_state.InitState(kDefaultWindowId, kDefaultWindowName, initial_state_);
// Add postponed state
- state = std::make_shared<HmiState>(
+ HmiStatePtr state = std::make_shared<HmiState>(
static_cast<std::shared_ptr<Application> >(mock_app_),
app_mngr_,
postponed_id);
@@ -305,19 +329,19 @@ TEST_F(ApplicationStateTest, AddPosponedState_DeletePosponedState) {
TEST_F(ApplicationStateTest,
AddRegularState_RemoveRegularState_RegularStateNotDeleted) {
- StateID reg_state = StateID::STATE_ID_REGULAR;
- HmiStatePtr state = std::make_shared<HmiState>(
+ StateID init_state = StateID::STATE_ID_REGULAR;
+ initial_state_ = std::make_shared<HmiState>(
static_cast<std::shared_ptr<Application> >(mock_app_),
app_mngr_,
- reg_state);
- app_state.InitState(kDefaultWindowId, kDefaultWindowName, state);
+ init_state);
+ app_state.InitState(kDefaultWindowId, kDefaultWindowName, initial_state_);
// Try deleting regular state
- app_state.RemoveState(kDefaultWindowId, reg_state);
+ app_state.RemoveState(kDefaultWindowId, init_state);
// Get regular state
- HmiStatePtr get_reg_state = app_state.GetState(kDefaultWindowId, reg_state);
- EXPECT_EQ(state, get_reg_state);
+ HmiStatePtr get_reg_state = app_state.GetState(kDefaultWindowId, init_state);
+ EXPECT_EQ(initial_state_, get_reg_state);
}
} // namespace application_manager_test
diff --git a/src/components/application_manager/test/state_controller/state_controller_test.cc b/src/components/application_manager/test/state_controller/state_controller_test.cc
index e9bce76fc5..36dc22a13f 100644
--- a/src/components/application_manager/test/state_controller/state_controller_test.cc
+++ b/src/components/application_manager/test/state_controller/state_controller_test.cc
@@ -238,6 +238,7 @@ class StateControllerImplTest : public ::testing::Test {
std::vector<am::HmiStatePtr> invalid_states_for_not_audio_app;
std::vector<am::HmiStatePtr> invalid_states_for_audio_app;
std::vector<am::HmiState::StateID> valid_state_ids_;
+ std::vector<am::HmiState::StateID> valid_non_navi_state_ids_;
typedef std::map<am::ApplicationSharedPtr,
NiceMock<application_manager_test::MockApplication>*>
@@ -524,7 +525,7 @@ class StateControllerImplTest : public ::testing::Test {
SystemContext::SYSCTXT_MAIN));
result_hmi_state.push_back(
createHmiState(HMILevel::HMI_LIMITED,
- AudioStreamingState::ATTENUATED,
+ AudioStreamingState::NOT_AUDIBLE,
VideoStreamingState::NOT_STREAMABLE,
SystemContext::SYSCTXT_MAIN));
result_hmi_state.push_back(
@@ -543,6 +544,10 @@ class StateControllerImplTest : public ::testing::Test {
result_hmi_state = valid_states_for_audio_app_;
break;
}
+ case APP_TYPE_ATTENUATED: {
+ PrepareStateResultsForAttenuated(result_hmi_state);
+ break;
+ }
default: { break; }
}
}
@@ -914,6 +919,15 @@ class StateControllerImplTest : public ::testing::Test {
valid_state_ids_.push_back(am::HmiState::StateID::STATE_ID_PHONE_CALL);
valid_state_ids_.push_back(am::HmiState::StateID::STATE_ID_SAFETY_MODE);
valid_state_ids_.push_back(am::HmiState::StateID::STATE_ID_NAVI_STREAMING);
+
+ valid_non_navi_state_ids_.push_back(
+ am::HmiState::StateID::STATE_ID_VR_SESSION);
+ valid_non_navi_state_ids_.push_back(
+ am::HmiState::StateID::STATE_ID_TTS_SESSION);
+ valid_non_navi_state_ids_.push_back(
+ am::HmiState::StateID::STATE_ID_PHONE_CALL);
+ valid_non_navi_state_ids_.push_back(
+ am::HmiState::StateID::STATE_ID_SAFETY_MODE);
}
void ConfigureApps() {
@@ -1224,6 +1238,13 @@ class StateControllerImplTest : public ::testing::Test {
mobile_apis::SystemContext::SYSCTXT_MAIN);
}
+ am::HmiStatePtr FullAudibleStreamableState() {
+ return createHmiState(mobile_apis::HMILevel::HMI_FULL,
+ mobile_apis::AudioStreamingState::AUDIBLE,
+ mobile_apis::VideoStreamingState::STREAMABLE,
+ mobile_apis::SystemContext::SYSCTXT_MAIN);
+ }
+
am::HmiStatePtr FullNotAudibleState() {
return createHmiState(mobile_apis::HMILevel::HMI_FULL,
mobile_apis::AudioStreamingState::NOT_AUDIBLE,
@@ -2199,8 +2220,7 @@ TEST_F(StateControllerImplTest,
media_navi_vc_app_, kDefaultWindowId, FullAudibleState(), false);
}
-// TODO {AKozoriz} Changed logic in state_controller
-TEST_F(StateControllerImplTest, DISABLED_ActivateAppSuccessReceivedFromHMI) {
+TEST_F(StateControllerImplTest, ActivateAppSuccessReceivedFromHMI) {
using namespace hmi_apis;
using namespace mobile_apis;
@@ -2342,16 +2362,16 @@ TEST_F(StateControllerImplTest, ActivateAppInvalidCorrelationId) {
state_ctrl_->on_event(event);
}
-TEST_F(StateControllerImplTest, DISABLED_ApplyTempStatesForSimpleApp) {
+TEST_F(StateControllerImplTest, ApplyTempStatesForSimpleApp) {
InsertApplication(simple_app_);
CheckStateApplyingForApplication(
- simple_app_, *simple_app_ptr_, valid_state_ids_);
+ simple_app_, *simple_app_ptr_, valid_non_navi_state_ids_);
}
-TEST_F(StateControllerImplTest, DISABLED_ApplyTempStatesForMediaApp) {
+TEST_F(StateControllerImplTest, ApplyTempStatesForMediaApp) {
InsertApplication(media_app_);
CheckStateApplyingForApplication(
- media_app_, *media_app_ptr_, valid_state_ids_);
+ media_app_, *media_app_ptr_, valid_non_navi_state_ids_);
}
TEST_F(StateControllerImplTest, ApplyTempStatesForNaviApp) {
@@ -2359,9 +2379,10 @@ TEST_F(StateControllerImplTest, ApplyTempStatesForNaviApp) {
CheckStateApplyingForApplication(navi_app_, *navi_app_ptr_, valid_state_ids_);
}
-TEST_F(StateControllerImplTest, DISABLED_ApplyTempStatesForVCApp) {
+TEST_F(StateControllerImplTest, ApplyTempStatesForVCApp) {
InsertApplication(vc_app_);
- CheckStateApplyingForApplication(vc_app_, *vc_app_ptr_, valid_state_ids_);
+ CheckStateApplyingForApplication(
+ vc_app_, *vc_app_ptr_, valid_non_navi_state_ids_);
}
TEST_F(StateControllerImplTest, ApplyTempStatesForMediaNaviApp) {
@@ -2370,10 +2391,10 @@ TEST_F(StateControllerImplTest, ApplyTempStatesForMediaNaviApp) {
media_navi_app_, *media_navi_app_ptr_, valid_state_ids_);
}
-TEST_F(StateControllerImplTest, DISABLED_ApplyTempStatesForMediaVCApp) {
+TEST_F(StateControllerImplTest, ApplyTempStatesForMediaVCApp) {
InsertApplication(media_vc_app_);
CheckStateApplyingForApplication(
- media_vc_app_, *media_vc_app_ptr_, valid_state_ids_);
+ media_vc_app_, *media_vc_app_ptr_, valid_non_navi_state_ids_);
}
TEST_F(StateControllerImplTest, ApplyTempStatesForNaviVCApp) {
@@ -2515,82 +2536,80 @@ TEST_F(StateControllerImplTest,
}
TEST_F(StateControllerImplTest, SetNaviStreamingStateForNonMediaApplication) {
- am::HmiStatePtr state_navi_streming =
- std::make_shared<am::VideoStreamingHmiState>(simple_app_,
- app_manager_mock_);
+ am::HmiStatePtr state_navi_streaming =
+ std::make_shared<am::NaviStreamingHmiState>(simple_app_,
+ app_manager_mock_);
TestSetState(simple_app_,
- state_navi_streming,
+ state_navi_streaming,
APP_TYPE_NON_MEDIA,
&StateControllerImplTest::PrepareNaviStreamingHMIStateResults);
}
TEST_F(StateControllerImplTest,
- DISABLED_SetNaviStreamingStateMediaApplicationAttenuatedNotSupported) {
- am::HmiStatePtr state_navi_streming =
- std::make_shared<am::VideoStreamingHmiState>(media_app_,
- app_manager_mock_);
+ SetNaviStreamingStateMediaApplicationAttenuatedNotSupported) {
+ am::HmiStatePtr state_navi_streaming =
+ std::make_shared<am::NaviStreamingHmiState>(media_app_,
+ app_manager_mock_);
EXPECT_CALL(app_manager_mock_, is_attenuated_supported())
.WillRepeatedly(Return(false));
TestSetState(media_app_,
- state_navi_streming,
+ state_navi_streaming,
APP_TYPE_MEDIA,
&StateControllerImplTest::PrepareNaviStreamingHMIStateResults);
}
TEST_F(StateControllerImplTest,
- DISABLED_SetNaviStreamingStateMediaApplicationAttenuatedSupported) {
- am::HmiStatePtr state_navi_streming =
- std::make_shared<am::VideoStreamingHmiState>(media_app_,
- app_manager_mock_);
+ SetNaviStreamingStateMediaApplicationAttenuatedSupported) {
+ am::HmiStatePtr state_navi_streaming =
+ std::make_shared<am::NaviStreamingHmiState>(media_app_,
+ app_manager_mock_);
EXPECT_CALL(app_manager_mock_, is_attenuated_supported())
.WillRepeatedly(Return(true));
TestSetState(media_app_,
- state_navi_streming,
+ state_navi_streaming,
APP_TYPE_ATTENUATED,
- &StateControllerImplTest::PrepareVRTTSHMIStateResults);
+ &StateControllerImplTest::PrepareNaviStreamingHMIStateResults);
}
TEST_F(StateControllerImplTest,
- DISABLED_SetNaviStreamingStateVCApplicationAttenuatedNotSupported) {
- am::HmiStatePtr state_navi_streming =
- std::make_shared<am::VideoStreamingHmiState>(vc_app_, app_manager_mock_);
+ SetNaviStreamingStateVCApplicationAttenuatedNotSupported) {
+ am::HmiStatePtr state_navi_streaming =
+ std::make_shared<am::NaviStreamingHmiState>(vc_app_, app_manager_mock_);
EXPECT_CALL(app_manager_mock_, is_attenuated_supported())
.WillRepeatedly(Return(false));
TestSetState(vc_app_,
- state_navi_streming,
+ state_navi_streaming,
APP_TYPE_MEDIA,
&StateControllerImplTest::PrepareNaviStreamingHMIStateResults);
}
TEST_F(StateControllerImplTest,
- DISABLED_SetNaviStreamingStateVCApplicationAttenuatedSupported) {
- am::HmiStatePtr state_navi_streming =
- std::make_shared<am::VideoStreamingHmiState>(vc_app_, app_manager_mock_);
+ SetNaviStreamingStateVCApplicationAttenuatedSupported) {
+ am::HmiStatePtr state_navi_streaming =
+ std::make_shared<am::NaviStreamingHmiState>(vc_app_, app_manager_mock_);
EXPECT_CALL(app_manager_mock_, is_attenuated_supported())
.WillRepeatedly(Return(true));
TestSetState(vc_app_,
- state_navi_streming,
+ state_navi_streaming,
APP_TYPE_ATTENUATED,
- &StateControllerImplTest::PrepareVRTTSHMIStateResults);
+ &StateControllerImplTest::PrepareNaviStreamingHMIStateResults);
}
-TEST_F(StateControllerImplTest, DISABLED_SetNaviStreamingStateNaviApplication) {
- am::HmiStatePtr state_navi_streming =
- std::make_shared<am::VideoStreamingHmiState>(navi_app_,
- app_manager_mock_);
+TEST_F(StateControllerImplTest, SetNaviStreamingStateNaviApplication) {
+ am::HmiStatePtr state_navi_streaming =
+ std::make_shared<am::NaviStreamingHmiState>(navi_app_, app_manager_mock_);
TestSetState(navi_app_,
- state_navi_streming,
+ state_navi_streaming,
APP_TYPE_NAVI,
&StateControllerImplTest::PrepareNaviStreamingHMIStateResults);
}
-TEST_F(StateControllerImplTest,
- DISABLED_SetNaviStreamingStateMediaNaviApplication) {
- am::HmiStatePtr state_navi_streming =
- std::make_shared<am::VideoStreamingHmiState>(media_navi_app_,
- app_manager_mock_);
+TEST_F(StateControllerImplTest, SetNaviStreamingStateMediaNaviApplication) {
+ am::HmiStatePtr state_navi_streaming =
+ std::make_shared<am::NaviStreamingHmiState>(media_navi_app_,
+ app_manager_mock_);
TestSetState(media_navi_app_,
- state_navi_streming,
+ state_navi_streaming,
APP_TYPE_NAVI,
&StateControllerImplTest::PrepareNaviStreamingHMIStateResults);
}
@@ -3166,6 +3185,8 @@ TEST_F(StateControllerImplTest,
EXPECT_CALL(*simple_app_ptr_, keep_context()).WillOnce(Return(true));
EXPECT_CALL(*simple_app_ptr_, IsAudioApplication())
.WillRepeatedly(Return(true));
+ EXPECT_CALL(*simple_app_ptr_, is_media_application())
+ .WillRepeatedly(Return(true));
EXPECT_CALL(*simple_app_ptr_, CurrentHmiState(kDefaultWindowId))
.WillOnce(Return(FullAudibleState()));
EXPECT_CALL(*simple_app_ptr_, set_keep_context(false));
@@ -3200,6 +3221,8 @@ TEST_F(StateControllerImplTest, OnEventChangedAudioSourceAppToBackground) {
EXPECT_CALL(*simple_app_ptr_, IsAudioApplication())
.WillRepeatedly(Return(true));
+ EXPECT_CALL(*simple_app_ptr_, is_media_application())
+ .WillRepeatedly(Return(true));
EXPECT_CALL(*simple_app_ptr_, CurrentHmiState(kDefaultWindowId))
.WillOnce(Return(LimitedState()));
@@ -3217,6 +3240,40 @@ TEST_F(StateControllerImplTest, OnEventChangedAudioSourceAppToBackground) {
mobile_apis::AudioStreamingState::NOT_AUDIBLE);
}
+TEST_F(StateControllerImplTest, OnEventChangedAudioSourceNavAppToLimited) {
+ const uint32_t app_id = navi_app_->app_id();
+ InsertApplication(navi_app_);
+ smart_objects::SmartObject msg;
+ msg[am::strings::msg_params][am::strings::app_id] = app_id;
+ msg[am::strings::msg_params][am::hmi_notification::is_active] = true;
+ msg[am::strings::msg_params][am::hmi_notification::event_name] =
+ hmi_apis::Common_EventTypes::AUDIO_SOURCE;
+
+ const hmi_apis::FunctionID::eType event_id =
+ hmi_apis::FunctionID::BasicCommunication_OnEventChanged;
+ am::event_engine::Event event(event_id);
+ event.set_smart_object(msg);
+
+ EXPECT_CALL(*navi_app_ptr_, is_navi()).WillRepeatedly(Return(true));
+ EXPECT_CALL(*navi_app_ptr_, CurrentHmiState(kDefaultWindowId))
+ .WillOnce(Return(FullAudibleStreamableState()));
+
+ HmiStatePtr new_state;
+ EXPECT_CALL(*navi_app_ptr_, AddHMIState(kDefaultWindowId, _))
+ .WillOnce(SaveArg<1>(&new_state));
+
+ am::WindowIds window_ids = {kDefaultWindowId};
+ EXPECT_CALL(*navi_app_ptr_, GetWindowIds()).WillOnce(Return(window_ids));
+
+ state_ctrl_->on_event(event);
+
+ EXPECT_EQ(new_state->hmi_level(), mobile_apis::HMILevel::HMI_LIMITED);
+ EXPECT_EQ(new_state->audio_streaming_state(),
+ mobile_apis::AudioStreamingState::AUDIBLE);
+ EXPECT_EQ(new_state->video_streaming_state(),
+ mobile_apis::VideoStreamingState::STREAMABLE);
+}
+
TEST_F(StateControllerImplTest, OnEventOnAppDeactivatedIncorrectHmiLevel) {
smart_objects::SmartObject msg;
const uint32_t app_id = simple_app_->app_id();