Skip to content

Commit

Permalink
Add shared base class for mobile button notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
ychernysheva committed Jul 15, 2021
1 parent 3d7d670 commit 0343ea4
Show file tree
Hide file tree
Showing 11 changed files with 481 additions and 288 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2021, Ford Motor Company
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of the Ford Motor Company nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_BUTTON_NOTIFICATION_TO_MOBILE_H_
#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_BUTTON_NOTIFICATION_TO_MOBILE_H_

#include "application_manager/application.h"
#include "command_notification_impl.h"
#include "interfaces/MOBILE_API.h"

namespace application_manager {
namespace commands {
namespace app_mngr = application_manager;

/**
* @brief Class is intended to encapsulate shared button notification logic in
* base class. Entities defined in this file do not conform to any version of
* HMI or mobile API, and exist only to remove duplication in OnButtonPress and
* OnButtonEvent notifications.
**/
class ButtonNotificationToMobile
: public app_mngr::commands::CommandNotificationImpl {
public:
/**
* @brief ButtonNotificationToMobile class constructor
**/
ButtonNotificationToMobile(
const app_mngr::commands::MessageSharedPtr& message,
app_mngr::ApplicationManager& application_manager,
app_mngr::rpc_service::RPCService& rpc_service,
app_mngr::HMICapabilities& hmi_capabilities,
policy::PolicyHandlerInterface& policy_handler);

/**
* @brief ButtonNotificationToMobile class destructor
**/
~ButtonNotificationToMobile();

/**
* @brief Execute command
**/
void Run() OVERRIDE;

protected:
virtual void SendButtonNotification(app_mngr::ApplicationSharedPtr app) = 0;

/**
* @brief HandleCustomButton handle event for custom buttons
* @param app pointer to application data.
**/
void HandleCustomButton(app_mngr::ApplicationSharedPtr app);

/**
* @brief HandleOKButton handle event for OK button
* @param app pointer to application data.
**/
void HandleOKButton(app_mngr::ApplicationSharedPtr app);

/**
* @brief HandleMediaButton handle event for media buttons
* @param app pointer to application data.
**/
void HandleMediaButton(app_mngr::ApplicationSharedPtr app);

/**
* @brief DoesParamExist check whether param is exists in msg_params
* @param param_name name of parameter to find
**/
bool DoesParamExist(const std::string& param_name) const;

/**
* @brief SubscribedApps get subscribed apps for btn id received in message
* @return Return applications list subscribed to current button
**/
std::vector<ApplicationSharedPtr> SubscribedApps() const;
};
} // namespace commands
} // namespace application_manager

#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_BUTTON_NOTIFICATION_TO_MOBILE_H_
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,16 @@ class MessageHelper {
const hmi_apis::FunctionID::eType function_id,
ApplicationManager& app_mngr);

/**
* @brief Creates button subscription request to mobile
* @param app shared pointer to application instance
* @param source_message source message
* @return Smart object with fulfilled request
*/
static smart_objects::SmartObjectSPtr CreateButtonNotificationToMobile(
ApplicationSharedPtr app,
const smart_objects::SmartObject& source_message);

/**
* @brief Creates button subscription request to hmi
* @param app_id id of application for which request should be created
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_MOBILE_ON_BUTTON_EVENT_NOTIFICATION_H_

#include "application_manager/application.h"
#include "application_manager/commands/button_notification_to_mobile.h"
#include "application_manager/commands/command_notification_impl.h"
#include "utils/macro.h"

Expand All @@ -50,7 +51,7 @@ namespace mobile {
* to mobile device that some button was pressed on HMI.
**/
class OnButtonEventNotification
: public app_mngr::commands::CommandNotificationImpl {
: public app_mngr::commands::ButtonNotificationToMobile {
public:
/**
* @brief OnButtonEventNotification class constructor
Expand All @@ -68,18 +69,13 @@ class OnButtonEventNotification
**/
virtual ~OnButtonEventNotification();

/**
* @brief Execute command
**/
virtual void Run();

private:
protected:
/*
* @brief Sends button event notification to mobile device
*
* @param app Application to receive notification
*/
void SendButtonEvent(app_mngr::ApplicationConstSharedPtr app);
void SendButtonNotification(app_mngr::ApplicationSharedPtr app) OVERRIDE;

DISALLOW_COPY_AND_ASSIGN(OnButtonEventNotification);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_MOBILE_ON_BUTTON_PRESS_NOTIFICATION_H_

#include "application_manager/application.h"
#include "application_manager/commands/button_notification_to_mobile.h"
#include "application_manager/commands/command_notification_impl.h"
#include "utils/macro.h"

Expand All @@ -50,7 +51,7 @@ namespace mobile {
* to mobile device that some button was pressed on HMI.
**/
class OnButtonPressNotification
: public app_mngr::commands::CommandNotificationImpl {
: public app_mngr::commands::ButtonNotificationToMobile {
public:
/**
* @brief OnButtonPressNotification class constructor
Expand All @@ -66,20 +67,15 @@ class OnButtonPressNotification
/**
* @brief OnButtonEventCommand class destructor
**/
virtual ~OnButtonPressNotification();

/**
* @brief Execute command
**/
virtual void Run();
~OnButtonPressNotification();

private:
/*
* @brief Sends button press notification to mobile device
*
* @param app Application to receive notification
*/
void SendButtonPress(app_mngr::ApplicationConstSharedPtr app);
void SendButtonNotification(app_mngr::ApplicationSharedPtr app) OVERRIDE;

DISALLOW_COPY_AND_ASSIGN(OnButtonPressNotification);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "sdl_rpc_plugin/commands/mobile/on_button_event_notification.h"

#include "application_manager/application_impl.h"
#include "application_manager/message_helper.h"
#include "interfaces/MOBILE_API.h"

namespace sdl_rpc_plugin {
Expand All @@ -51,146 +52,37 @@ OnButtonEventNotification::OnButtonEventNotification(
rpc_service::RPCService& rpc_service,
HMICapabilities& hmi_capabilities,
policy::PolicyHandlerInterface& policy_handler)
: CommandNotificationImpl(message,
application_manager,
rpc_service,
hmi_capabilities,
policy_handler) {}
: ButtonNotificationToMobile(message,
application_manager,
rpc_service,
hmi_capabilities,
policy_handler) {}

OnButtonEventNotification::~OnButtonEventNotification() {}

void OnButtonEventNotification::Run() {
void OnButtonEventNotification::SendButtonNotification(
ApplicationSharedPtr app) {
SDL_LOG_AUTO_TRACE();

const uint32_t btn_id = static_cast<uint32_t>(
(*message_)[strings::msg_params][hmi_response::button_name].asInt());

const bool is_app_id_exists =
(*message_)[strings::msg_params].keyExists(strings::app_id);
ApplicationSharedPtr app;

// CUSTOM_BUTTON notification
if (static_cast<uint32_t>(mobile_apis::ButtonName::CUSTOM_BUTTON) == btn_id) {
// app_id is mandatory for CUSTOM_BUTTON notification
if (!is_app_id_exists) {
SDL_LOG_ERROR("CUSTOM_BUTTON OnButtonEvent without app_id.");
return;
}

app = application_manager_.application(
(*message_)[strings::msg_params][strings::app_id].asUInt());

// custom_button_id is mandatory for CUSTOM_BUTTON notification
if (false == (*message_)[strings::msg_params].keyExists(
hmi_response::custom_button_id)) {
SDL_LOG_ERROR("CUSTOM_BUTTON OnButtonEvent without custom_button_id.");
return;
}

if (!app) {
SDL_LOG_ERROR("Application doesn't exist.");
return;
}

uint32_t custom_btn_id = 0;
custom_btn_id =
(*message_)[strings::msg_params][hmi_response::custom_button_id]
.asUInt();

if (false == app->IsSubscribedToSoftButton(custom_btn_id)) {
SDL_LOG_ERROR("Application doesn't subscribed to this custom_button_id.");
return;
}

const auto window_id = app->GetSoftButtonWindowID(custom_btn_id);
(*message_)[strings::msg_params][strings::window_id] = window_id;
const auto window_hmi_level = app->hmi_level(window_id);
if ((mobile_api::HMILevel::HMI_NONE == window_hmi_level)) {
SDL_LOG_WARN(
"CUSTOM_BUTTON OnButtonEvent notification is not allowed in "
"NONE hmi level");
return;
}

SendButtonEvent(app);
return;
}
auto& ref = (*message_)[strings::msg_params];

const std::vector<ApplicationSharedPtr>& subscribed_apps =
application_manager_.applications_by_button(btn_id);

std::vector<ApplicationSharedPtr>::const_iterator it =
subscribed_apps.begin();
for (; subscribed_apps.end() != it; ++it) {
ApplicationSharedPtr subscribed_app = *it;
if (!subscribed_app) {
SDL_LOG_WARN("Null pointer to subscribed app.");
continue;
}

// Send ButtonEvent notification only in HMI_FULL or HMI_LIMITED mode
const mobile_apis::HMILevel::eType app_hmi_level =
subscribed_app->hmi_level(
mobile_apis::PredefinedWindows::DEFAULT_WINDOW);
if ((mobile_api::HMILevel::HMI_FULL != app_hmi_level) &&
(mobile_api::HMILevel::HMI_LIMITED != app_hmi_level)) {
SDL_LOG_WARN("OnButtonEvent notification is allowed only"
<< "in FULL or LIMITED hmi level");
continue;
}
// if OK button and "app_id" absent send notification only in HMI_FULL mode
// otherwise send to subscribed apps in limited
if (is_app_id_exists || hmi_apis::Common_ButtonName::OK != btn_id ||
subscribed_app->IsFullscreen()) {
SendButtonEvent(subscribed_app);
}
}
}
mobile_apis::ButtonEventMode::eType btn_event_mode;
if (ref.keyExists(hmi_response::button_mode)) {
btn_event_mode = static_cast<mobile_apis::ButtonEventMode::eType>(
ref[hmi_response::button_mode].asInt());

void OnButtonEventNotification::SendButtonEvent(ApplicationConstSharedPtr app) {
if (!app) {
SDL_LOG_ERROR("OnButtonEvent NULL pointer");
return;
} else if (ref.keyExists(strings::button_event_mode)) {
btn_event_mode = static_cast<mobile_apis::ButtonEventMode::eType>(
ref[strings::button_event_mode].asInt());
}

smart_objects::SmartObjectSPtr on_btn_event =
std::make_shared<smart_objects::SmartObject>();

if (!on_btn_event) {
SDL_LOG_ERROR("OnButtonEvent NULL pointer");
return;
}

(*on_btn_event)[strings::params][strings::connection_key] = app->app_id();

(*on_btn_event)[strings::params][strings::function_id] =
static_cast<int32_t>(mobile_apis::FunctionID::eType::OnButtonEventID);
message_ = MessageHelper::CreateButtonNotificationToMobile(app, *message_);

mobile_apis::ButtonName::eType btn_id =
static_cast<mobile_apis::ButtonName::eType>(
(*message_)[strings::msg_params][hmi_response::button_name].asInt());
(*message_)[strings::msg_params][strings::button_event_mode] = btn_event_mode;

if (btn_id == mobile_apis::ButtonName::PLAY_PAUSE &&
app->msg_version() < utils::rpc_version_5) {
btn_id = mobile_apis::ButtonName::OK;
}

(*on_btn_event)[strings::msg_params][strings::button_name] = btn_id;
(*on_btn_event)[strings::msg_params][strings::button_event_mode] =
(*message_)[strings::msg_params][hmi_response::button_mode];

if ((*message_)[strings::msg_params].keyExists(
hmi_response::custom_button_id)) {
(*on_btn_event)[strings::msg_params][strings::custom_button_id] =
(*message_)[strings::msg_params][strings::custom_button_id];
}

if ((*message_)[strings::msg_params].keyExists(strings::window_id)) {
(*on_btn_event)[strings::msg_params][strings::window_id] =
(*message_)[strings::msg_params][strings::window_id];
}
(*message_)[strings::params][strings::function_id] =
mobile_apis::FunctionID::eType::OnButtonEventID;

message_ = on_btn_event;
SendNotification();
}

Expand Down
Loading

0 comments on commit 0343ea4

Please sign in to comment.