summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtem Nosach (GitHub) <ANosach@luxoft.com>2016-07-18 15:44:47 +0300
committerGitHub <noreply@github.com>2016-07-18 15:44:47 +0300
commit3dc74d9071cdb44840a74bef8353109623b7923c (patch)
tree0ba50b1a141c499e8a4e3fc7bc5bc42f11212572
parent7ae459d489ba7a6f3ea2c9517c5673ca26159481 (diff)
parentd2f17e8efe863ef4998d8f4dc0385ccb3c747dc5 (diff)
downloadsdl_core-3dc74d9071cdb44840a74bef8353109623b7923c.tar.gz
Merge pull request #694 from dev-gh/fix/Fixes_LAUNCH_APP_flow
Fixes SDL4.0 LAUNCH_APP flow
-rw-r--r--src/components/application_manager/include/application_manager/application_manager.h31
-rw-r--r--src/components/application_manager/include/application_manager/application_manager_impl.h25
-rw-r--r--src/components/application_manager/include/application_manager/commands/hmi/sdl_activate_app_request.h33
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc21
-rw-r--r--src/components/application_manager/src/commands/hmi/sdl_activate_app_request.cc195
-rw-r--r--src/components/application_manager/test/include/application_manager/mock_application_manager.h6
6 files changed, 223 insertions, 88 deletions
diff --git a/src/components/application_manager/include/application_manager/application_manager.h b/src/components/application_manager/include/application_manager/application_manager.h
index 411ecec092..97c38cd134 100644
--- a/src/components/application_manager/include/application_manager/application_manager.h
+++ b/src/components/application_manager/include/application_manager/application_manager.h
@@ -87,8 +87,22 @@ struct ApplicationsAppIdSorter {
return lhs->app_id() < rhs->app_id();
}
};
+
+struct ApplicationsPolicyAppIdSorter {
+ bool operator()(const ApplicationSharedPtr lhs,
+ const ApplicationSharedPtr rhs) {
+ if (lhs->policy_app_id() == rhs->policy_app_id()) {
+ return lhs->device() < rhs->device();
+ }
+ return lhs->policy_app_id() < rhs->policy_app_id();
+ }
+};
+
typedef std::set<ApplicationSharedPtr, ApplicationsAppIdSorter> ApplicationSet;
+typedef std::set<ApplicationSharedPtr, ApplicationsPolicyAppIdSorter>
+ AppsWaitRegistrationSet;
+
// typedef for Applications list iterator
typedef ApplicationSet::iterator ApplicationSetIt;
@@ -326,6 +340,23 @@ class ApplicationManager {
virtual void MarkAppsGreyOut(const connection_handler::DeviceHandle handle,
bool is_greyed_out) = 0;
+
+ /**
+ * @brief Returns pointer to application-to-be-registered (from QUERY_APP
+ * list)
+ * @param hmi_id HMI application id
+ * @return Pointer to application or uninitialized shared pointer
+ */
+ virtual ApplicationConstSharedPtr WaitingApplicationByID(
+ const uint32_t hmi_id) const = 0;
+
+ /**
+ * @brief Returns list of applications-to-be-registered (QUERY_APP list)
+ * @return Locked list of applications
+ */
+ virtual DataAccessor<AppsWaitRegistrationSet> AppsWaitingForRegistration()
+ const = 0;
+
virtual bool IsAppsQueriedFrom(
const connection_handler::DeviceHandle handle) const = 0;
diff --git a/src/components/application_manager/include/application_manager/application_manager_impl.h b/src/components/application_manager/include/application_manager/application_manager_impl.h
index 91b0f3f86f..dda192f8b0 100644
--- a/src/components/application_manager/include/application_manager/application_manager_impl.h
+++ b/src/components/application_manager/include/application_manager/application_manager_impl.h
@@ -835,9 +835,9 @@ class ApplicationManagerImpl
ApplicationConstSharedPtr application) const;
/**
- * Getter for resume_controller
- * @return Resume Controller
- */
+ * Getter for resume_controller
+ * @return Resume Controller
+ */
resumption::ResumeCtrl& resume_controller() OVERRIDE {
return resume_ctrl_;
}
@@ -991,20 +991,7 @@ class ApplicationManagerImpl
}
};
- struct ApplicationsPolicyAppIdSorter {
- bool operator()(const ApplicationSharedPtr lhs,
- const ApplicationSharedPtr rhs) {
- if (lhs->policy_app_id() == rhs->policy_app_id()) {
- return lhs->device() < rhs->device();
- }
- return lhs->policy_app_id() < rhs->policy_app_id();
- }
- };
-
// typedef for Applications list
- typedef std::set<ApplicationSharedPtr, ApplicationsPolicyAppIdSorter>
- AppsWaitRegistrationSet;
-
typedef std::set<std::string> ForbiddenApps;
struct AppIdPredicate {
@@ -1093,6 +1080,12 @@ class ApplicationManagerImpl
void MarkAppsGreyOut(const connection_handler::DeviceHandle handle,
bool is_greyed_out) OVERRIDE;
+ ApplicationConstSharedPtr WaitingApplicationByID(
+ const uint32_t hmi_id) const OVERRIDE;
+
+ DataAccessor<AppsWaitRegistrationSet> AppsWaitingForRegistration()
+ const OVERRIDE;
+
/**
* @brief Checks, if apps list had been queried already from certain device
* @param handle, Device handle
diff --git a/src/components/application_manager/include/application_manager/commands/hmi/sdl_activate_app_request.h b/src/components/application_manager/include/application_manager/commands/hmi/sdl_activate_app_request.h
index ce86ea2df3..0dff904955 100644
--- a/src/components/application_manager/include/application_manager/commands/hmi/sdl_activate_app_request.h
+++ b/src/components/application_manager/include/application_manager/commands/hmi/sdl_activate_app_request.h
@@ -40,14 +40,17 @@ namespace application_manager {
namespace commands {
-typedef std::pair<ApplicationSharedPtr, std::vector<ApplicationSharedPtr> >
- DevicesApps;
/**
* @brief SDLActivateAppRequest command class
**/
class SDLActivateAppRequest : public RequestFromHMI {
public:
/**
+ * @brief Applications registered over protocol v4
+ */
+ typedef std::vector<application_manager::ApplicationSharedPtr> V4ProtoApps;
+
+ /**
* @brief SDLActivateAppRequest class constructor
*
* @param message Incoming SmartObject message
@@ -58,32 +61,46 @@ class SDLActivateAppRequest : public RequestFromHMI {
/**
* @brief SDLActivateAppRequest class destructor
**/
- virtual ~SDLActivateAppRequest();
+ ~SDLActivateAppRequest() OVERRIDE;
/**
* @brief Execute command
**/
- virtual void Run();
+ void Run() OVERRIDE;
/**
* @brief onTimeOut allows to process case when timeout has appeared
* during request execution.
*/
- virtual void onTimeOut();
+ void onTimeOut() OVERRIDE;
/**
* @brief on_event allows to handle events
*
* @param event event type that current request subscribed on.
*/
- virtual void on_event(const event_engine::Event& event);
+ void on_event(const event_engine::Event& event) OVERRIDE;
private:
uint32_t app_id() const;
uint32_t hmi_app_id(const smart_objects::SmartObject& so) const;
- DevicesApps FindAllAppOnParticularDevice(
- const connection_handler::DeviceHandle handle);
+ /**
+ * @brief Retrieves all v4 protocol applications for particular device
+ * @param handle Device handle
+ * @return List of applications registered over v4 protocol
+ */
+ V4ProtoApps get_v4_proto_apps(
+ const connection_handler::DeviceHandle handle) const;
+
+ /**
+ * @brief Get v4 protocol application reported as forgrounded on device
+ * @param handle Device
+ * @return Pointer to application or empty pointer
+ */
+ ApplicationSharedPtr get_foreground_app(
+ const connection_handler::DeviceHandle handle) const;
+
DISALLOW_COPY_AND_ASSIGN(SDLActivateAppRequest);
};
diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc
index 7aa1bd550d..f525165827 100644
--- a/src/components/application_manager/src/application_manager_impl.cc
+++ b/src/components/application_manager/src/application_manager_impl.cc
@@ -835,6 +835,27 @@ void ApplicationManagerImpl::OnMessageReceived(
messages_from_hmi_.PostMessage(impl::MessageFromHmi(message));
}
+ApplicationConstSharedPtr ApplicationManagerImpl::WaitingApplicationByID(
+ const uint32_t hmi_id) const {
+ AppsWaitRegistrationSet app_list = AppsWaitingForRegistration().GetData();
+
+ AppsWaitRegistrationSet::const_iterator it_end = app_list.end();
+
+ HmiAppIdPredicate finder(hmi_id);
+ ApplicationSharedPtr result;
+ ApplicationSetConstIt it_app = std::find_if(app_list.begin(), it_end, finder);
+ if (it_app != it_end) {
+ result = *it_app;
+ }
+ return result;
+}
+
+DataAccessor<AppsWaitRegistrationSet>
+ApplicationManagerImpl::AppsWaitingForRegistration() const {
+ return DataAccessor<AppsWaitRegistrationSet>(apps_to_register_,
+ apps_to_register_list_lock_);
+}
+
bool ApplicationManagerImpl::IsAppsQueriedFrom(
const connection_handler::DeviceHandle handle) const {
sync_primitives::AutoLock lock(apps_to_register_list_lock_);
diff --git a/src/components/application_manager/src/commands/hmi/sdl_activate_app_request.cc b/src/components/application_manager/src/commands/hmi/sdl_activate_app_request.cc
index 9c4ff8c41e..30ea41e0b0 100644
--- a/src/components/application_manager/src/commands/hmi/sdl_activate_app_request.cc
+++ b/src/components/application_manager/src/commands/hmi/sdl_activate_app_request.cc
@@ -38,6 +38,46 @@ namespace application_manager {
namespace commands {
+namespace {
+struct ProtoV4AppsOnDevice : std::unary_function<ApplicationSharedPtr, bool> {
+ connection_handler::DeviceHandle handle_;
+ ProtoV4AppsOnDevice(const connection_handler::DeviceHandle handle)
+ : handle_(handle) {}
+ bool operator()(const ApplicationSharedPtr app) const {
+ return app
+ ? handle_ == app->device() &&
+ ProtocolVersion::kV4 == app->protocol_version()
+ : false;
+ }
+};
+
+struct ForegroundApp
+ : std::unary_function<SDLActivateAppRequest::V4ProtoApps::value_type,
+ bool> {
+ bool operator()(
+ const SDLActivateAppRequest::V4ProtoApps::value_type ptr) const {
+ return ptr ? ptr->is_foreground() : false;
+ }
+};
+
+struct SendLaunchApp
+ : std::unary_function<SDLActivateAppRequest::V4ProtoApps::value_type,
+ void> {
+ ApplicationConstSharedPtr app_to_launch_;
+ ApplicationManager& application_manager_;
+ SendLaunchApp(ApplicationConstSharedPtr app_to_launch, ApplicationManager& am)
+ : app_to_launch_(app_to_launch), application_manager_(am) {}
+ void operator()(
+ const SDLActivateAppRequest::V4ProtoApps::value_type ptr) const {
+ MessageHelper::SendLaunchApp((*ptr).app_id(),
+ app_to_launch_->SchemaUrl(),
+ app_to_launch_->PackageName(),
+ application_manager_);
+ return;
+ }
+};
+}
+
SDLActivateAppRequest::SDLActivateAppRequest(
const MessageSharedPtr& message, ApplicationManager& application_manager)
: RequestFromHMI(message, application_manager) {}
@@ -51,55 +91,73 @@ void SDLActivateAppRequest::Run() {
const uint32_t application_id = app_id();
- ApplicationConstSharedPtr app =
+ ApplicationConstSharedPtr app_to_activate =
application_manager_.application(application_id);
- if (!app) {
- LOG4CXX_ERROR(
+ if (!app_to_activate) {
+ LOG4CXX_WARN(
logger_,
"Can't find application within regular apps: " << application_id);
+
+ // Here is the hack - in fact SDL gets hmi_app_id in appID field and
+ // replaces it with connection_key only for normally registered apps, but
+ // for apps_to_be_registered (waiting) it keeps original value (hmi_app_id)
+ // so method does lookup for hmi_app_id
+ app_to_activate =
+ application_manager_.WaitingApplicationByID(application_id);
+
+ if (!app_to_activate) {
+ LOG4CXX_WARN(
+ logger_,
+ "Can't find application within waiting apps: " << application_id);
+ return;
+ }
+ }
+
+ LOG4CXX_DEBUG(logger_,
+ "Found application to activate. Application id is "
+ << app_to_activate->app_id());
+
+ if (app_to_activate->IsRegistered()) {
+ LOG4CXX_DEBUG(logger_, "Application is registered. Activating.");
+ application_manager_.GetPolicyHandler().OnActivateApp(application_id,
+ correlation_id());
return;
}
- DevicesApps devices_apps = FindAllAppOnParticularDevice(app->device());
- if (!devices_apps.first && devices_apps.second.empty()) {
+ connection_handler::DeviceHandle device_handle = app_to_activate->device();
+ ApplicationSharedPtr foreground_v4_app = get_foreground_app(device_handle);
+ V4ProtoApps v4_proto_apps = get_v4_proto_apps(device_handle);
+
+ if (!foreground_v4_app && v4_proto_apps.empty()) {
LOG4CXX_ERROR(logger_,
"Can't find regular foreground app with the same "
"connection id:"
- << app->device());
+ << device_handle);
SendResponse(false, correlation_id(), SDL_ActivateApp, NO_APPS_REGISTERED);
return;
}
- if (!app->IsRegistered()) {
- if (devices_apps.first) {
- MessageHelper::SendLaunchApp(devices_apps.first->app_id(),
- app->SchemaUrl(),
- app->PackageName(),
- application_manager_);
- } else {
- std::vector<ApplicationSharedPtr>::const_iterator it =
- devices_apps.second.begin();
- for (; it != devices_apps.second.end(); ++it) {
- MessageHelper::SendLaunchApp((*it)->app_id(),
- app->SchemaUrl(),
- app->PackageName(),
- application_manager_);
- }
- }
- subscribe_on_event(BasicCommunication_OnAppRegistered);
+ LOG4CXX_DEBUG(logger_,
+ "Application is not registered yet. "
+ "Sending launch request.");
+
+ if (foreground_v4_app) {
+ LOG4CXX_DEBUG(logger_, "Sending request to foreground application.");
+ MessageHelper::SendLaunchApp(foreground_v4_app->app_id(),
+ app_to_activate->SchemaUrl(),
+ app_to_activate->PackageName(),
+ application_manager_);
} else {
- if (devices_apps.first) {
- MessageHelper::SendLaunchApp(devices_apps.first->app_id(),
- app->SchemaUrl(),
- app->PackageName(),
- application_manager_);
- } else {
- const uint32_t application_id = app_id();
- application_manager_.GetPolicyHandler().OnActivateApp(application_id,
- correlation_id());
- }
+ LOG4CXX_DEBUG(logger_,
+ "No preffered (foreground) application is found. "
+ "Sending request to all v4 applications.");
+ std::for_each(v4_proto_apps.begin(),
+ v4_proto_apps.end(),
+ SendLaunchApp(app_to_activate, application_manager_));
}
+
+ subscribe_on_event(BasicCommunication_OnAppRegistered);
}
void SDLActivateAppRequest::onTimeOut() {
@@ -135,47 +193,56 @@ void SDLActivateAppRequest::on_event(const event_engine::Event& event) {
}
uint32_t SDLActivateAppRequest::app_id() const {
- if ((*message_).keyExists(strings::msg_params)) {
- if ((*message_)[strings::msg_params].keyExists(strings::app_id)) {
- return (*message_)[strings::msg_params][strings::app_id].asUInt();
- }
+ using namespace strings;
+ if (!(*message_).keyExists(msg_params)) {
+ LOG4CXX_DEBUG(logger_, msg_params << " section is absent in the message.");
+ return 0;
+ }
+ if (!(*message_)[msg_params].keyExists(strings::app_id)) {
+ LOG4CXX_DEBUG(logger_,
+ strings::app_id << " section is absent in the message.");
+ return 0;
}
- LOG4CXX_DEBUG(logger_, "app_id section is absent in the message.");
- return 0;
+ return (*message_)[msg_params][strings::app_id].asUInt();
}
uint32_t SDLActivateAppRequest::hmi_app_id(
const smart_objects::SmartObject& so) const {
- if (so.keyExists(strings::params)) {
- if (so[strings::msg_params].keyExists(strings::application)) {
- if (so[strings::msg_params][strings::application].keyExists(
- strings::app_id)) {
- return so[strings::msg_params][strings::application][strings::app_id]
- .asUInt();
- }
- }
+ using namespace strings;
+ if (!so.keyExists(params)) {
+ LOG4CXX_DEBUG(logger_, params << " section is absent in the message.");
+ return 0;
}
- LOG4CXX_DEBUG(logger_, "Can't find app_id section is absent in the message.");
- return 0;
+ if (!so[msg_params].keyExists(application)) {
+ LOG4CXX_DEBUG(logger_, application << " section is absent in the message.");
+ return 0;
+ }
+ if (so[msg_params][application].keyExists(strings::app_id)) {
+ LOG4CXX_DEBUG(logger_,
+ strings::app_id << " section is absent in the message.");
+ return 0;
+ }
+ return so[msg_params][application][strings::app_id].asUInt();
}
-DevicesApps SDLActivateAppRequest::FindAllAppOnParticularDevice(
- const connection_handler::DeviceHandle handle) {
- DevicesApps apps;
+SDLActivateAppRequest::V4ProtoApps SDLActivateAppRequest::get_v4_proto_apps(
+ const connection_handler::DeviceHandle handle) const {
const ApplicationSet app_list = application_manager_.applications().GetData();
+ V4ProtoApps v4_proto_apps;
+ std::copy_if(app_list.begin(),
+ app_list.end(),
+ std::back_inserter(v4_proto_apps),
+ ProtoV4AppsOnDevice(handle));
+ return v4_proto_apps;
+}
- ApplicationSetIt it = app_list.begin();
- ApplicationSetIt it_end = app_list.end();
-
- for (; it != it_end; ++it) {
- if (handle == (*it)->device()) {
- if ((*it)->is_foreground()) {
- apps.first = *it;
- }
- apps.second.push_back(*it);
- }
- }
- return apps;
+ApplicationSharedPtr SDLActivateAppRequest::get_foreground_app(
+ const connection_handler::DeviceHandle handle) const {
+ V4ProtoApps v4_proto_apps = get_v4_proto_apps(handle);
+ V4ProtoApps::iterator foreground_app =
+ std::find_if(v4_proto_apps.begin(), v4_proto_apps.end(), ForegroundApp());
+ return foreground_app != v4_proto_apps.end() ? *foreground_app
+ : ApplicationSharedPtr();
}
} // namespace commands
diff --git a/src/components/application_manager/test/include/application_manager/mock_application_manager.h b/src/components/application_manager/test/include/application_manager/mock_application_manager.h
index ff21958404..6ad8aeb250 100644
--- a/src/components/application_manager/test/include/application_manager/mock_application_manager.h
+++ b/src/components/application_manager/test/include/application_manager/mock_application_manager.h
@@ -233,6 +233,12 @@ class MockApplicationManager : public application_manager::ApplicationManager {
MOCK_METHOD1(UnsubscribeAppFromWayPoints, void(const uint32_t));
MOCK_CONST_METHOD0(IsAnyAppSubscribedForWayPoints, bool());
MOCK_CONST_METHOD0(GetAppsSubscribedForWayPoints, const std::set<int32_t>());
+ MOCK_CONST_METHOD1(
+ WaitingApplicationByID,
+ application_manager::ApplicationConstSharedPtr(const uint32_t));
+ MOCK_CONST_METHOD0(
+ AppsWaitingForRegistration,
+ DataAccessor<application_manager::AppsWaitRegistrationSet>());
};
} // namespace application_manager_test