diff options
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(); |