diff options
author | Jacob Keeler <jacob.keeler@livioradio.com> | 2019-07-24 09:38:52 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-24 09:38:52 -0400 |
commit | 25a8ef5d2ec10d88a5eda53af85a2b746f401c05 (patch) | |
tree | 7b9384f59d2c6a59d0e298eb4a3d046949ca5314 | |
parent | a6d1390dab380805ef475552b63a95843ed97133 (diff) | |
parent | 2c83332223342252286f7d33520b83070259ef20 (diff) | |
download | sdl_core-25a8ef5d2ec10d88a5eda53af85a2b746f401c05.tar.gz |
Merge pull request #2783 from smartdevicelink/feature/sdl_passenger_mode
Feature/SDL passenger mode
44 files changed, 862 insertions, 95 deletions
diff --git a/src/appMain/sdl_preloaded_pt.json b/src/appMain/sdl_preloaded_pt.json index 2630d8bd8e..88bcafcd82 100644 --- a/src/appMain/sdl_preloaded_pt.json +++ b/src/appMain/sdl_preloaded_pt.json @@ -33,7 +33,8 @@ "COMMUNICATION": 6,
"NORMAL": 4,
"NONE": 0
- }
+ },
+ "lock_screen_dismissal_enabled": true
},
"functional_groupings": {
"Base-4": {
@@ -1919,6 +1920,13 @@ }
}
},
+ "LockScreenDismissalWarning":{
+ "languages":{
+ "en-us":{
+ "textBody": "Swipe down to dismiss, acknowledging that you are not the driver"
+ }
+ }
+ },
"Notifications": {
"languages": {
"de-de": {
diff --git a/src/components/application_manager/include/application_manager/message_helper.h b/src/components/application_manager/include/application_manager/message_helper.h index 2671278442..98992a20d5 100644 --- a/src/components/application_manager/include/application_manager/message_helper.h +++ b/src/components/application_manager/include/application_manager/message_helper.h @@ -726,6 +726,14 @@ class MessageHelper { hmi_apis::Common_Language::eType language); /** + * @brief Converts mobile language to string representation + * @param language Mobile UI language + * @return Mobile language string representation + */ + static std::string MobileLanguageToString( + mobile_apis::Language::eType language); + + /** * @brief Converts string to mobile language enum value * @param language language as string * @return Mobile language enum value diff --git a/src/components/application_manager/include/application_manager/policies/policy_handler.h b/src/components/application_manager/include/application_manager/policies/policy_handler.h index abffd3eebb..917f8be559 100644 --- a/src/components/application_manager/include/application_manager/policies/policy_handler.h +++ b/src/components/application_manager/include/application_manager/policies/policy_handler.h @@ -204,6 +204,9 @@ class PolicyHandler : public PolicyHandlerInterface, uint32_t TimeoutExchangeMSec() const OVERRIDE; void OnExceededTimeout() OVERRIDE; void OnSystemReady() OVERRIDE; + const boost::optional<bool> LockScreenDismissalEnabledState() const OVERRIDE; + const boost::optional<std::string> LockScreenDismissalWarningMessage( + const std::string& language) const OVERRIDE; void PTUpdatedAt(Counters counter, int value) OVERRIDE; void add_listener(PolicyHandlerObserver* listener) OVERRIDE; void remove_listener(PolicyHandlerObserver* listener) OVERRIDE; @@ -661,6 +664,8 @@ class PolicyHandler : public PolicyHandlerInterface, void OnDeviceSwitching(const std::string& device_id_from, const std::string& device_id_to) FINAL; + void OnLockScreenDismissalStateChanged() FINAL; + protected: /** * Starts next retry exchange policy table @@ -807,7 +812,6 @@ class PolicyHandler : public PolicyHandlerInterface, std::vector<FunctionalGroupPermission> CollectAppPermissions( const uint32_t connection_key); - private: static const std::string kLibrary; /** @@ -817,7 +821,6 @@ class PolicyHandler : public PolicyHandlerInterface, */ void GetRegisteredLinks(std::map<std::string, std::string>& out_links) const; - private: mutable sync_primitives::RWLock policy_manager_lock_; std::shared_ptr<PolicyManager> policy_manager_; void* dl_handle_; diff --git a/src/components/application_manager/include/application_manager/smart_object_keys.h b/src/components/application_manager/include/application_manager/smart_object_keys.h index 328d7f5e81..69e00f5838 100644 --- a/src/components/application_manager/include/application_manager/smart_object_keys.h +++ b/src/components/application_manager/include/application_manager/smart_object_keys.h @@ -480,6 +480,8 @@ namespace mobile_notification { extern const char* state; extern const char* syncp_timeout; extern const char* syncp_url; +extern const char* lock_screen_dismissal_enabled; +extern const char* lock_screen_dismissal_warning; } // namespace mobile_notification namespace hmi_levels { diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_driver_distraction_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_driver_distraction_notification.cc index 2f3ee60a16..4229369acc 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_driver_distraction_notification.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_driver_distraction_notification.cc @@ -59,12 +59,35 @@ struct OnDriverDistractionProcessor { void operator()(ApplicationSharedPtr application) { if (application) { - (*on_driver_distraction_so_)[strings::params][strings::connection_key] = - application->app_id(); + // Create modifiable copy of base message + smart_objects::SmartObject message = *on_driver_distraction_so_; + message[strings::params][strings::connection_key] = application->app_id(); const RPCParams params; policy::CheckPermissionResult result; application_manager_.GetPolicyHandler().CheckPermissions( application, stringified_function_id_, params, result); + auto& msg_params = message[strings::msg_params]; + const bool is_lock_screen_dismissal_exists = msg_params.keyExists( + mobile_notification::lock_screen_dismissal_enabled); + + if (is_lock_screen_dismissal_exists && + msg_params[mobile_notification::lock_screen_dismissal_enabled] + .asBool()) { + const auto language = + MessageHelper::MobileLanguageToString(application->ui_language()); + + const auto warning_message = + application_manager_.GetPolicyHandler() + .LockScreenDismissalWarningMessage(language); + // Only allow lock screen dismissal if a warning message is available + if (warning_message && !warning_message->empty()) { + msg_params[mobile_notification::lock_screen_dismissal_warning] = + *warning_message; + } else { + msg_params[mobile_notification::lock_screen_dismissal_enabled] = + false; + } + } if (result.hmi_level_permitted != policy::kRpcAllowed) { MobileMessageQueue messages; application->SwapMobileMessageQueue(messages); @@ -72,15 +95,19 @@ struct OnDriverDistractionProcessor { std::remove_if( messages.begin(), messages.end(), - [this](smart_objects::SmartObjectSPtr message) { + [](smart_objects::SmartObjectSPtr message) { return (*message)[strings::params][strings::function_id] - .asString() == stringified_function_id_; + .asUInt() == + mobile_api::FunctionID::OnDriverDistractionID; }), messages.end()); - application->PushMobileMessage(on_driver_distraction_so_); + application->SwapMobileMessageQueue(messages); + application->PushMobileMessage( + std::make_shared<smart_objects::SmartObject>(message)); return; } - command_.SendNotificationToMobile(on_driver_distraction_so_); + command_.SendNotificationToMobile( + std::make_shared<smart_objects::SmartObject>(message)); } } @@ -108,14 +135,12 @@ OnDriverDistractionNotification::~OnDriverDistractionNotification() {} void OnDriverDistractionNotification::Run() { LOG4CXX_AUTO_TRACE(logger_); - const hmi_apis::Common_DriverDistractionState::eType state = + const auto state = static_cast<hmi_apis::Common_DriverDistractionState::eType>( (*message_)[strings::msg_params][hmi_notification::state].asInt()); application_manager_.set_driver_distraction_state(state); - smart_objects::SmartObjectSPtr on_driver_distraction = - std::make_shared<smart_objects::SmartObject>(); - + auto on_driver_distraction = std::make_shared<smart_objects::SmartObject>(); if (!on_driver_distraction) { LOG4CXX_ERROR(logger_, "NULL pointer"); return; @@ -127,6 +152,17 @@ void OnDriverDistractionNotification::Run() { (*on_driver_distraction)[strings::msg_params][mobile_notification::state] = state; + const auto lock_screen_dismissal = + application_manager_.GetPolicyHandler().LockScreenDismissalEnabledState(); + + if (lock_screen_dismissal && + hmi_apis::Common_DriverDistractionState::DD_ON == state) { + (*on_driver_distraction) + [strings::msg_params] + [mobile_notification::lock_screen_dismissal_enabled] = + *lock_screen_dismissal; + } + const ApplicationSet applications = application_manager_.applications().GetData(); diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/hmi_notifications_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/hmi_notifications_test.cc index 8f2feed877..2f8f5c2849 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/hmi_notifications_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/hmi_notifications_test.cc @@ -192,6 +192,14 @@ const int32_t kMobileProtocolType_ = 0; const int32_t kProtocolVersion_ = 3; const uint32_t kCorrelationId_ = 1939u; const uint32_t kAppId_ = 2014u; +const std::string kDefaultLanguage = "en-us"; +const mobile_apis::Language::eType kMobileLanguage = + mobile_apis::Language::EN_US; + +// LSDW - lock screen dismissal warning +const std::string kLockScreenDismissalWarningMessage_en = + "Swipe down to dismiss, acknowledging that you are not the driver"; +const uint32_t kConnectionKey = 2u; } // namespace class HMICommandsNotificationsTest @@ -240,6 +248,9 @@ class HMICommandsNotificationsTest .WillByDefault(ReturnRef(mock_event_dispatcher_)); ON_CALL(app_mngr_, application_by_hmi_app(_)).WillByDefault(Return(app_)); ON_CALL(*app_ptr_, app_id()).WillByDefault(Return(kAppId_)); + ON_CALL(app_mngr_, application(kConnectionKey)).WillByDefault(Return(app_)); + ON_CALL(mock_message_helper_, MobileLanguageToString(kMobileLanguage)) + .WillByDefault(Return(kDefaultLanguage)); } am::ApplicationSharedPtr ConfigureApp(NiceMock<MockApplication>** app_mock, @@ -259,6 +270,8 @@ class HMICommandsNotificationsTest .WillByDefault(Return(vc)); ON_CALL(**app_mock, IsAudioApplication()) .WillByDefault(Return(media || navi || vc)); + ON_CALL(**app_mock, ui_language()) + .WillByDefault(ReturnRef(kMobileLanguage)); return app; } #if defined(OS_POSIX) @@ -1793,11 +1806,26 @@ TEST_F(HMICommandsNotificationsTest, OnDriverDistractionNotificationEmptyData) { hmi_apis::Common_DriverDistractionState::DD_ON; MessageSharedPtr message = CreateMessage(); (*message)[am::strings::msg_params][am::hmi_notification::state] = state; + (*message)[am::strings::params][am::strings::connection_key] = kConnectionKey; std::shared_ptr<Command> command = CreateCommand<hmi::OnDriverDistractionNotification>(message); EXPECT_CALL(app_mngr_, set_driver_distraction_state(state)); - EXPECT_CALL(app_mngr_, applications()).WillOnce(Return(applications_)); + + ON_CALL(app_mngr_, GetPolicyHandler()) + .WillByDefault(ReturnRef(mock_policy_handler_)); + typedef boost::optional<bool> OptionalBool; + + ON_CALL(mock_policy_handler_, LockScreenDismissalEnabledState()) + .WillByDefault(Return(OptionalBool(true))); + std::string required_language = "en-us"; + ON_CALL(mock_policy_handler_, + LockScreenDismissalWarningMessage(required_language)) + .WillByDefault(Return( + boost::optional<std::string>(kLockScreenDismissalWarningMessage_en))); + + ON_CALL(app_mngr_, applications()).WillByDefault(Return(applications_)); + EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _)).Times(0); EXPECT_CALL(*app_ptr_, app_id()).Times(0); command->Run(); @@ -1805,16 +1833,28 @@ TEST_F(HMICommandsNotificationsTest, OnDriverDistractionNotificationEmptyData) { TEST_F(HMICommandsNotificationsTest, OnDriverDistractionNotificationInvalidApp) { - const hmi_apis::Common_DriverDistractionState::eType state = - hmi_apis::Common_DriverDistractionState::DD_ON; + const auto state = hmi_apis::Common_DriverDistractionState::DD_ON; MessageSharedPtr message = CreateMessage(); (*message)[am::strings::msg_params][am::hmi_notification::state] = state; + (*message)[am::strings::params][am::strings::connection_key] = kConnectionKey; std::shared_ptr<Command> command = CreateCommand<hmi::OnDriverDistractionNotification>(message); ApplicationSharedPtr invalid_app; application_set_.insert(invalid_app); - EXPECT_CALL(app_mngr_, applications()).WillOnce(Return(applications_)); + + ON_CALL(app_mngr_, GetPolicyHandler()) + .WillByDefault(ReturnRef(mock_policy_handler_)); + typedef boost::optional<bool> OptionalBool; + ON_CALL(mock_policy_handler_, LockScreenDismissalEnabledState()) + .WillByDefault(Return(OptionalBool(true))); + std::string required_language = "en-us"; + ON_CALL(mock_policy_handler_, + LockScreenDismissalWarningMessage(required_language)) + .WillByDefault(Return( + boost::optional<std::string>(kLockScreenDismissalWarningMessage_en))); + ON_CALL(app_mngr_, applications()).WillByDefault(Return(applications_)); + EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _)).Times(0); EXPECT_CALL(*app_ptr_, app_id()).Times(0); command->Run(); @@ -1825,21 +1865,33 @@ TEST_F(HMICommandsNotificationsTest, OnDriverDistractionNotificationValidApp) { hmi_apis::Common_DriverDistractionState::DD_ON; MessageSharedPtr message = CreateMessage(); (*message)[am::strings::msg_params][am::mobile_notification::state] = state; + (*message)[am::strings::params][am::strings::connection_key] = kConnectionKey; std::shared_ptr<Command> command = CreateCommand<hmi::OnDriverDistractionNotification>(message); application_set_.insert(app_); - EXPECT_CALL(app_mngr_, applications()).WillOnce(Return(applications_)); + + ON_CALL(app_mngr_, GetPolicyHandler()) + .WillByDefault(ReturnRef(mock_policy_handler_)); + typedef boost::optional<bool> OptionalBool; + ON_CALL(mock_policy_handler_, LockScreenDismissalEnabledState()) + .WillByDefault(Return(OptionalBool(true))); + std::string required_language = "en-us"; + ON_CALL(mock_policy_handler_, + LockScreenDismissalWarningMessage(required_language)) + .WillByDefault(Return( + boost::optional<std::string>(kLockScreenDismissalWarningMessage_en))); + ON_CALL(app_mngr_, applications()).WillByDefault(Return(applications_)); + policy::CheckPermissionResult result; result.hmi_level_permitted = policy::kRpcAllowed; - EXPECT_CALL(app_mngr_, GetPolicyHandler()) - .WillOnce(ReturnRef(mock_policy_handler_)); EXPECT_CALL(mock_policy_handler_, CheckPermissions(_, _, _, _)) .WillOnce(GetArg3(&result)); + EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, Command::CommandSource::SOURCE_SDL)) .WillOnce(GetMessage(message)); - EXPECT_CALL(*app_ptr_, app_id()).WillRepeatedly(Return(kAppId_)); + ON_CALL(*app_ptr_, app_id()).WillByDefault(Return(kAppId_)); command->Run(); EXPECT_EQ( diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/on_driver_distraction_notification_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/on_driver_distraction_notification_test.cc index 802ad01d0b..5e0083d395 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/on_driver_distraction_notification_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/on_driver_distraction_notification_test.cc @@ -52,22 +52,65 @@ namespace hmi_commands_test { namespace on_driver_distraction_notification { using ::testing::_; +using ::testing::DoAll; using ::testing::Eq; +using ::testing::NiceMock; using ::testing::Return; +using ::testing::SaveArg; +using ::testing::SetArgumentPointee; + namespace am = ::application_manager; using am::commands::MessageSharedPtr; using sdl_rpc_plugin::commands::hmi::OnDriverDistractionNotification; using namespace am::commands; +using test::components::commands_test::MobileResultCodeIs; + +namespace { +const std::string kDefaultLanguage = "en-us"; +const mobile_apis::Language::eType kMobileLanguage = + mobile_apis::Language::EN_US; -typedef std::shared_ptr<OnDriverDistractionNotification> NotificationPtr; +// LSDW - lock screen dismissal warning +const std::string kLockScreenDismissalWarningMessage_en = + "Swipe down to dismiss, acknowledging that you are not the driver"; +const uint32_t kConnectionKey = 2u; +} // namespace class HMIOnDriverDistractionNotificationTest : public CommandsTest<CommandsTestMocks::kIsNice> { public: HMIOnDriverDistractionNotificationTest() - : app_set_lock_(std::make_shared<sync_primitives::Lock>()) {} + : mock_app_(CreateMockApp()) + , app_set_lock_(std::make_shared<sync_primitives::Lock>()) + , accessor(app_set_, app_set_lock_) { + app_set_.insert(mock_app_); + InitMocksRelations(); + } + + typedef std::shared_ptr<OnDriverDistractionNotification> NotificationPtr; + typedef boost::optional<bool> OptionalBool; + + void SetUp() OVERRIDE { + ON_CALL(*mock_app_, ui_language()) + .WillByDefault(ReturnRef(kMobileLanguage)); + ON_CALL(app_mngr_, application(kConnectionKey)) + .WillByDefault(Return(mock_app_)); + ON_CALL(mock_message_helper_, MobileLanguageToString(kMobileLanguage)) + .WillByDefault(Return(kDefaultLanguage)); + } + + MockAppPtr mock_app_; std::shared_ptr<sync_primitives::Lock> app_set_lock_; - policy_test::MockPolicyHandlerInterface mock_policy_handler_interface_; + am::ApplicationSet app_set_; + DataAccessor<am::ApplicationSet> accessor; + NiceMock<policy_test::MockPolicyHandlerInterface> + mock_policy_handler_interface_; + + void InitMocksRelations() { + ON_CALL(app_mngr_, applications()).WillByDefault(Return(accessor)); + ON_CALL(app_mngr_, GetPolicyHandler()) + .WillByDefault(ReturnRef(mock_policy_handler_interface_)); + } }; MATCHER_P2(CheckNotificationParams, function_id, state, "") { @@ -87,71 +130,232 @@ ACTION_P(GetArg3, result) { arg3 = *result; } -TEST_F(HMIOnDriverDistractionNotificationTest, Run_PushMobileMessage_SUCCESS) { - const hmi_apis::Common_DriverDistractionState::eType state = - hmi_apis::Common_DriverDistractionState::DD_ON; +ACTION_P(SetMessage, lockScreenDismissalWarning) { + smart_objects::SmartObject& notification = arg0; + + notification[application_manager::strings::msg_params] + [application_manager::mobile_notification:: + lock_screen_dismissal_warning] = lockScreenDismissalWarning; +} + +TEST_F(HMIOnDriverDistractionNotificationTest, + Run_SendNotificationToMobile_SUCCESS) { + const auto state = hmi_apis::Common_DriverDistractionState::DD_ON; MessageSharedPtr commands_msg(CreateMessage(smart_objects::SmartType_Map)); (*commands_msg)[am::strings::msg_params][am::hmi_notification::state] = state; + (*commands_msg)[am::strings::params][am::strings::connection_key] = + kConnectionKey; NotificationPtr command( CreateCommand<OnDriverDistractionNotification>(commands_msg)); EXPECT_CALL(app_mngr_, set_driver_distraction_state(Eq(state))); - MockAppPtr mock_app = CreateMockApp(); - am::ApplicationSet app_set; - app_set.insert(mock_app); + ON_CALL(mock_policy_handler_interface_, LockScreenDismissalEnabledState()) + .WillByDefault(Return(OptionalBool(true))); + + ON_CALL(mock_policy_handler_interface_, LockScreenDismissalWarningMessage(_)) + .WillByDefault(Return(kLockScreenDismissalWarningMessage_en)); + + policy::CheckPermissionResult result; + result.hmi_level_permitted = policy::kRpcAllowed; + EXPECT_CALL(mock_policy_handler_interface_, CheckPermissions(_, _, _, _)) + .WillOnce(GetArg3(&result)); + + MessageSharedPtr message_to_mobile( + CreateMessage(smart_objects::SmartType_Map)); + EXPECT_CALL(mock_rpc_service_, + ManageMobileCommand( + CheckNotificationParams( + am::mobile_api::FunctionID::OnDriverDistractionID, state), + Command::CommandSource::SOURCE_SDL)) + .WillOnce(DoAll(SaveArg<0>(&message_to_mobile), Return(true))); + command->Run(); + + ASSERT_TRUE((*message_to_mobile)[am::strings::msg_params].keyExists( + am::mobile_notification::lock_screen_dismissal_warning)); + + auto LSDW_message = + (*message_to_mobile) + [am::strings::msg_params] + [am::mobile_notification::lock_screen_dismissal_warning] + .asString(); + + EXPECT_EQ(kLockScreenDismissalWarningMessage_en, LSDW_message); +} + +TEST_F(HMIOnDriverDistractionNotificationTest, + Run_PushMobileMessage_If_DisallowedByPolicy) { + const auto state = hmi_apis::Common_DriverDistractionState::DD_ON; + MessageSharedPtr commands_msg(CreateMessage(smart_objects::SmartType_Map)); + (*commands_msg)[am::strings::msg_params][am::hmi_notification::state] = state; + (*commands_msg)[am::strings::params][am::strings::connection_key] = + kConnectionKey; + NotificationPtr command( + CreateCommand<OnDriverDistractionNotification>(commands_msg)); + + ON_CALL(mock_policy_handler_interface_, LockScreenDismissalEnabledState()) + .WillByDefault(Return(boost::optional<bool>(true))); + + ON_CALL(mock_policy_handler_interface_, LockScreenDismissalWarningMessage(_)) + .WillByDefault(Return(kLockScreenDismissalWarningMessage_en)); - DataAccessor<am::ApplicationSet> accessor(app_set, app_set_lock_); - EXPECT_CALL(app_mngr_, applications()).WillOnce(Return(accessor)); policy::CheckPermissionResult result; result.hmi_level_permitted = policy::kRpcDisallowed; - EXPECT_CALL(app_mngr_, GetPolicyHandler()) - .WillOnce(ReturnRef(mock_policy_handler_interface_)); EXPECT_CALL(mock_policy_handler_interface_, CheckPermissions(_, _, _, _)) .WillOnce(GetArg3(&result)); - EXPECT_CALL(*mock_app, + MessageSharedPtr pushed_message(CreateMessage(smart_objects::SmartType_Map)); + EXPECT_CALL(*mock_app_, PushMobileMessage(CheckNotificationParams( - am::mobile_api::FunctionID::OnDriverDistractionID, state))); + am::mobile_api::FunctionID::OnDriverDistractionID, state))) + .WillOnce(SaveArg<0>(&pushed_message)); + EXPECT_CALL(app_mngr_, set_driver_distraction_state(Eq(state))); command->Run(); + + ASSERT_TRUE((*pushed_message)[am::strings::msg_params].keyExists( + am::mobile_notification::lock_screen_dismissal_warning)); + + auto lock_screen_dismissal_warning_message = + (*pushed_message)[am::strings::msg_params] + [am::mobile_notification::lock_screen_dismissal_warning] + .asString(); + + EXPECT_EQ(kLockScreenDismissalWarningMessage_en, + lock_screen_dismissal_warning_message); } TEST_F(HMIOnDriverDistractionNotificationTest, - Run_SendNotificationToMobile_SUCCESS) { - const hmi_apis::Common_DriverDistractionState::eType state = - hmi_apis::Common_DriverDistractionState::DD_ON; + Run_SendNotificationIfLockScreenDismissalMissed) { + const auto state = hmi_apis::Common_DriverDistractionState::DD_ON; + MessageSharedPtr commands_msg(CreateMessage(smart_objects::SmartType_Map)); + (*commands_msg)[am::strings::msg_params][am::hmi_notification::state] = state; + + NotificationPtr command( + CreateCommand<OnDriverDistractionNotification>(commands_msg)); + + ON_CALL(mock_policy_handler_interface_, LockScreenDismissalEnabledState()) + .WillByDefault(Return(boost::optional<bool>())); + + policy::CheckPermissionResult result; + result.hmi_level_permitted = policy::kRpcAllowed; + ON_CALL(mock_policy_handler_interface_, CheckPermissions(_, _, _, _)) + .WillByDefault(GetArg3(&result)); + + MessageSharedPtr command_result; + EXPECT_CALL(mock_rpc_service_, + ManageMobileCommand(_, Command::CommandSource::SOURCE_SDL)) + .WillOnce(DoAll(SaveArg<0>(&command_result), Return(true))); + + command->Run(); + + auto& msg_params = + (*command_result)[application_manager::strings::msg_params]; + EXPECT_FALSE(msg_params.keyExists( + application_manager::mobile_notification::lock_screen_dismissal_enabled)); + EXPECT_FALSE(msg_params.keyExists( + application_manager::mobile_notification::lock_screen_dismissal_warning)); +} + +// LSDW - lock screen dimissal +TEST_F(HMIOnDriverDistractionNotificationTest, + Run_SendNotificationToMobile_LSDWMessageIsAbsent_SUCCESS) { + const auto state = hmi_apis::Common_DriverDistractionState::DD_ON; MessageSharedPtr commands_msg(CreateMessage(smart_objects::SmartType_Map)); (*commands_msg)[am::strings::msg_params][am::hmi_notification::state] = state; + (*commands_msg)[am::strings::params][am::strings::connection_key] = + kConnectionKey; NotificationPtr command( CreateCommand<OnDriverDistractionNotification>(commands_msg)); EXPECT_CALL(app_mngr_, set_driver_distraction_state(Eq(state))); - MockAppPtr mock_app = CreateMockApp(); - am::ApplicationSet app_set; - app_set.insert(mock_app); + ON_CALL(mock_policy_handler_interface_, LockScreenDismissalEnabledState()) + .WillByDefault(Return(OptionalBool(false))); - DataAccessor<am::ApplicationSet> accessor(app_set, app_set_lock_); - EXPECT_CALL(app_mngr_, applications()).WillOnce(Return(accessor)); + // LockScreenDismissalWarning won't be added to message if value of + // LockScreenDismissalEnabledState is false + std::string required_language = "en-us"; + EXPECT_CALL(mock_policy_handler_interface_, + LockScreenDismissalWarningMessage(required_language)) + .Times(0); policy::CheckPermissionResult result; result.hmi_level_permitted = policy::kRpcAllowed; - EXPECT_CALL(app_mngr_, GetPolicyHandler()) - .WillOnce(ReturnRef(mock_policy_handler_interface_)); EXPECT_CALL(mock_policy_handler_interface_, CheckPermissions(_, _, _, _)) .WillOnce(GetArg3(&result)); + + MessageSharedPtr message_to_mobile( + CreateMessage(smart_objects::SmartType_Map)); EXPECT_CALL(mock_rpc_service_, ManageMobileCommand( CheckNotificationParams( am::mobile_api::FunctionID::OnDriverDistractionID, state), - Command::CommandSource::SOURCE_SDL)); - + Command::CommandSource::SOURCE_SDL)) + .WillOnce(DoAll(SaveArg<0>(&message_to_mobile), Return(true))); command->Run(); + + EXPECT_FALSE((*message_to_mobile)[am::strings::msg_params].keyExists( + am::mobile_notification::lock_screen_dismissal_warning)); } +TEST_F(HMIOnDriverDistractionNotificationTest, + Run_SendNotificationToMobile_SpecifiedLanguageIsAbsent_SUCCESS) { + const auto state = hmi_apis::Common_DriverDistractionState::DD_ON; + MessageSharedPtr commands_msg(CreateMessage(smart_objects::SmartType_Map)); + (*commands_msg)[am::strings::msg_params][am::hmi_notification::state] = state; + (*commands_msg)[am::strings::params][am::strings::connection_key] = + kConnectionKey; + + NotificationPtr command( + CreateCommand<OnDriverDistractionNotification>(commands_msg)); + + EXPECT_CALL(app_mngr_, set_driver_distraction_state(Eq(state))); + + ON_CALL(mock_policy_handler_interface_, LockScreenDismissalEnabledState()) + .WillByDefault(Return(OptionalBool(true))); + + ON_CALL(mock_policy_handler_interface_, LockScreenDismissalWarningMessage(_)) + .WillByDefault(Return(kLockScreenDismissalWarningMessage_en)); + + // In case when specified language is absent in policy table, will added + // message on default language (en-us) + const mobile_apis::Language::eType mobile_language = + mobile_apis::Language::FR_FR; + std::string required_language = "FR-FR"; + ON_CALL(*mock_app_, ui_language()).WillByDefault(ReturnRef(mobile_language)); + ON_CALL(mock_message_helper_, MobileLanguageToString(mobile_language)) + .WillByDefault(Return(required_language)); + + policy::CheckPermissionResult result; + result.hmi_level_permitted = policy::kRpcAllowed; + EXPECT_CALL(mock_policy_handler_interface_, CheckPermissions(_, _, _, _)) + .WillOnce(GetArg3(&result)); + + MessageSharedPtr message_to_mobile( + CreateMessage(smart_objects::SmartType_Map)); + EXPECT_CALL(mock_rpc_service_, + ManageMobileCommand( + CheckNotificationParams( + am::mobile_api::FunctionID::OnDriverDistractionID, state), + Command::CommandSource::SOURCE_SDL)) + .WillOnce(DoAll(SaveArg<0>(&message_to_mobile), Return(true))); + command->Run(); + + ASSERT_TRUE((*message_to_mobile)[am::strings::msg_params].keyExists( + am::mobile_notification::lock_screen_dismissal_warning)); + + auto lock_screen_dismissal_warning_message = + (*message_to_mobile) + [am::strings::msg_params] + [am::mobile_notification::lock_screen_dismissal_warning] + .asString(); + + EXPECT_EQ(kLockScreenDismissalWarningMessage_en, + lock_screen_dismissal_warning_message); +} } // namespace on_driver_distraction_notification } // namespace hmi_commands_test } // namespace commands_test diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 3a92009d4f..317ad2933f 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -3907,30 +3907,69 @@ void ApplicationManagerImpl::SendDriverDistractionState( LOG4CXX_WARN(logger_, "DriverDistractionState is INVALID_ENUM"); return; } - smart_objects::SmartObjectSPtr on_driver_distraction = - std::make_shared<smart_objects::SmartObject>(); - (*on_driver_distraction)[strings::params][strings::message_type] = - static_cast<int32_t>(application_manager::MessageType::kNotification); - (*on_driver_distraction)[strings::params][strings::function_id] = - mobile_api::FunctionID::OnDriverDistractionID; - (*on_driver_distraction)[strings::msg_params][mobile_notification::state] = - driver_distraction_state(); - (*on_driver_distraction)[strings::params][strings::connection_key] = - application->app_id(); + auto create_notification = [application, this]() { + auto notification = std::make_shared<smart_objects::SmartObject>(); + auto& msg_params = (*notification)[strings::msg_params]; + auto& params = (*notification)[strings::params]; + + params[strings::message_type] = + static_cast<int32_t>(application_manager::MessageType::kNotification); + params[strings::function_id] = + static_cast<int32_t>(mobile_apis::FunctionID::OnDriverDistractionID); + msg_params[mobile_notification::state] = driver_distraction_state(); + const auto lock_screen_dismissal = + policy_handler_->LockScreenDismissalEnabledState(); + + if (lock_screen_dismissal && + hmi_apis::Common_DriverDistractionState::DD_ON == + driver_distraction_state()) { + bool dismissal_enabled = *lock_screen_dismissal; + if (dismissal_enabled) { + const auto language = + MessageHelper::MobileLanguageToString(application->ui_language()); + + const auto warning_message = + policy_handler_->LockScreenDismissalWarningMessage(language); + // Only allow lock screen dismissal if a warning message is available + if (warning_message && !warning_message->empty()) { + msg_params[mobile_notification::lock_screen_dismissal_warning] = + *warning_message; + } else { + dismissal_enabled = false; + } + } + msg_params[mobile_notification::lock_screen_dismissal_enabled] = + dismissal_enabled; + } + + params[strings::connection_key] = application->app_id(); + return notification; + }; - const std::string function_id = MessageHelper::StringifiedFunctionID( - static_cast<mobile_apis::FunctionID::eType>( - (*on_driver_distraction)[strings::params][strings::function_id] - .asUInt())); const RPCParams params; + const std::string function_id = MessageHelper::StringifiedFunctionID( + mobile_api::FunctionID::OnDriverDistractionID); const mobile_apis::Result::eType check_result = CheckPolicyPermissions(application, function_id, params); if (mobile_api::Result::SUCCESS == check_result) { - rpc_service_->ManageMobileCommand(on_driver_distraction, + rpc_service_->ManageMobileCommand(create_notification(), commands::Command::SOURCE_SDL); } else { - application->PushMobileMessage(on_driver_distraction); + MobileMessageQueue messages; + application->SwapMobileMessageQueue(messages); + messages.erase( + std::remove_if( + messages.begin(), + messages.end(), + [](smart_objects::SmartObjectSPtr message) { + return (*message)[strings::params][strings::function_id] + .asUInt() == + mobile_apis::FunctionID::OnDriverDistractionID; + }), + messages.end()); + application->SwapMobileMessageQueue(messages); + application->PushMobileMessage(create_notification()); } } diff --git a/src/components/application_manager/src/message_helper/message_helper.cc b/src/components/application_manager/src/message_helper/message_helper.cc index 8dc57b96b0..d2e911f227 100644 --- a/src/components/application_manager/src/message_helper/message_helper.cc +++ b/src/components/application_manager/src/message_helper/message_helper.cc @@ -332,6 +332,15 @@ std::string MessageHelper::CommonLanguageToString( return std::string(); } +std::string MessageHelper::MobileLanguageToString( + mobile_apis::Language::eType language) { + using namespace ns_smart_device_link::ns_smart_objects; + const char* str = 0; + EnumConversionHelper<mobile_apis::Language::eType>::EnumToCString(language, + &str); + return str ? str : std::string(); +} + smart_objects::SmartObjectSPtr MessageHelper::CreateMessageForHMI( hmi_apis::messageType::eType message_type, const uint32_t correlation_id) { using namespace smart_objects; diff --git a/src/components/application_manager/src/policies/policy_handler.cc b/src/components/application_manager/src/policies/policy_handler.cc index bee88633c1..cac09bd5f3 100644 --- a/src/components/application_manager/src/policies/policy_handler.cc +++ b/src/components/application_manager/src/policies/policy_handler.cc @@ -826,6 +826,15 @@ void PolicyHandler::OnDeviceSwitching(const std::string& device_id_from, policy_manager_->OnDeviceSwitching(device_id_from, device_id_to); } +void PolicyHandler::OnLockScreenDismissalStateChanged() { + LOG4CXX_AUTO_TRACE(logger_); + const auto accessor = application_manager_.applications(); + const auto apps = accessor.GetData(); + for (auto& app : apps) { + application_manager_.SendDriverDistractionState(app); + } +} + void PolicyHandler::OnGetStatusUpdate(const uint32_t correlation_id) { LOG4CXX_AUTO_TRACE(logger_); POLICY_LIB_CHECK_VOID(); @@ -1574,6 +1583,19 @@ void PolicyHandler::OnSystemReady() { policy_manager_->OnSystemReady(); } +const boost::optional<bool> PolicyHandler::LockScreenDismissalEnabledState() + const { + POLICY_LIB_CHECK(boost::optional<bool>()); + return policy_manager_->LockScreenDismissalEnabledState(); +} + +const boost::optional<std::string> +PolicyHandler::LockScreenDismissalWarningMessage( + const std::string& language) const { + POLICY_LIB_CHECK(boost::optional<std::string>()); + return policy_manager_->LockScreenDismissalWarningMessage(language); +} + void PolicyHandler::PTUpdatedAt(Counters counter, int value) { POLICY_LIB_CHECK_VOID(); policy_manager_->PTUpdatedAt(counter, value); diff --git a/src/components/application_manager/src/smart_object_keys.cc b/src/components/application_manager/src/smart_object_keys.cc index 54033b12ab..411d0a3e8a 100644 --- a/src/components/application_manager/src/smart_object_keys.cc +++ b/src/components/application_manager/src/smart_object_keys.cc @@ -441,6 +441,8 @@ namespace mobile_notification { const char* state = "state"; const char* syncp_timeout = "Timeout"; const char* syncp_url = "URL"; +const char* lock_screen_dismissal_enabled = "lockScreenDismissalEnabled"; +const char* lock_screen_dismissal_warning = "lockScreenDismissalWarning"; } // namespace mobile_notification namespace hmi_levels { diff --git a/src/components/application_manager/test/include/application_manager/mock_message_helper.h b/src/components/application_manager/test/include/application_manager/mock_message_helper.h index 819ead8d8b..29afd36e52 100644 --- a/src/components/application_manager/test/include/application_manager/mock_message_helper.h +++ b/src/components/application_manager/test/include/application_manager/mock_message_helper.h @@ -168,6 +168,8 @@ class MockMessageHelper { hmi_apis::Common_LightName::eType(const std::string& lightName)); MOCK_METHOD1(CommonLanguageToString, std::string(hmi_apis::Common_Language::eType)); + MOCK_METHOD1(MobileLanguageToString, + std::string(mobile_apis::Language::eType)); MOCK_METHOD2(CreateModuleInfoSO, smart_objects::SmartObjectSPtr(uint32_t function_id, ApplicationManager& app_mngr)); diff --git a/src/components/application_manager/test/mock_message_helper.cc b/src/components/application_manager/test/mock_message_helper.cc index 522ef3dbd5..3284224237 100644 --- a/src/components/application_manager/test/mock_message_helper.cc +++ b/src/components/application_manager/test/mock_message_helper.cc @@ -366,6 +366,11 @@ std::string MessageHelper::CommonLanguageToString( return MockMessageHelper::message_helper_mock()->CommonLanguageToString(lang); } +std::string MessageHelper::MobileLanguageToString( + mobile_apis::Language::eType lang) { + return MockMessageHelper::message_helper_mock()->MobileLanguageToString(lang); +} + smart_objects::SmartObjectSPtr MessageHelper::GetBCActivateAppRequestToHMI( ApplicationConstSharedPtr app, const policy::PolicyHandlerInterface& policy_handler, @@ -589,4 +594,5 @@ void MessageHelper::BroadcastCapabilityUpdate( MockMessageHelper::message_helper_mock()->BroadcastCapabilityUpdate( msg_params, app_mngr); } + } // namespace application_manager diff --git a/src/components/include/application_manager/policies/policy_handler_interface.h b/src/components/include/application_manager/policies/policy_handler_interface.h index 708c4ddd32..835ddedd28 100644 --- a/src/components/include/application_manager/policies/policy_handler_interface.h +++ b/src/components/include/application_manager/policies/policy_handler_interface.h @@ -38,6 +38,8 @@ #include <set> #include <string> #include <vector> +#include "boost/optional.hpp" + #include "application_manager/application.h" #include "application_manager/policies/policy_handler_observer.h" #include "interfaces/MOBILE_API.h" @@ -49,6 +51,7 @@ #include "smart_objects/smart_object.h" #include "utils/callable.h" #include "utils/custom_string.h" +#include "utils/optional.h" using namespace ::rpc::policy_table_interface_base; namespace policy { @@ -121,6 +124,10 @@ class PolicyHandlerInterface { virtual uint32_t TimeoutExchangeMSec() const = 0; virtual void OnExceededTimeout() = 0; virtual void OnSystemReady() = 0; + virtual const boost::optional<bool> LockScreenDismissalEnabledState() + const = 0; + virtual const boost::optional<std::string> LockScreenDismissalWarningMessage( + const std::string& language) const = 0; virtual void PTUpdatedAt(Counters counter, int value) = 0; virtual void add_listener(PolicyHandlerObserver* listener) = 0; virtual void remove_listener(PolicyHandlerObserver* listener) = 0; diff --git a/src/components/include/policy/policy_external/policy/policy_listener.h b/src/components/include/policy/policy_external/policy/policy_listener.h index 8299d019f5..c64a6d5496 100644 --- a/src/components/include/policy/policy_external/policy/policy_listener.h +++ b/src/components/include/policy/policy_external/policy/policy_listener.h @@ -175,6 +175,12 @@ class PolicyListener { virtual void OnUpdateHMIStatus(const std::string& device_id, const std::string& policy_app_id, const std::string& hmi_level) = 0; + + /** + * @brief Notify Connected mobile apps about changing state of + * LockScreenDismissal + */ + virtual void OnLockScreenDismissalStateChanged() = 0; }; } // namespace policy #endif // SRC_COMPONENTS_INCLUDE_POLICY_POLICY_EXTERNAL_POLICY_POLICY_LISTENER_H_ diff --git a/src/components/include/policy/policy_external/policy/policy_manager.h b/src/components/include/policy/policy_external/policy/policy_manager.h index 331b579365..aecc4b607a 100644 --- a/src/components/include/policy/policy_external/policy/policy_manager.h +++ b/src/components/include/policy/policy_external/policy/policy_manager.h @@ -36,6 +36,7 @@ #include <vector> #include "utils/callable.h" +#include "utils/optional.h" #include "policy/access_remote.h" #include "policy/cache_manager_interface.h" @@ -165,6 +166,24 @@ class PolicyManager : public usage_statistics::StatisticsManager { virtual void KmsChanged(int kilometers) = 0; /** + * @brief Returns state of the lock screen that could be able to be dismissed + * while connected to SDL, allowing users the ability to interact with the + * app. + * @return bool True if lock screen can be dismissed. + */ + virtual const boost::optional<bool> LockScreenDismissalEnabledState() + const = 0; + + /** + * @brief Returns lock screen warning message. In case when specified language + * is absent in policy table will be returned message on default language + * ("en-us"). Otherwise returns uninitialized boost::optional<std::string> + * @return std::string Lock screen warning message + */ + virtual const boost::optional<std::string> LockScreenDismissalWarningMessage( + const std::string& language) const = 0; + + /** * @brief Increments counter of ignition cycles */ virtual void IncrementIgnitionCycles() = 0; diff --git a/src/components/include/policy/policy_regular/policy/policy_listener.h b/src/components/include/policy/policy_regular/policy/policy_listener.h index 0907e42142..f12bb2e85f 100644 --- a/src/components/include/policy/policy_regular/policy/policy_listener.h +++ b/src/components/include/policy/policy_regular/policy/policy_listener.h @@ -157,6 +157,12 @@ class PolicyListener { virtual void OnUpdateHMIStatus(const std::string& device_id, const std::string& policy_app_id, const std::string& hmi_level) = 0; + + /** + * @brief Notify Connected mobile apps about changing state + * LockScreenDismissal + */ + virtual void OnLockScreenDismissalStateChanged() = 0; }; } // namespace policy #endif // SRC_COMPONENTS_INCLUDE_POLICY_POLICY_REGULAR_POLICY_POLICY_LISTENER_H_ diff --git a/src/components/include/policy/policy_regular/policy/policy_manager.h b/src/components/include/policy/policy_regular/policy/policy_manager.h index f82657ef26..713f71dcdb 100644 --- a/src/components/include/policy/policy_regular/policy/policy_manager.h +++ b/src/components/include/policy/policy_regular/policy/policy_manager.h @@ -35,6 +35,7 @@ #include <cstdint> #include <vector> +#include "boost/optional.hpp" #include "policy/access_remote.h" #include "policy/cache_manager_interface.h" @@ -43,6 +44,7 @@ #include "policy/policy_types.h" #include "policy/usage_statistics/statistics_manager.h" #include "utils/callable.h" +#include "utils/optional.h" namespace policy { class PolicySettings; @@ -165,6 +167,23 @@ class PolicyManager : public usage_statistics::StatisticsManager { virtual void KmsChanged(int kilometers) = 0; /** + * @brief Returns state of the lock screen that could be able to be dismissed + * while connected to SDL, allowing users the ability to interact with the + * app. + * @return bool True if lock screen can be dismissed. + */ + virtual const boost::optional<bool> LockScreenDismissalEnabledState() + const = 0; + + /** + * @brief Returns lock screen warning message + * @param language_code Specific language for which need message + * @return std::string Lock screen warning message + */ + virtual const boost::optional<std::string> LockScreenDismissalWarningMessage( + const std::string& language) const = 0; + + /** * @brief Increments counter of ignition cycles */ virtual void IncrementIgnitionCycles() = 0; diff --git a/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h b/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h index 059442f424..342debca0a 100644 --- a/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h +++ b/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h @@ -109,6 +109,10 @@ class MockPolicyHandlerInterface : public policy::PolicyHandlerInterface { MOCK_CONST_METHOD0(TimeoutExchangeMSec, uint32_t()); MOCK_METHOD0(OnExceededTimeout, void()); MOCK_METHOD0(OnSystemReady, void()); + MOCK_CONST_METHOD0(LockScreenDismissalEnabledState, + const boost::optional<bool>()); + MOCK_CONST_METHOD1(LockScreenDismissalWarningMessage, + const boost::optional<std::string>(const std::string&)); MOCK_METHOD2(PTUpdatedAt, void(policy::Counters counter, int value)); MOCK_METHOD1(add_listener, void(policy::PolicyHandlerObserver* listener)); MOCK_METHOD1(remove_listener, void(policy::PolicyHandlerObserver* listener)); diff --git a/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h b/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h index 6f754ad2c9..0a6bef45dd 100644 --- a/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h +++ b/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h @@ -110,6 +110,10 @@ class MockCacheManagerInterface : public ::policy::CacheManagerInterface { policy_table::AppServiceParameters* app_service_parameters)); MOCK_CONST_METHOD1(UnknownRPCPassthroughAllowed, bool(const std::string& policy_app_id)); + MOCK_CONST_METHOD0(LockScreenDismissalEnabledState, + const boost::optional<bool>()); + MOCK_CONST_METHOD1(LockScreenDismissalWarningMessage, + const boost::optional<std::string>(const std::string&)); MOCK_CONST_METHOD1(GetDeviceConsent, DeviceConsent(const std::string& device_id)); MOCK_METHOD2(SetDeviceConsent, @@ -120,11 +124,11 @@ class MockCacheManagerInterface : public ::policy::CacheManagerInterface { MOCK_CONST_METHOD1(GetCachedDeviceConsent, DeviceConsent(const std::string& device_id)); MOCK_METHOD1(SetVINValue, bool(const std::string& value)); - MOCK_METHOD3(GetUserFriendlyMsg, - std::vector<UserFriendlyMessage>( - const std::vector<std::string>& msg_codes, - const std::string& language, - const std::string& active_hmi_language)); + MOCK_CONST_METHOD3(GetUserFriendlyMsg, + std::vector<UserFriendlyMessage>( + const std::vector<std::string>& msg_codes, + const std::string& language, + const std::string& active_hmi_language)); MOCK_METHOD2(GetUpdateUrls, void(const std::string& service_type, EndpointUrls& out_end_points)); diff --git a/src/components/include/test/policy/policy_external/policy/mock_policy_listener.h b/src/components/include/test/policy/policy_external/policy/mock_policy_listener.h index 1e42423a03..e6ee086b31 100644 --- a/src/components/include/test/policy/policy_external/policy/mock_policy_listener.h +++ b/src/components/include/test/policy/policy_external/policy/mock_policy_listener.h @@ -103,6 +103,7 @@ class MockPolicyListener : public ::policy::PolicyListener { void(const std::string& device_id, const std::string& policy_app_id, const std::string& hmi_level)); + MOCK_METHOD0(OnLockScreenDismissalStateChanged, void()); }; } // namespace policy_test diff --git a/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h b/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h index 7ebf73ae54..309e357235 100644 --- a/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h +++ b/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h @@ -77,6 +77,10 @@ class MockPolicyManager : public PolicyManager { MOCK_METHOD0(ResetUserConsent, bool()); MOCK_CONST_METHOD0(GetPolicyTableStatus, std::string()); MOCK_METHOD1(KmsChanged, void(int kilometers)); + MOCK_CONST_METHOD0(LockScreenDismissalEnabledState, + const boost::optional<bool>()); + MOCK_CONST_METHOD1(LockScreenDismissalWarningMessage, + const boost::optional<std::string>(const std::string&)); MOCK_METHOD0(IncrementIgnitionCycles, void()); MOCK_METHOD0(ForcePTExchange, std::string()); MOCK_METHOD0(ForcePTExchangeAtUserRequest, std::string()); diff --git a/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h b/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h index dacdaf202f..c296701e34 100644 --- a/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h +++ b/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h @@ -91,11 +91,15 @@ class MockCacheManagerInterface : public CacheManagerInterface { MOCK_METHOD2(SetHybridAppPreference, void(const std::string& policy_app_id, const std::string& hybrid_app_preference)); + MOCK_CONST_METHOD0(LockScreenDismissalEnabledState, + const boost::optional<bool>()); + MOCK_CONST_METHOD1(LockScreenDismissalWarningMessage, + const boost::optional<std::string>(const std::string&)); MOCK_METHOD1(SetVINValue, bool(const std::string& value)); - MOCK_METHOD2(GetUserFriendlyMsg, - std::vector<UserFriendlyMessage>( - const std::vector<std::string>& msg_codes, - const std::string& language)); + MOCK_CONST_METHOD2(GetUserFriendlyMsg, + std::vector<UserFriendlyMessage>( + const std::vector<std::string>& msg_codes, + const std::string& language)); MOCK_CONST_METHOD2( GetAppServiceParameters, void(const std::string& policy_app_id, diff --git a/src/components/include/test/policy/policy_regular/policy/mock_policy_listener.h b/src/components/include/test/policy/policy_regular/policy/mock_policy_listener.h index f409100a49..7958bd3304 100644 --- a/src/components/include/test/policy/policy_regular/policy/mock_policy_listener.h +++ b/src/components/include/test/policy/policy_regular/policy/mock_policy_listener.h @@ -96,6 +96,7 @@ class MockPolicyListener : public ::policy::PolicyListener { void(const std::string& device_id, const std::string& policy_app_id, const std::string& hmi_level)); + MOCK_METHOD0(OnLockScreenDismissalStateChanged, void()); }; } // namespace policy_test diff --git a/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h b/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h index 73bf2d387b..a670e99bef 100644 --- a/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h +++ b/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h @@ -78,6 +78,10 @@ class MockPolicyManager : public PolicyManager { MOCK_METHOD0(ResetUserConsent, bool()); MOCK_CONST_METHOD0(GetPolicyTableStatus, std::string()); MOCK_METHOD1(KmsChanged, void(int kilometers)); + MOCK_CONST_METHOD0(LockScreenDismissalEnabledState, + const boost::optional<bool>()); + MOCK_CONST_METHOD1(LockScreenDismissalWarningMessage, + const boost::optional<std::string>(const std::string&)); MOCK_METHOD0(IncrementIgnitionCycles, void()); MOCK_METHOD0(ForcePTExchange, std::string()); MOCK_METHOD0(ForcePTExchangeAtUserRequest, std::string()); diff --git a/src/components/interfaces/MOBILE_API.xml b/src/components/interfaces/MOBILE_API.xml index fb6e9dc95e..3072b3fb5b 100644 --- a/src/components/interfaces/MOBILE_API.xml +++ b/src/components/interfaces/MOBILE_API.xml @@ -7554,6 +7554,21 @@ <param name="state" type="DriverDistractionState" mandatory="true"> <description>Current State of Driver Distraction</description> </param> + <param name="lockScreenDismissalEnabled" type="Boolean" mandatory="false" since="6.0"> + <description> + If enabled, the lock screen will be able to be dismissed while connected to SDL, allowing users + the ability to interact with the app. Dismissals should include a warning to the user and ensure + that they are not the driver. + </description> + </param> + <param name="lockScreenDismissalWarning" type="String" mandatory="false" since="6.0"> + <description> + Warning message to be displayed on the lock screen when dismissal is enabled. + This warning should be used to ensure that the user is not the driver of the vehicle, + ex. `Swipe down to dismiss, acknowledging that you are not the driver.`. + This parameter must be present if "lockScreenDismissalEnabled" is set to true. + </description> + </param> </function> <function name="OnPermissionsChange" functionID="OnPermissionsChangeID" messagetype="notification" since="2.0"> diff --git a/src/components/policy/policy_external/include/policy/cache_manager.h b/src/components/policy/policy_external/include/policy/cache_manager.h index 15eb51565d..19a475371d 100644 --- a/src/components/policy/policy_external/include/policy/cache_manager.h +++ b/src/components/policy/policy_external/include/policy/cache_manager.h @@ -34,6 +34,7 @@ #define SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_INCLUDE_POLICY_CACHE_MANAGER_H_ #include <map> +#include "boost/optional.hpp" #include "policy/cache_manager_interface.h" #include "policy/pt_ext_representation.h" @@ -158,6 +159,11 @@ class CacheManager : public CacheManagerInterface { */ virtual const VehicleInfo GetVehicleInfo() const; + const boost::optional<bool> LockScreenDismissalEnabledState() const OVERRIDE; + + const boost::optional<std::string> LockScreenDismissalWarningMessage( + const std::string& language) const OVERRIDE; + /** * @brief Get a list of enabled cloud applications * @param enabled_apps List filled with the policy app id of each enabled @@ -283,7 +289,7 @@ class CacheManager : public CacheManagerInterface { std::vector<UserFriendlyMessage> GetUserFriendlyMsg( const std::vector<std::string>& msg_codes, const std::string& language, - const std::string& active_hmi_language); + const std::string& active_hmi_language) const; /** * @brief GetLockScreenIcon allows to obtain lock screen icon url; diff --git a/src/components/policy/policy_external/include/policy/cache_manager_interface.h b/src/components/policy/policy_external/include/policy/cache_manager_interface.h index 980ad42dcd..0cbbb6df1f 100644 --- a/src/components/policy/policy_external/include/policy/cache_manager_interface.h +++ b/src/components/policy/policy_external/include/policy/cache_manager_interface.h @@ -35,6 +35,7 @@ #include <string> #include <vector> +#include "boost/optional.hpp" #include "policy/policy_table/types.h" #include "policy/pt_representation.h" @@ -270,6 +271,24 @@ class CacheManagerInterface { const std::string& policy_app_id) const = 0; /** + * @brief Returns state of the lock screen that could be able to be dismissed + * while connected to SDL, allowing users the ability to interact with the + * app. + * @return bool True if lock screen can be dismissed. + */ + virtual const boost::optional<bool> LockScreenDismissalEnabledState() + const = 0; + + /** + * @brief Returns lock screen warning message. In case when specified language + * is absent in policy table will be returned message on default language + * ("en-us"). Otherwise returns uninitialized boost::optional<std::string> + * @return std::string Lock screen warning message + */ + virtual const boost::optional<std::string> LockScreenDismissalWarningMessage( + const std::string& language) const = 0; + + /** * @brief Allows to update 'vin' field in module_meta table. * * @param new 'vin' value. @@ -290,7 +309,7 @@ class CacheManagerInterface { virtual std::vector<UserFriendlyMessage> GetUserFriendlyMsg( const std::vector<std::string>& msg_codes, const std::string& language, - const std::string& active_hmi_language) = 0; + const std::string& active_hmi_language) const = 0; /** * @brief Get list of URL to send PTS to diff --git a/src/components/policy/policy_external/include/policy/policy_manager_impl.h b/src/components/policy/policy_external/include/policy/policy_manager_impl.h index 2f8f6cf070..9dd2b3c6ec 100644 --- a/src/components/policy/policy_external/include/policy/policy_manager_impl.h +++ b/src/components/policy/policy_external/include/policy/policy_manager_impl.h @@ -148,6 +148,11 @@ class PolicyManagerImpl : public PolicyManager { */ void KmsChanged(int kilometers) OVERRIDE; + const boost::optional<bool> LockScreenDismissalEnabledState() const OVERRIDE; + + const boost::optional<std::string> LockScreenDismissalWarningMessage( + const std::string& language) const OVERRIDE; + /** * @brief Increments counter of ignition cycles */ @@ -851,6 +856,17 @@ class PolicyManagerImpl : public PolicyManager { const std::shared_ptr<policy_table::Table> snapshot); /** + * @brief Compares current policies to the updated one. + * Trigger actions in case if certain fields after udate was changes. + * This function should be called after PT update. + * Actions require already updated policy table + * @param update Shared pointer to policy table udpate + * @param snapshot Shared pointer to old copy of policy table + */ + void CheckPermissionsChangesAfterUpdate(const policy_table::Table& update, + const policy_table::Table& snapshot); + + /** * @brief Processes results from policy table update analysis done by * CheckPermissionsChanges() by filling ApplicationsPoliciesActions struct * with actions which should be done for every application and passes them to diff --git a/src/components/policy/policy_external/include/policy/policy_table/types.h b/src/components/policy/policy_external/include/policy/policy_table/types.h index 994fd86579..8795e2690f 100644 --- a/src/components/policy/policy_external/include/policy/policy_table/types.h +++ b/src/components/policy/policy_external/include/policy/policy_table/types.h @@ -364,6 +364,7 @@ struct ModuleConfig : CompositeType { Optional<String<0, 65535> > certificate; Optional<Boolean> preloaded_pt; Optional<Boolean> full_app_id_supported; + Optional<Boolean> lock_screen_dismissal_enabled; public: ModuleConfig(); diff --git a/src/components/policy/policy_external/src/cache_manager.cc b/src/components/policy/policy_external/src/cache_manager.cc index bd38f7bf8f..4170e7aaa6 100644 --- a/src/components/policy/policy_external/src/cache_manager.cc +++ b/src/components/policy/policy_external/src/cache_manager.cc @@ -1561,10 +1561,44 @@ bool CacheManager::UnknownRPCPassthroughAllowed( return false; } +const boost::optional<bool> CacheManager::LockScreenDismissalEnabledState() + const { + boost::optional<bool> empty; + CACHE_MANAGER_CHECK(empty); + sync_primitives::AutoLock auto_lock(cache_lock_); + policy_table::ModuleConfig& module_config = pt_->policy_table.module_config; + if (module_config.lock_screen_dismissal_enabled.is_initialized()) { + return boost::optional<bool>(*module_config.lock_screen_dismissal_enabled); + } + return empty; +} + +const boost::optional<std::string> +CacheManager::LockScreenDismissalWarningMessage( + const std::string& language) const { + LOG4CXX_AUTO_TRACE(logger_); + boost::optional<std::string> empty; + CACHE_MANAGER_CHECK(empty); + + const std::string lock_screen_dismissal_warning_message = + "LockScreenDismissalWarning"; + sync_primitives::AutoLock auto_lock(cache_lock_); + + std::vector<std::string> msg_codes{lock_screen_dismissal_warning_message}; + + const auto messages = GetUserFriendlyMsg(msg_codes, language, "en-us"); + + if (messages.empty() || messages[0].text_body.empty()) { + return empty; + } + + return boost::optional<std::string>(messages[0].text_body); +} + std::vector<UserFriendlyMessage> CacheManager::GetUserFriendlyMsg( const std::vector<std::string>& msg_codes, const std::string& language, - const std::string& active_hmi_language) { + const std::string& active_hmi_language) const { LOG4CXX_AUTO_TRACE(logger_); std::vector<UserFriendlyMessage> result; CACHE_MANAGER_CHECK(result); diff --git a/src/components/policy/policy_external/src/policy_manager_impl.cc b/src/components/policy/policy_external/src/policy_manager_impl.cc index 15900f0187..42b67734ae 100644 --- a/src/components/policy/policy_external/src/policy_manager_impl.cc +++ b/src/components/policy/policy_external/src/policy_manager_impl.cc @@ -491,6 +491,8 @@ bool PolicyManagerImpl::LoadPT(const std::string& file, ProcessAppPolicyCheckResults( results, pt_update->policy_table.app_policies_section.apps); + CheckPermissionsChangesAfterUpdate(*pt_update, *policy_table_snapshot); + listener_->OnCertificateUpdated( *(pt_update->policy_table.module_config.certificate)); @@ -538,6 +540,17 @@ CheckAppPolicyResults PolicyManagerImpl::CheckPermissionsChanges( return out_results; } +void PolicyManagerImpl::CheckPermissionsChangesAfterUpdate( + const policy_table::Table& update, const policy_table::Table& snapshot) { + const auto new_lock_screen_dismissal_enabled = + update.policy_table.module_config.lock_screen_dismissal_enabled; + const auto old_lock_screen_dismissal_enabled = + snapshot.policy_table.module_config.lock_screen_dismissal_enabled; + if (new_lock_screen_dismissal_enabled != old_lock_screen_dismissal_enabled) { + listener()->OnLockScreenDismissalStateChanged(); + } +} + void PolicyManagerImpl::ProcessAppPolicyCheckResults( const CheckAppPolicyResults& results, const policy_table::ApplicationPolicies& app_policies) { @@ -1738,6 +1751,19 @@ void PolicyManagerImpl::KmsChanged(int kilometers) { } } +const boost::optional<bool> PolicyManagerImpl::LockScreenDismissalEnabledState() + const { + LOG4CXX_AUTO_TRACE(logger_); + return cache_->LockScreenDismissalEnabledState(); +} + +const boost::optional<std::string> +PolicyManagerImpl::LockScreenDismissalWarningMessage( + const std::string& language) const { + LOG4CXX_AUTO_TRACE(logger_); + return cache_->LockScreenDismissalWarningMessage(language); +} + void PolicyManagerImpl::IncrementIgnitionCycles() { cache_->IncrementIgnitionCycles(); } diff --git a/src/components/policy/policy_external/src/policy_table/types.cc b/src/components/policy/policy_external/src/policy_table/types.cc index ca3f8a1648..d39b3f7623 100644 --- a/src/components/policy/policy_external/src/policy_table/types.cc +++ b/src/components/policy/policy_external/src/policy_table/types.cc @@ -788,8 +788,9 @@ ModuleConfig::ModuleConfig(const Json::Value* value__) , preloaded_date(impl::ValueMember(value__, "preloaded_date")) , certificate(impl::ValueMember(value__, "certificate")) , preloaded_pt(impl::ValueMember(value__, "preloaded_pt")) - , full_app_id_supported( - impl::ValueMember(value__, "full_app_id_supported")) {} + , full_app_id_supported(impl::ValueMember(value__, "full_app_id_supported")) + , lock_screen_dismissal_enabled( + impl::ValueMember(value__, "lock_screen_dismissal_enabled")) {} void ModuleConfig::SafeCopyFrom(const ModuleConfig& from) { exchange_after_x_days = from.exchange_after_x_days; @@ -801,6 +802,7 @@ void ModuleConfig::SafeCopyFrom(const ModuleConfig& from) { endpoints = from.endpoints; notifications_per_minute_by_priority = from.notifications_per_minute_by_priority; + lock_screen_dismissal_enabled = from.lock_screen_dismissal_enabled; certificate.assign_if_valid(from.certificate); vehicle_make.assign_if_valid(from.vehicle_make); @@ -834,6 +836,9 @@ Json::Value ModuleConfig::ToJsonValue() const { impl::WriteJsonField("vehicle_year", vehicle_year, &result__); impl::WriteJsonField("certificate", certificate, &result__); impl::WriteJsonField("preloaded_date", preloaded_date, &result__); + impl::WriteJsonField("lock_screen_dismissal_enabled", + lock_screen_dismissal_enabled, + &result__); return result__; } @@ -883,6 +888,9 @@ bool ModuleConfig::is_valid() const { if (!preloaded_date.is_valid()) { return false; } + if (!lock_screen_dismissal_enabled.is_valid()) { + return false; + } return Validate(); } @@ -925,6 +933,9 @@ bool ModuleConfig::struct_empty() const { if (notifications_per_minute_by_priority.is_initialized()) { return false; } + if (lock_screen_dismissal_enabled.is_initialized()) { + return false; + } if (vehicle_make.is_initialized()) { return false; } @@ -979,6 +990,10 @@ void ModuleConfig::ReportErrors(rpc::ValidationReport* report__) const { notifications_per_minute_by_priority.ReportErrors( &report__->ReportSubobject("notifications_per_minute_by_priority")); } + if (!lock_screen_dismissal_enabled.is_valid()) { + lock_screen_dismissal_enabled.ReportErrors( + &report__->ReportSubobject("lock_screen_dismissal_enabled")); + } if (!vehicle_make.is_valid()) { vehicle_make.ReportErrors(&report__->ReportSubobject("vehicle_make")); } @@ -1037,6 +1052,7 @@ void ModuleConfig::SetPolicyTableType(PolicyTableType pt_type) { seconds_between_retries.SetPolicyTableType(pt_type); endpoints.SetPolicyTableType(pt_type); notifications_per_minute_by_priority.SetPolicyTableType(pt_type); + lock_screen_dismissal_enabled.SetPolicyTableType(pt_type); vehicle_make.SetPolicyTableType(pt_type); vehicle_model.SetPolicyTableType(pt_type); vehicle_year.SetPolicyTableType(pt_type); diff --git a/src/components/policy/policy_external/src/sql_pt_queries.cc b/src/components/policy/policy_external/src/sql_pt_queries.cc index f4cac214a5..5592fdecd8 100644 --- a/src/components/policy/policy_external/src/sql_pt_queries.cc +++ b/src/components/policy/policy_external/src/sql_pt_queries.cc @@ -76,7 +76,8 @@ const std::string kCreateSchema = " `vehicle_model` VARCHAR(45), " " `vehicle_year` VARCHAR(4), " " `preloaded_date` VARCHAR (10), " - " `certificate` VARCHAR (45) " + " `certificate` VARCHAR (45), " + " `lock_screen_dismissal_enabled` BOOL" "); " "CREATE TABLE IF NOT EXISTS `functional_group`( " " `id` INTEGER PRIMARY KEY NOT NULL, " @@ -459,7 +460,7 @@ const std::string kInsertInitData = " VALUES (0, 0, 0, 0); " "INSERT OR IGNORE INTO `module_config` (`preloaded_pt`, `is_first_run`," " `exchange_after_x_ignition_cycles`, `exchange_after_x_kilometers`, " - " `exchange_after_x_days`, `timeout_after_x_seconds`) " + " `exchange_after_x_days`, `timeout_after_x_seconds`)" " VALUES(1, 0, 0, 0, 0, 0); " "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('EMERGENCY'); " "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('NAVIGATION'); " @@ -734,7 +735,7 @@ const std::string kUpdateModuleConfig = " `exchange_after_x_kilometers` = ?, `exchange_after_x_days` = ?, " " `timeout_after_x_seconds` = ?, `vehicle_make` = ?, " " `vehicle_model` = ?, `vehicle_year` = ?, `preloaded_date` = ?, " - " `certificate` = ? "; + " `certificate` = ?, lock_screen_dismissal_enabled = ?"; const std::string kInsertEndpoint = "INSERT INTO `endpoint` (`service`, `url`, `application_id`) " @@ -785,7 +786,8 @@ const std::string kSelectModuleConfig = "SELECT `preloaded_pt`, `exchange_after_x_ignition_cycles`, " " `exchange_after_x_kilometers`, `exchange_after_x_days`, " " `timeout_after_x_seconds`, `vehicle_make`," - " `vehicle_model`, `vehicle_year`, `preloaded_date`, `certificate` " + " `vehicle_model`, `vehicle_year`, `preloaded_date`, `certificate`, " + " `lock_screen_dismissal_enabled` " " FROM `module_config`"; const std::string kSelectEndpoints = diff --git a/src/components/policy/policy_external/src/sql_pt_representation.cc b/src/components/policy/policy_external/src/sql_pt_representation.cc index 1bb0cf0fa1..d5950f9d42 100644 --- a/src/components/policy/policy_external/src/sql_pt_representation.cc +++ b/src/components/policy/policy_external/src/sql_pt_representation.cc @@ -552,6 +552,9 @@ void SQLPTRepresentation::GatherModuleConfig( *config->vehicle_year = query.GetString(7); *config->preloaded_date = query.GetString(8); *config->certificate = query.GetString(9); + if (!query.IsNull(10)) { + *config->lock_screen_dismissal_enabled = query.GetBoolean(10); + } } utils::dbms::SQLQuery endpoints(db()); @@ -1412,6 +1415,10 @@ bool SQLPTRepresentation::SaveModuleConfig( config.certificate.is_initialized() ? query.Bind(9, *(config.certificate)) : query.Bind(9); + config.lock_screen_dismissal_enabled.is_initialized() + ? query.Bind(10, *(config.lock_screen_dismissal_enabled)) + : query.Bind(10); + if (!query.Exec()) { LOG4CXX_WARN(logger_, "Incorrect update module config"); return false; diff --git a/src/components/policy/policy_regular/include/policy/cache_manager.h b/src/components/policy/policy_regular/include/policy/cache_manager.h index 30732f685c..1c28b596c0 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager.h @@ -146,6 +146,10 @@ class CacheManager : public CacheManagerInterface { */ virtual const VehicleInfo GetVehicleInfo() const; + const boost::optional<bool> LockScreenDismissalEnabledState() const OVERRIDE; + + const boost::optional<std::string> LockScreenDismissalWarningMessage( + const std::string& language) const OVERRIDE; /** * @brief Get a list of enabled cloud applications * @param enabled_apps List filled with the policy app id of each enabled @@ -267,7 +271,8 @@ class CacheManager : public CacheManagerInterface { * @return Array of appropriate messages parameters */ std::vector<UserFriendlyMessage> GetUserFriendlyMsg( - const std::vector<std::string>& msg_codes, const std::string& language); + const std::vector<std::string>& msg_codes, + const std::string& language) const; /** * @brief Get list of URLs related to particular service diff --git a/src/components/policy/policy_regular/include/policy/cache_manager_interface.h b/src/components/policy/policy_regular/include/policy/cache_manager_interface.h index da15a4ecab..e8f2644bc5 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager_interface.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager_interface.h @@ -35,11 +35,13 @@ #include <string> #include <vector> +#include "boost/optional.hpp" #include "policy/policy_settings.h" #include "policy/policy_table/types.h" #include "policy/policy_types.h" #include "policy/usage_statistics/counter.h" +#include "utils/optional.h" namespace policy_table = rpc::policy_table_interface_base; @@ -255,6 +257,23 @@ class CacheManagerInterface { const std::string& policy_app_id) const = 0; /** + * @brief Returns state of the lock screen that could be able to be dismissed + * while connected to SDL, allowing users the ability to interact with the + * app. + * @return bool True if lock screen can be dismissed. + */ + virtual const boost::optional<bool> LockScreenDismissalEnabledState() + const = 0; + + /** + * @brief Returns lock screen warning message. In case when specified language + * is absent in policy table will be returned message on default language + * ("en-us"). Otherwise returns uninitialized boost::optional<std::string> + * @return std::string Lock screen warning message + */ + virtual const boost::optional<std::string> LockScreenDismissalWarningMessage( + const std::string& language_code) const = 0; + /** * @brief Allows to update 'vin' field in module_meta table. * * @param new 'vin' value. @@ -274,7 +293,7 @@ class CacheManagerInterface { */ virtual std::vector<UserFriendlyMessage> GetUserFriendlyMsg( const std::vector<std::string>& msg_codes, - const std::string& language) = 0; + const std::string& language) const = 0; /** * @brief Get list of URLs related to particular service diff --git a/src/components/policy/policy_regular/include/policy/policy_manager_impl.h b/src/components/policy/policy_regular/include/policy/policy_manager_impl.h index 1860f7e591..13d19e1a41 100644 --- a/src/components/policy/policy_regular/include/policy/policy_manager_impl.h +++ b/src/components/policy/policy_regular/include/policy/policy_manager_impl.h @@ -162,6 +162,11 @@ class PolicyManagerImpl : public PolicyManager { */ void KmsChanged(int kilometers) OVERRIDE; + const boost::optional<bool> LockScreenDismissalEnabledState() const OVERRIDE; + + const boost::optional<std::string> LockScreenDismissalWarningMessage( + const std::string& language) const OVERRIDE; + /** * @brief Increments counter of ignition cycles */ @@ -820,6 +825,17 @@ class PolicyManagerImpl : public PolicyManager { const std::shared_ptr<policy_table::Table> snapshot); /** + * @brief Compares current policies to the updated one. + * Trigger actions in case if certain fields after update were changed. + * This function should be called after PT update. + * Actions require already updated policy table + * @param update Shared pointer to policy table update + * @param snapshot Shared pointer to old copy of policy table + */ + void CheckPermissionsChangesAfterUpdate(const policy_table::Table& update, + const policy_table::Table& snapshot); + + /** * @brief Fill structure to be sent with OnPermissionsChanged notification * * @param Policy table struct, which contains rpc functional groups data diff --git a/src/components/policy/policy_regular/include/policy/policy_table/types.h b/src/components/policy/policy_regular/include/policy/policy_table/types.h index e41069a86c..c2a8f901ad 100644 --- a/src/components/policy/policy_regular/include/policy/policy_table/types.h +++ b/src/components/policy/policy_regular/include/policy/policy_table/types.h @@ -302,6 +302,7 @@ struct ModuleConfig : CompositeType { Optional<String<4, 4> > vehicle_year; Optional<String<0, 10> > preloaded_date; Optional<String<0, 65535> > certificate; + Optional<Boolean> lock_screen_dismissal_enabled; public: ModuleConfig(); diff --git a/src/components/policy/policy_regular/src/cache_manager.cc b/src/components/policy/policy_regular/src/cache_manager.cc index 94ce52b6f1..d121886765 100644 --- a/src/components/policy/policy_regular/src/cache_manager.cc +++ b/src/components/policy/policy_regular/src/cache_manager.cc @@ -856,8 +856,47 @@ bool CacheManager::UnknownRPCPassthroughAllowed( return false; } +const boost::optional<bool> CacheManager::LockScreenDismissalEnabledState() + const { + LOG4CXX_AUTO_TRACE(logger_); + boost::optional<bool> empty; + CACHE_MANAGER_CHECK(empty); + sync_primitives::AutoLock auto_lock(cache_lock_); + policy_table::ModuleConfig& module_config = pt_->policy_table.module_config; + if (module_config.lock_screen_dismissal_enabled.is_initialized()) { + LOG4CXX_TRACE(logger_, + "state = " << *module_config.lock_screen_dismissal_enabled); + return boost::optional<bool>(*module_config.lock_screen_dismissal_enabled); + } + LOG4CXX_TRACE(logger_, "state = empty"); + return empty; +} + +const boost::optional<std::string> +CacheManager::LockScreenDismissalWarningMessage( + const std::string& language) const { + LOG4CXX_AUTO_TRACE(logger_); + boost::optional<std::string> empty; + CACHE_MANAGER_CHECK(empty); + + const std::string lock_screen_dismissal_warning_message = + "LockScreenDismissalWarning"; + sync_primitives::AutoLock auto_lock(cache_lock_); + + std::vector<std::string> msg_codes{lock_screen_dismissal_warning_message}; + + const auto messages = GetUserFriendlyMsg(msg_codes, language); + + if (messages.empty() || messages[0].text_body.empty()) { + return empty; + } + + return boost::optional<std::string>(messages[0].text_body); +} + std::vector<UserFriendlyMessage> CacheManager::GetUserFriendlyMsg( - const std::vector<std::string>& msg_codes, const std::string& language) { + const std::vector<std::string>& msg_codes, + const std::string& language) const { LOG4CXX_AUTO_TRACE(logger_); std::vector<UserFriendlyMessage> result; CACHE_MANAGER_CHECK(result); @@ -903,6 +942,12 @@ std::vector<UserFriendlyMessage> CacheManager::GetUserFriendlyMsg( UserFriendlyMessage msg; msg.message_code = *it; + msg.tts = *message_string.tts; + msg.label = *message_string.label; + msg.line1 = *message_string.line1; + msg.line2 = *message_string.line2; + msg.text_body = *message_string.textBody; + result.push_back(msg); } return result; diff --git a/src/components/policy/policy_regular/src/policy_manager_impl.cc b/src/components/policy/policy_regular/src/policy_manager_impl.cc index 0884fc53b6..00a3d33379 100644 --- a/src/components/policy/policy_regular/src/policy_manager_impl.cc +++ b/src/components/policy/policy_regular/src/policy_manager_impl.cc @@ -356,6 +356,7 @@ bool PolicyManagerImpl::LoadPT(const std::string& file, ForcePTExchange(); return false; } + CheckPermissionsChangesAfterUpdate(*pt_update, *policy_table_snapshot); listener_->OnCertificateUpdated( *(pt_update->policy_table.module_config.certificate)); @@ -390,7 +391,7 @@ bool PolicyManagerImpl::LoadPT(const std::string& file, void PolicyManagerImpl::CheckPermissionsChanges( const std::shared_ptr<policy_table::Table> pt_update, const std::shared_ptr<policy_table::Table> snapshot) { - LOG4CXX_INFO(logger_, "Checking incoming permissions."); + LOG4CXX_AUTO_TRACE(logger_); // Replace predefined policies with its actual setting, e.g. "123":"default" // to actual values of default section @@ -401,6 +402,17 @@ void PolicyManagerImpl::CheckPermissionsChanges( CheckAppPolicy(this, pt_update, snapshot)); } +void PolicyManagerImpl::CheckPermissionsChangesAfterUpdate( + const policy_table::Table& update, const policy_table::Table& snapshot) { + const auto new_lock_screen_dismissal_enabled = + update.policy_table.module_config.lock_screen_dismissal_enabled; + const auto old_lock_screen_dismissal_enabled = + snapshot.policy_table.module_config.lock_screen_dismissal_enabled; + if (new_lock_screen_dismissal_enabled != old_lock_screen_dismissal_enabled) { + listener()->OnLockScreenDismissalStateChanged(); + } +} + void PolicyManagerImpl::PrepareNotificationData( const policy_table::FunctionalGroupings& groups, const policy_table::Strings& group_names, @@ -1068,6 +1080,17 @@ void PolicyManagerImpl::KmsChanged(int kilometers) { } } +const boost::optional<bool> PolicyManagerImpl::LockScreenDismissalEnabledState() + const { + return cache_->LockScreenDismissalEnabledState(); +} + +const boost::optional<std::string> +PolicyManagerImpl::LockScreenDismissalWarningMessage( + const std::string& language) const { + return cache_->LockScreenDismissalWarningMessage(language); +} + void PolicyManagerImpl::IncrementIgnitionCycles() { cache_->IncrementIgnitionCycles(); } diff --git a/src/components/policy/policy_regular/src/policy_table/types.cc b/src/components/policy/policy_regular/src/policy_table/types.cc index bdf1329dee..7fdfde996c 100644 --- a/src/components/policy/policy_regular/src/policy_table/types.cc +++ b/src/components/policy/policy_regular/src/policy_table/types.cc @@ -678,7 +678,9 @@ ModuleConfig::ModuleConfig(const Json::Value* value__) , vehicle_model(impl::ValueMember(value__, "vehicle_model")) , vehicle_year(impl::ValueMember(value__, "vehicle_year")) , preloaded_date(impl::ValueMember(value__, "preloaded_date")) - , certificate(impl::ValueMember(value__, "certificate")) {} + , certificate(impl::ValueMember(value__, "certificate")) + , lock_screen_dismissal_enabled( + impl::ValueMember(value__, "lock_screen_dismissal_enabled")) {} void ModuleConfig::SafeCopyFrom(const ModuleConfig& from) { // device_certificates = from.device_certificates; // According to the @@ -692,6 +694,8 @@ void ModuleConfig::SafeCopyFrom(const ModuleConfig& from) { notifications_per_minute_by_priority = from.notifications_per_minute_by_priority; + lock_screen_dismissal_enabled = from.lock_screen_dismissal_enabled; + vehicle_make.assign_if_valid(from.vehicle_make); vehicle_model.assign_if_valid(from.vehicle_model); vehicle_year.assign_if_valid(from.vehicle_year); @@ -723,6 +727,9 @@ Json::Value ModuleConfig::ToJsonValue() const { impl::WriteJsonField("vehicle_year", vehicle_year, &result__); impl::WriteJsonField("certificate", certificate, &result__); impl::WriteJsonField("preloaded_date", preloaded_date, &result__); + impl::WriteJsonField("lock_screen_dismissal_enabled", + lock_screen_dismissal_enabled, + &result__); return result__; } @@ -754,6 +761,9 @@ bool ModuleConfig::is_valid() const { if (!notifications_per_minute_by_priority.is_valid()) { return false; } + if (!lock_screen_dismissal_enabled.is_valid()) { + return false; + } if (!vehicle_make.is_valid()) { return false; } @@ -808,6 +818,9 @@ bool ModuleConfig::struct_empty() const { if (notifications_per_minute_by_priority.is_initialized()) { return false; } + if (lock_screen_dismissal_enabled.is_initialized()) { + return false; + } if (vehicle_make.is_initialized()) { return false; } @@ -863,6 +876,10 @@ void ModuleConfig::ReportErrors(rpc::ValidationReport* report__) const { notifications_per_minute_by_priority.ReportErrors( &report__->ReportSubobject("notifications_per_minute_by_priority")); } + if (!lock_screen_dismissal_enabled.is_valid()) { + lock_screen_dismissal_enabled.ReportErrors( + &report__->ReportSubobject("lock_screen_dismissal_enabled")); + } if (!vehicle_make.is_valid()) { vehicle_make.ReportErrors(&report__->ReportSubobject("vehicle_make")); } @@ -902,6 +919,7 @@ void ModuleConfig::SetPolicyTableType(PolicyTableType pt_type) { seconds_between_retries.SetPolicyTableType(pt_type); endpoints.SetPolicyTableType(pt_type); notifications_per_minute_by_priority.SetPolicyTableType(pt_type); + lock_screen_dismissal_enabled.SetPolicyTableType(pt_type); vehicle_make.SetPolicyTableType(pt_type); vehicle_model.SetPolicyTableType(pt_type); vehicle_year.SetPolicyTableType(pt_type); diff --git a/src/components/policy/policy_regular/src/sql_pt_queries.cc b/src/components/policy/policy_regular/src/sql_pt_queries.cc index a97b0ab153..b3816d37f8 100644 --- a/src/components/policy/policy_regular/src/sql_pt_queries.cc +++ b/src/components/policy/policy_regular/src/sql_pt_queries.cc @@ -71,7 +71,8 @@ const std::string kCreateSchema = " `certificate` TEXT, " " `vehicle_make` VARCHAR(45), " " `vehicle_model` VARCHAR(45), " - " `vehicle_year` VARCHAR(4) " + " `vehicle_year` VARCHAR(4), " + " `lock_screen_dismissal_enabled` BOOL" "); " "CREATE TABLE IF NOT EXISTS `functional_group`( " " `id` INTEGER PRIMARY KEY NOT NULL, " @@ -419,7 +420,7 @@ const std::string kInsertInitData = " VALUES (0, 0, 0, 0); " "INSERT OR IGNORE INTO `module_config` (`preloaded_pt`, `is_first_run`," " `exchange_after_x_ignition_cycles`, `exchange_after_x_kilometers`, " - " `exchange_after_x_days`, `timeout_after_x_seconds`) " + " `exchange_after_x_days`, `timeout_after_x_seconds`)" " VALUES(1, 0, 0, 0, 0, 0); " "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('EMERGENCY'); " "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('NAVIGATION'); " @@ -674,15 +675,17 @@ const std::string kInsertLanguage = "INSERT OR IGNORE INTO `language` (`code`) VALUES (?)"; const std::string kInsertMessageString = - "INSERT INTO `message` (`language_code`, `message_type_name`) " - "VALUES (?, ?)"; + "INSERT INTO `message` (`language_code`, `message_type_name`, `tts`, " + "`label`, `line1`, `line2`, `textBody`) " + "VALUES (?, ?, ?, ?, ?, ?, ?)"; const std::string kUpdateModuleConfig = "UPDATE `module_config` SET `preloaded_pt` = ?, " " `exchange_after_x_ignition_cycles` = ?," " `exchange_after_x_kilometers` = ?, `exchange_after_x_days` = ?, " " `timeout_after_x_seconds` = ?, `certificate` = ?, `vehicle_make` = ?, " - " `vehicle_model` = ?, `vehicle_year` = ? "; + " `vehicle_model` = ?, `vehicle_year` = ?, lock_screen_dismissal_enabled " + "= ?"; const std::string kInsertEndpoint = "INSERT INTO `endpoint` (`service`, `url`, `application_id`) " @@ -722,7 +725,7 @@ const std::string kSelectModuleConfig = "SELECT `preloaded_pt`, `exchange_after_x_ignition_cycles`, " " `exchange_after_x_kilometers`, `exchange_after_x_days`, " " `timeout_after_x_seconds`, `certificate`, `vehicle_make`," - " `vehicle_model`, `vehicle_year` " + " `vehicle_model`, `vehicle_year` ,`lock_screen_dismissal_enabled`" " FROM `module_config`"; const std::string kSelectEndpoints = @@ -907,6 +910,5 @@ const std::string kSaveModuleMeta = "`ignition_cycles_since_last_exchange` = ? "; const std::string kSelectModuleMeta = "SELECT* FROM `module_meta`"; - } // namespace sql_pt } // namespace policy diff --git a/src/components/policy/policy_regular/src/sql_pt_representation.cc b/src/components/policy/policy_regular/src/sql_pt_representation.cc index 20ba9ec651..8ac04ba5f3 100644 --- a/src/components/policy/policy_regular/src/sql_pt_representation.cc +++ b/src/components/policy/policy_regular/src/sql_pt_representation.cc @@ -525,7 +525,9 @@ void SQLPTRepresentation::GatherModuleConfig( *config->vehicle_make = query.GetString(6); *config->vehicle_model = query.GetString(7); *config->vehicle_year = query.GetString(8); - *config->preloaded_date = query.GetString(9); + if (!query.IsNull(9)) { + *config->lock_screen_dismissal_enabled = query.GetBoolean(9); + } } utils::dbms::SQLQuery endpoints(db()); @@ -1365,6 +1367,9 @@ bool SQLPTRepresentation::SaveModuleConfig( : query.Bind(7); config.vehicle_year.is_initialized() ? query.Bind(8, *(config.vehicle_year)) : query.Bind(8); + config.lock_screen_dismissal_enabled.is_initialized() + ? query.Bind(9, *(config.lock_screen_dismissal_enabled)) + : query.Bind(9); if (!query.Exec()) { LOG4CXX_WARN(logger_, "Incorrect update module config"); return false; @@ -1519,6 +1524,25 @@ bool SQLPTRepresentation::SaveMessageString( query.Bind(0, lang); query.Bind(1, type); + if (strings.tts.is_valid() && strings.tts.is_initialized()) { + query.Bind(2, (*strings.tts)); + } + + if (strings.label.is_valid() && strings.label.is_initialized()) { + query.Bind(3, (*strings.label)); + } + + if (strings.line1.is_valid() && strings.line1.is_initialized()) { + query.Bind(4, *(strings.line1)); + } + + if (strings.line2.is_valid() && strings.line2.is_initialized()) { + query.Bind(5, (*strings.line2)); + } + + if (strings.textBody.is_valid() && strings.textBody.is_initialized()) { + query.Bind(6, (*strings.textBody)); + } if (!query.Exec() || !query.Reset()) { LOG4CXX_WARN(logger_, "Incorrect insert into message."); |