Skip to content

Commit c12490f

Browse files
author
Piotr Tanski
authored
[EGD-4151] Application manager actions introduced. (#905)
* [EGD-4151] Application manifest structure defined. * [EGD-4156] Applications registry and basic action handler implemented.
1 parent e48fa0a commit c12490f

File tree

73 files changed

+1034
-558
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1034
-558
lines changed

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
* `[cellular]` Handled properly SIM READY and SIM PIN URC messages with Action mockup
1717
* `[calendar]` Rework to use database model instead of internal model in day events list.
18+
* `[appmgr]` Application manager actions introduced.
1819

1920
### Fixed
2021

module-apps/Application.cpp

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,16 @@ namespace app
6262
}
6363
}
6464

65-
Application::Application(
66-
std::string name, std::string parent, bool startBackground, uint32_t stackDepth, sys::ServicePriority priority)
65+
Application::Application(std::string name,
66+
std::string parent,
67+
StartInBackground startInBackground,
68+
uint32_t stackDepth,
69+
sys::ServicePriority priority)
6770
: Service(name, parent, stackDepth, priority), default_window(gui::name::window::main_window),
68-
windowsStack(this), windowsFactory(), startBackground{startBackground}
71+
windowsStack(this), startInBackground{startInBackground}
6972
{
7073
keyTranslator = std::make_unique<gui::KeyInputSimpleTranslation>();
7174
busChannels.push_back(sys::BusChannels::ServiceCellularNotifications);
72-
if (startBackground) {
73-
setState(State::ACTIVE_BACKGROUND);
74-
}
7575

7676
longPressTimer = std::make_unique<sys::Timer>("LongPress", this, key_timer_ms);
7777
longPressTimer->connect([&](sys::Timer &) { longPressTimerCallback(); });
@@ -223,6 +223,9 @@ namespace app
223223
else if (msgl->messageType == MessageType::EVMMinuteUpdated) {
224224
return handleMinuteUpdated(msgl);
225225
}
226+
else if (msgl->messageType == MessageType::AppAction) {
227+
return handleAction(msgl);
228+
}
226229
else if (msgl->messageType == MessageType::AppSwitch) {
227230
return handleApplicationSwitch(msgl);
228231
}
@@ -333,6 +336,21 @@ namespace app
333336
return msgHandled();
334337
}
335338

339+
sys::Message_t Application::handleAction(sys::DataMessage *msgl)
340+
{
341+
auto *msg = static_cast<AppActionRequest *>(msgl);
342+
const auto action = msg->getAction();
343+
try {
344+
const auto &actionHandler = receivers.at(action);
345+
auto &data = msg->getData();
346+
actionHandler(std::move(data));
347+
}
348+
catch (const std::out_of_range &) {
349+
LOG_ERROR("Application %s is not able to handle action #%d", GetName().c_str(), action);
350+
}
351+
return msgHandled();
352+
}
353+
336354
sys::Message_t Application::handleApplicationSwitch(sys::DataMessage *msgl)
337355
{
338356
auto *msg = static_cast<AppSwitchMessage *>(msgl);
@@ -472,12 +490,16 @@ namespace app
472490
setState(State::INITIALIZING);
473491
settings = DBServiceAPI::SettingsGet(this);
474492

475-
const bool initialised = settings.dbID == 1;
476-
app::manager::Controller::registerApplication(this, initialised, startBackground);
477-
if (!initialised) {
493+
const auto status = (settings.dbID == 1) ? StartupStatus::Success : StartupStatus::Failure;
494+
app::manager::Controller::applicationInitialised(this, status, startInBackground);
495+
if (status == StartupStatus::Failure) {
478496
setState(State::DEACTIVATED);
479497
return sys::ReturnCodes::Failure;
480498
}
499+
500+
if (startInBackground) {
501+
setState(State::ACTIVE_BACKGROUND);
502+
}
481503
return sys::ReturnCodes::Success;
482504
}
483505

@@ -507,6 +529,15 @@ namespace app
507529
return AudioServiceAPI::KeyPressed(this, step);
508530
}
509531

532+
void Application::requestAction(sys::Service *sender,
533+
const ApplicationName &applicationName,
534+
manager::actions::ActionId actionId,
535+
manager::actions::ActionParamsPtr &&data)
536+
{
537+
auto msg = std::make_shared<AppActionRequest>(actionId, std::move(data));
538+
sys::Bus::SendUnicast(msg, applicationName, sender);
539+
}
540+
510541
void Application::messageSwitchApplication(sys::Service *sender,
511542
std::string application,
512543
std::string window,
@@ -616,4 +647,9 @@ namespace app
616647
timer->sysapi.connect(item);
617648
item->attachTimer(std::move(timer));
618649
}
650+
651+
void Application::addActionReceiver(manager::actions::ActionId actionId, OnActionReceived &&callback)
652+
{
653+
receivers.insert_or_assign(actionId, std::move(callback));
654+
}
619655
} /* namespace app */

module-apps/Application.hpp

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "gui/Common.hpp" // for ShowMode
1818
#include "projdefs.h" // for pdMS_TO_TICKS
1919
#include "service-evtmgr/messages/EVMessages.hpp" // for TorchStateMe...
20+
#include "module-services/service-appmgr/ApplicationManifest.hpp"
2021
#include <list> // for list
2122
#include <map> // for allocator, map
2223
#include <memory> // for make_shared
@@ -57,7 +58,6 @@ namespace sys
5758

5859
namespace app
5960
{
60-
6161
class Application;
6262
class GuiTimer;
6363

@@ -71,6 +71,49 @@ namespace app
7171
return std::make_shared<sys::ResponseMessage>(sys::ReturnCodes::Unresolved);
7272
}
7373

74+
using ApplicationName = std::string;
75+
76+
enum class StartupStatus
77+
{
78+
Success,
79+
Failure
80+
};
81+
82+
struct StartInBackground
83+
{
84+
StartInBackground(bool _value) : value{_value}
85+
{}
86+
87+
explicit operator bool() const noexcept
88+
{
89+
return value;
90+
}
91+
92+
bool value;
93+
};
94+
95+
/// Type traits pattern used to enforce user-defined types to implement "GetManifest" function.
96+
template <class T> struct ManifestTraits;
97+
98+
template <class, class = void> struct HasManifest : std::false_type
99+
{};
100+
101+
/// Checks whether T implements "GetManifest" static method.
102+
/// Provides the member constant "value" that is equal to true if T implements "GetManifest" static method.
103+
/// Otherwise, "value" is equal to false.
104+
template <class T>
105+
struct HasManifest<T, std::void_t<decltype(&ManifestTraits<T>::GetManifest)>>
106+
: std::is_same<app::manager::ApplicationManifest, decltype(ManifestTraits<T>::GetManifest())>
107+
{};
108+
109+
/// Retrieves the manifest of T, if T implements ManifestTraits.
110+
/// Otherwise, reports an error during compile time.
111+
template <class T, std::enable_if_t<HasManifest<T>::value, int> = 0>
112+
auto ManifestOf() -> manager::ApplicationManifest
113+
{
114+
return ManifestTraits<T>::GetManifest();
115+
}
116+
74117
/// This is template for creating new applications. Main difference between Application and service is that:
75118
/// 1. Application has access to GUI and Input
76119
/// 2. Application lifetime is managed with app::manager::ApplicationManager
@@ -111,6 +154,8 @@ namespace app
111154
/// c_str() function for Application::State
112155
static const char *stateStr(State st);
113156

157+
using OnActionReceived = std::function<void(manager::actions::ActionParamsPtr &&)>;
158+
114159
private:
115160
std::string default_window;
116161
State state = State::DEACTIVATED;
@@ -122,6 +167,7 @@ namespace app
122167
sys::Message_t handleBatteryLevel(sys::DataMessage *msgl);
123168
sys::Message_t handleChargerPlugged(sys::DataMessage *msgl);
124169
sys::Message_t handleMinuteUpdated(sys::DataMessage *msgl);
170+
sys::Message_t handleAction(sys::DataMessage *msgl);
125171
sys::Message_t handleApplicationSwitch(sys::DataMessage *msgl);
126172
sys::Message_t handleSwitchWindow(sys::DataMessage *msgl);
127173
sys::Message_t handleAppClose(sys::DataMessage *msgl);
@@ -131,14 +177,15 @@ namespace app
131177
sys::Message_t handleSIMMessage(sys::DataMessage *msgl);
132178

133179
std::list<std::unique_ptr<app::GuiTimer>> gui_timers;
180+
std::unordered_map<manager::actions::ActionId, OnActionReceived> receivers;
134181

135182
public:
136183
std::unique_ptr<sys::Timer> longPressTimer;
137184
Application(std::string name,
138-
std::string parent = "",
139-
bool startBackground = false,
140-
uint32_t stackDepth = 4096,
141-
sys::ServicePriority priority = sys::ServicePriority::Idle);
185+
std::string parent = "",
186+
StartInBackground startInBackground = {false},
187+
uint32_t stackDepth = 4096,
188+
sys::ServicePriority priority = sys::ServicePriority::Idle);
142189

143190
virtual ~Application();
144191

@@ -287,6 +334,10 @@ namespace app
287334
/// @note consider moving these as private elements of ApplicationManager i.e. under names
288335
/// message::switchApplication etc.
289336
/// @{
337+
static void requestAction(sys::Service *sender,
338+
const ApplicationName &applicationName,
339+
manager::actions::ActionId actionId,
340+
manager::actions::ActionParamsPtr &&data);
290341
static void messageSwitchApplication(sys::Service *sender,
291342
std::string application,
292343
std::string window,
@@ -343,7 +394,7 @@ namespace app
343394
/// 2. simple translation of keys 1 to 1 with keyboard
344395
std::unique_ptr<gui::KeyInputSimpleTranslation> keyTranslator;
345396
/// Flag defines how application will behave after registration. It can go forground or background
346-
bool startBackground = false;
397+
StartInBackground startInBackground{false};
347398
/// Flag which defines whether application initialized suspend mode, this will influence how render message will
348399
/// sent to gui service. If suspend is true, application manager will receive information from both eink and gui
349400
/// services if last rendering mesage will be processed.
@@ -358,6 +409,24 @@ namespace app
358409
static void messageInputEventApplication(sys::Service *sender,
359410
std::string application,
360411
const gui::InputEvent &event);
412+
413+
void addActionReceiver(manager::actions::ActionId actionId, OnActionReceived &&callback);
361414
};
362415

416+
/// Parameter pack used by application launch action.
417+
class ApplicationLaunchData : public manager::actions::ActionParams
418+
{
419+
public:
420+
ApplicationLaunchData(const app::ApplicationName &appName)
421+
: manager::actions::ActionParams{"Application launch parameters"}, targetAppName{appName}
422+
{}
423+
424+
[[nodiscard]] auto getTargetApplicationName() const noexcept
425+
{
426+
return targetAppName;
427+
}
428+
429+
private:
430+
ApplicationName targetAppName;
431+
};
363432
} /* namespace app */

module-apps/ApplicationLauncher.hpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace app
99
{
10+
using ApplicationManifest = app::manager::ApplicationManifest;
1011

1112
/// used in ApplicationManager to start applications
1213
class ApplicationLauncher
@@ -16,6 +17,8 @@ namespace app
1617
std::string name;
1718
/// name of the application's owner
1819
std::string parent;
20+
/// Application's manifest
21+
ApplicationManifest manifest;
1922
/// defines whether application can be closed when it looses focus
2023
bool closeable = true;
2124
/// defines whether application should be run without gaining focus, it will remian in the BACKGROUND state
@@ -24,15 +27,23 @@ namespace app
2427
bool preventBlocking = false;
2528

2629
public:
27-
ApplicationLauncher(std::string name, bool isCloseable, bool preventBlocking = false)
28-
: name{name}, closeable{isCloseable}, preventBlocking{preventBlocking} {};
30+
ApplicationLauncher(std::string name,
31+
ApplicationManifest &&manifest,
32+
bool isCloseable,
33+
bool preventBlocking = false)
34+
: name{name}, manifest{std::move(manifest)}, closeable{isCloseable}, preventBlocking{preventBlocking} {};
2935
virtual ~ApplicationLauncher() = default;
3036

3137
[[nodiscard]] std::string getName() const noexcept
3238
{
3339
return name;
3440
}
3541

42+
[[nodiscard]] const ApplicationManifest &getManifest() const noexcept
43+
{
44+
return manifest;
45+
}
46+
3647
[[nodiscard]] bool isCloseable() const noexcept
3748
{
3849
return closeable;
@@ -60,7 +71,8 @@ namespace app
6071
template <class T> class ApplicationLauncherT : public ApplicationLauncher
6172
{
6273
public:
63-
ApplicationLauncherT(std::string name, bool isCloseable = true) : ApplicationLauncher(name, isCloseable)
74+
ApplicationLauncherT(std::string name, ApplicationManifest &&manifest, bool isCloseable = true)
75+
: ApplicationLauncher(name, std::move(manifest), isCloseable)
6476
{}
6577

6678
bool run(sys::Service *caller) override
@@ -82,6 +94,7 @@ namespace app
8294
template <class T>
8395
std::unique_ptr<ApplicationLauncherT<T>> CreateLauncher(std::string name, bool isCloseable = true)
8496
{
85-
return std::unique_ptr<ApplicationLauncherT<T>>(new ApplicationLauncherT<T>(name, isCloseable));
97+
return std::unique_ptr<ApplicationLauncherT<T>>(
98+
new ApplicationLauncherT<T>(name, ManifestOf<T>(), isCloseable));
8699
}
87100
} // namespace app

module-apps/UiCommonActions.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include "application-special-input/ApplicationSpecialInput.hpp"
1313

1414
#include "service-appmgr/Controller.hpp"
15-
#include "service-appmgr/messages/APMMessage.hpp"
15+
#include "service-appmgr/messages/Message.hpp"
1616

1717
#include <i18/i18.hpp>
1818
#include <log/log.hpp>
@@ -40,10 +40,8 @@ namespace app
4040
auto call(Application *app, const utils::PhoneNumber::View &phoneNumber) -> bool
4141
{
4242
assert(app != nullptr);
43-
auto data = std::make_unique<ExecuteCallData>(phoneNumber);
44-
data->disableAppClose = true;
45-
46-
return app::manager::Controller::switchApplication(app, name_call, window::name_enterNumber, std::move(data));
43+
auto data = std::make_unique<ExecuteCallData>(phoneNumber);
44+
return app::manager::Controller::sendAction(app, manager::actions::Call, std::move(data));
4745
}
4846

4947
auto prepareCall(Application *app, const std::string &number) -> bool
@@ -169,6 +167,6 @@ namespace app
169167
app, app::special_input, app::char_select, std::move(switchData));
170168
}
171169
return app::manager::Controller::switchBack(
172-
app, std::make_unique<app::manager::APMSwitchPrevApp>(switchData->requester, std::move(switchData)));
170+
app, std::make_unique<app::manager::SwitchBackRequest>(switchData->requester, std::move(switchData)));
173171
}
174172
} // namespace app

module-apps/application-antenna/ApplicationAntenna.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ namespace app
3434
}
3535
}
3636

37-
ApplicationAntenna::ApplicationAntenna(std::string name, std::string parent, bool startBackgound)
38-
: Application(name, parent, startBackgound, 4096 * 2)
37+
ApplicationAntenna::ApplicationAntenna(std::string name, std::string parent, StartInBackground startInBackground)
38+
: Application(name, parent, startInBackground, 4096 * 2)
3939
{
4040
busChannels.push_back(sys::BusChannels::AntennaNotifications);
4141
busChannels.push_back(sys::BusChannels::AntennaNotifications);

module-apps/application-antenna/ApplicationAntenna.hpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ namespace app
3030
};
3131
constexpr uint32_t paramsMaxSize = 9;
3232
} // namespace antenna
33+
3334
class ApplicationAntenna : public app::Application
3435
{
3536
protected:
@@ -44,7 +45,9 @@ namespace app
4445
uint32_t lastFreq = 0;
4546

4647
public:
47-
ApplicationAntenna(std::string name = name_antenna, std::string parent = "", bool startBackgound = false);
48+
ApplicationAntenna(std::string name = name_antenna,
49+
std::string parent = {},
50+
StartInBackground startInBackground = {false});
4851
virtual ~ApplicationAntenna();
4952

5053
sys::Message_t DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) override;
@@ -73,6 +76,13 @@ namespace app
7376
std::vector<app::antenna::StoreParams> highBandParams;
7477
};
7578

79+
template <> struct ManifestTraits<ApplicationAntenna>
80+
{
81+
static auto GetManifest() -> manager::ApplicationManifest
82+
{
83+
return {{manager::actions::Launch}};
84+
}
85+
};
7686
} /* namespace app */
7787

7888
#endif /* MODULE_APPS_APPLICATION_ANTENNA_APPLICATIONANTENNA_HPP_ */

0 commit comments

Comments
 (0)