M changelog.md => changelog.md +3 -0
@@ 5,6 5,9 @@
### Added
* `[settings][bluetooth]` Add "Phone name" window.
+### Changed
+
+* `[appmgr]` Application manager refactored.
### Fixed
M module-apps/Application.cpp => module-apps/Application.cpp +34 -36
@@ 16,7 16,7 @@
#include "log/debug.hpp" // for DEBUG_APPLI...
#include "log/log.hpp" // for LOG_INFO
#include "messages/AppMessage.hpp" // for AppSwitchMe...
-#include "service-appmgr/ApplicationManager.hpp" // for Application...
+#include "service-appmgr/Controller.hpp" // for Controller
#include "service-cellular/messages/CellularMessage.hpp" // for CellularNot...
#include "service-db/api/DBServiceAPI.hpp" // for DBServiceAPI
#include "service-evtmgr/messages/BatteryMessages.hpp" // for BatteryLeve...
@@ 167,16 167,15 @@ namespace app
#endif
// case to handle returning to previous application
- if (windowName == "LastWindow") {
+ if (windowName.empty()) {
window = getCurrentWindow()->getName();
auto msg =
std::make_shared<AppSwitchWindowMessage>(window, getCurrentWindow()->getName(), std::move(data), cmd);
sys::Bus::SendUnicast(msg, this->GetName(), this);
}
else {
- window = windowName.empty() ? default_window : windowName;
auto msg = std::make_shared<AppSwitchWindowMessage>(
- window, getCurrentWindow() ? getCurrentWindow()->getName() : "", std::move(data), cmd);
+ windowName, getCurrentWindow() ? getCurrentWindow()->getName() : "", std::move(data), cmd);
sys::Bus::SendUnicast(msg, this->GetName(), this);
}
}
@@ 187,7 186,7 @@ namespace app
if (prevWindow == gui::name::window::no_window) {
LOG_INFO("Back to previous application");
cleanPrevWindw();
- sapm::ApplicationManager::messageSwitchPreviousApplication(this);
+ app::manager::Controller::switchBack(this);
}
else {
LOG_INFO("Back to previous window %s", prevWindow.c_str());
@@ 237,6 236,9 @@ namespace app
else if (msgl->messageType == MessageType::AppRefresh) {
return handleAppRefresh(msgl);
}
+ else if (msgl->messageType == MessageType::AppFocusLost) {
+ return handleAppFocusLost(msgl);
+ }
else if (dynamic_cast<sevm::SIMMessage *>(msgl) != nullptr) {
return handleSIMMessage(msgl);
}
@@ 335,7 337,7 @@ namespace app
if (msg->getTargetApplicationName() == this->GetName()) {
setState(State::ACTIVE_FORGROUND);
- if (sapm::ApplicationManager::messageConfirmSwitch(this)) {
+ if (app::manager::Controller::confirmSwitch(this)) {
LOG_INFO("target Window: %s : target description: %s",
msg->getTargetWindowName().c_str(),
msg->getData() ? msg->getData()->getDescription().c_str() : "");
@@ 352,25 354,9 @@ namespace app
}
}
else if (state == State::ACTIVE_FORGROUND) {
- if (msg->getTargetApplicationName() == this->GetName()) {
- // if window name and data are null pointers this is a message informing
- // that application should go to background mode
- if ((msg->getTargetWindowName() == "") && (msg->getData() == nullptr)) {
- setState(State::ACTIVE_BACKGROUND);
- if (sapm::ApplicationManager::messageConfirmSwitch(this)) {
- handled = true;
- }
- else {
- // TODO send to itself message to close
- LOG_ERROR("Failed to communicate ");
- }
- }
- // if application is in front and receives message with defined window it should
- // change to that window.
- else {
- switchWindow(msg->getTargetWindowName(), std::move(msg->getData()));
- handled = true;
- }
+ if (msg->getTargetApplicationName() == GetName()) {
+ switchWindow(msg->getTargetWindowName(), std::move(msg->getData()));
+ handled = true;
}
else {
LOG_ERROR("Received switch message outside of activation flow");
@@ 427,7 413,7 @@ namespace app
sys::Message_t Application::handleAppClose(sys::DataMessage *msgl)
{
setState(State::DEACTIVATING);
- sapm::ApplicationManager::messageConfirmClose(this);
+ app::manager::Controller::confirmClose(this);
return msgHandled();
}
@@ 453,6 439,15 @@ namespace app
return msgHandled();
}
+ sys::Message_t Application::handleAppFocusLost(sys::DataMessage *msgl)
+ {
+ if (state == State::ACTIVE_FORGROUND) {
+ setState(State::ACTIVE_BACKGROUND);
+ app::manager::Controller::confirmSwitch(this);
+ }
+ return msgHandled();
+ }
+
sys::Message_t Application::handleSIMMessage(sys::DataMessage *msgl)
{
getCurrentWindow()->setSIM();
@@ 462,19 457,16 @@ namespace app
sys::ReturnCodes Application::InitHandler()
{
- bool initState = true;
-
setState(State::INITIALIZING);
- // uint32_t start = xTaskGetTickCount();
settings = DBServiceAPI::SettingsGet(this);
- // uint32_t stop = xTaskGetTickCount();
- // LOG_INFO("DBServiceAPI::SettingsGet %d", stop-start);
- initState = (settings.dbID == 1);
- // send response to application manager true if successful, false otherwise.
- sapm::ApplicationManager::messageRegisterApplication(this, initState, startBackground);
- sys::ReturnCodes retCode = (initState ? sys::ReturnCodes::Success : sys::ReturnCodes::Failure);
- return retCode;
+ const bool initialised = settings.dbID == 1;
+ app::manager::Controller::registerApplication(this, initialised, startBackground);
+ if (!initialised) {
+ setState(State::DEACTIVATED);
+ return sys::ReturnCodes::Failure;
+ }
+ return sys::ReturnCodes::Success;
}
sys::ReturnCodes Application::DeinitHandler()
@@ 534,6 526,12 @@ namespace app
sys::Bus::SendUnicast(msg, application, sender);
}
+ void Application::messageApplicationLostFocus(sys::Service *sender, std::string application)
+ {
+ auto msg = std::make_shared<AppLostFocusMessage>();
+ sys::Bus::SendUnicast(msg, application, sender);
+ }
+
void Application::messageInputEventApplication(sys::Service *sender,
std::string application,
const gui::InputEvent &event)
M module-apps/Application.hpp => module-apps/Application.hpp +4 -2
@@ 73,7 73,7 @@ namespace app
/// This is template for creating new applications. Main difference between Application and service is that:
/// 1. Application has access to GUI and Input
- /// 2. Application lifetime is managed with sapm::ApplicationManager
+ /// 2. Application lifetime is managed with app::manager::ApplicationManager
class Application : public sys::Service
{
public:
@@ 126,6 126,7 @@ namespace app
sys::Message_t handleAppClose(sys::DataMessage *msgl);
sys::Message_t handleAppRebuild(sys::DataMessage *msgl);
sys::Message_t handleAppRefresh(sys::DataMessage *msgl);
+ sys::Message_t handleAppFocusLost(sys::DataMessage *msgl);
sys::Message_t handleSIMMessage(sys::DataMessage *msgl);
std::list<std::unique_ptr<app::GuiTimer>> gui_timers;
@@ 152,7 153,7 @@ namespace app
void blockEvents(bool isBlocked);
/// Method sending switch command for another window. It will switch window within active application.
- /// To switch windows between applications use sapm::ApplicationManager::messageSwitchApplication
+ /// To switch windows between applications use app::manager::Controller::switchApplication
/// it will effectively trigger setActiveWindow and change on windows stack
///
/// @param windowName name of window to show, only required parameter, our windows stack uses string names as
@@ 295,6 296,7 @@ namespace app
gui::SwitchData *data = nullptr);
static void messageCloseApplication(sys::Service *sender, std::string application);
static void messageRebuildApplication(sys::Service *sender, std::string application);
+ static void messageApplicationLostFocus(sys::Service *sender, std::string application);
/// @}
protected:
M module-apps/UiCommonActions.cpp => module-apps/UiCommonActions.cpp +27 -12
@@ 9,7 9,10 @@
#include "application-messages/windows/SMSThreadViewWindow.hpp"
#include "application-phonebook/ApplicationPhonebook.hpp"
#include "application-phonebook/data/PhonebookItemData.hpp"
-#include "service-appmgr/ApplicationManager.hpp"
+#include "application-special-input/ApplicationSpecialInput.hpp"
+
+#include "service-appmgr/Controller.hpp"
+#include "service-appmgr/messages/APMMessage.hpp"
#include <i18/i18.hpp>
#include <log/log.hpp>
@@ 37,10 40,10 @@ namespace app
auto call(Application *app, const utils::PhoneNumber::View &phoneNumber) -> bool
{
assert(app != nullptr);
- auto data = std::make_unique<ExecuteCallData>(phoneNumber);
+ auto data = std::make_unique<ExecuteCallData>(phoneNumber);
+ data->disableAppClose = true;
- return sapm::ApplicationManager::messageSwitchApplication(
- app, name_call, window::name_enterNumber, std::move(data));
+ return app::manager::Controller::switchApplication(app, name_call, window::name_enterNumber, std::move(data));
}
auto prepareCall(Application *app, const std::string &number) -> bool
@@ 48,8 51,7 @@ namespace app
assert(app != nullptr);
auto data = std::make_unique<EnterNumberData>(number);
- return sapm::ApplicationManager::messageSwitchApplication(
- app, name_call, window::name_enterNumber, std::move(data));
+ return app::manager::Controller::switchApplication(app, name_call, window::name_enterNumber, std::move(data));
}
auto sms(Application *app, SmsOperation smsOperation, const utils::PhoneNumber::View &number, const UTF8 textData)
@@ 60,12 62,13 @@ namespace app
switch (smsOperation) {
case SmsOperation::New: {
auto data = std::make_unique<SMSSendRequest>(number, textData);
+ data->disableAppClose = true;
data->ignoreCurrentWindowOnStack = true;
- return sapm::ApplicationManager::messageSwitchApplication(
+ return app::manager::Controller::switchApplication(
app, name_messages, gui::name::window::new_sms, std::move(data));
}
case SmsOperation::Template: {
- return sapm::ApplicationManager::messageSwitchApplication(
+ return app::manager::Controller::switchApplication(
app, name_messages, gui::name::window::sms_templates, std::make_unique<SMSSendTemplateRequest>(number));
}
default: {
@@ 83,15 86,15 @@ namespace app
switch (contactOperation) {
case ContactOperation::Add: {
data->ignoreCurrentWindowOnStack = true;
- return sapm::ApplicationManager::messageSwitchApplication(
+ return app::manager::Controller::switchApplication(
app, name_phonebook, gui::window::name::new_contact, std::move(data));
}
case ContactOperation::Details: {
- return sapm::ApplicationManager::messageSwitchApplication(
+ return app::manager::Controller::switchApplication(
app, name_phonebook, gui::window::name::contact, std::move(data));
}
case ContactOperation::Edit: {
- return sapm::ApplicationManager::messageSwitchApplication(
+ return app::manager::Controller::switchApplication(
app,
name_phonebook,
gui::window::name::new_contact, // TODO: need to be fixed when contact edition is working
@@ 119,7 122,7 @@ namespace app
contactRec.alternativeName.c_str());
if (contactOperation == ContactOperation::Add) {
- return sapm::ApplicationManager::messageSwitchApplication(
+ return app::manager::Controller::switchApplication(
app,
name_phonebook,
gui::window::name::new_contact,
@@ 156,4 159,16 @@ namespace app
return false;
}
+ auto specialInput(Application *app, std::unique_ptr<gui::SwitchSpecialChar> &&switchData) -> bool
+ {
+ assert(app != nullptr);
+
+ switchData->disableAppClose = true;
+ if (gui::SwitchSpecialChar::Type::Request == switchData->type) {
+ return app::manager::Controller::switchApplication(
+ app, app::special_input, app::char_select, std::move(switchData));
+ }
+ return app::manager::Controller::switchBack(
+ app, std::make_unique<app::manager::APMSwitchPrevApp>(switchData->requester, std::move(switchData)));
+ }
} // namespace app
M module-apps/UiCommonActions.hpp => module-apps/UiCommonActions.hpp +6 -0
@@ 102,4 102,10 @@ namespace app
///
/// @return true if succeed
auto contact(Application *app, ContactOperation contactOperation, uint32_t contactId) -> bool;
+
+ /// @brief requests display special input window.
+ /// @param app Requesting application
+ /// @param switchData Application switch data.
+ /// @return true if succeed.
+ auto specialInput(Application *app, std::unique_ptr<gui::SwitchSpecialChar> &&switchData) -> bool;
} // namespace app
M module-apps/application-calendar/windows/AllEventsWindow.cpp => module-apps/application-calendar/windows/AllEventsWindow.cpp +2 -2
@@ 8,7 8,7 @@
#include <gui/widgets/BottomBar.hpp>
#include <gui/widgets/TopBar.hpp>
#include <gui/widgets/Window.hpp>
-#include <service-appmgr/ApplicationManager.hpp>
+#include <service-appmgr/Controller.hpp>
#include <module-services/service-db/messages/QueryMessage.hpp>
#include <module-db/queries/calendar/QueryEventsGetAllLimited.hpp>
@@ 66,7 66,7 @@ namespace gui
if (inputEvent.keyCode == gui::KeyCode::KEY_RF &&
inputEvent.state == gui::InputEvent::State::keyReleasedShort) {
LOG_DEBUG("Switch to desktop");
- sapm::ApplicationManager::messageSwitchPreviousApplication(application);
+ app::manager::Controller::switchBack(application);
}
if (AppWindow::onInput(inputEvent)) {
M module-apps/application-calendar/windows/EventReminderWindow.cpp => module-apps/application-calendar/windows/EventReminderWindow.cpp +2 -3
@@ 6,7 6,7 @@
#include "module-apps/application-calendar/data/CalendarData.hpp"
#include <gui/widgets/Window.hpp>
#include <time/time_conversion.hpp>
-#include "service-appmgr/ApplicationManager.hpp"
+#include "service-appmgr/Controller.hpp"
namespace gui
{
@@ 156,8 156,7 @@ namespace gui
LOG_DEBUG("Switch to previous window");
destroyTimer();
- sapm::ApplicationManager::messageSwitchApplication(
- application, "ApplicationDesktop", gui::name::window::main_window, nullptr);
+ app::manager::Controller::switchApplication(application, "ApplicationDesktop", gui::name::window::main_window);
}
} /* namespace gui */
M module-apps/application-call/ApplicationCall.cpp => module-apps/application-call/ApplicationCall.cpp +2 -2
@@ 22,7 22,7 @@
#include <service-cellular/ServiceCellular.hpp>
#include <service-cellular/api/CellularServiceAPI.hpp>
#include <service-audio/api/AudioServiceAPI.hpp>
-#include <service-appmgr/ApplicationManager.hpp>
+#include <service-appmgr/Controller.hpp>
#include <time/time_conversion.hpp>
#include <ticks.hpp>
@@ 45,7 45,7 @@ namespace app
app->switchWindow(window::name_call, std::move(data));
}
else {
- sapm::ApplicationManager::messageSwitchApplication(app, name_call, window::name_call, std::move(data));
+ app::manager::Controller::switchApplication(app, name_call, window::name_call, std::move(data));
}
}
M module-apps/application-call/windows/CallWindow.cpp => module-apps/application-call/windows/CallWindow.cpp +2 -2
@@ 8,7 8,7 @@
#include "InputEvent.hpp"
#include "application-call/widgets/Icons.hpp"
#include "log/log.hpp"
-#include "service-appmgr/ApplicationManager.hpp"
+#include "service-appmgr/Controller.hpp"
#include "application-call/ApplicationCall.hpp"
#include "application-call/data/CallSwitchData.hpp"
@@ 421,7 421,7 @@ namespace gui
timerCallback = [this](Item &, Timer &timer) {
setState(State::IDLE);
detachTimer(timer);
- sapm::ApplicationManager::messageSwitchPreviousApplication(application);
+ app::manager::Controller::switchBack(application);
return true;
};
application->connect(std::move(timer), this);
M module-apps/application-call/windows/EnterNumberWindow.cpp => module-apps/application-call/windows/EnterNumberWindow.cpp +3 -3
@@ 11,7 11,7 @@
#include <country.hpp>
#include <i18/i18.hpp>
#include <InputMode.hpp>
-#include <service-appmgr/ApplicationManager.hpp>
+#include <service-appmgr/Controller.hpp>
#include <service-cellular/api/CellularServiceAPI.hpp>
#include <UiCommonActions.hpp>
@@ 108,7 108,7 @@ namespace gui
// if there isn't any char in phone number field return to previous application
if (enteredNumber.empty()) {
formatter->Clear();
- sapm::ApplicationManager::messageSwitchPreviousApplication(application);
+ app::manager::Controller::switchBack(application);
}
// if there is the last char just clear input
else if (enteredNumber.size() == 1) {
@@ 134,7 134,7 @@ namespace gui
if (inputEvent.keyCode == KeyCode::KEY_RF) {
// if there isn't any char in phone number field return to previous application
if (enteredNumber.empty()) {
- sapm::ApplicationManager::messageSwitchPreviousApplication(application);
+ app::manager::Controller::switchBack(application);
return true;
}
M module-apps/application-desktop/ApplicationDesktop.cpp => module-apps/application-desktop/ApplicationDesktop.cpp +3 -3
@@ 17,7 17,7 @@
#include <service-db/api/DBServiceAPI.hpp>
#include <application-settings-new/ApplicationSettings.hpp>
#include <application-settings/ApplicationSettings.hpp>
-#include <service-appmgr/ApplicationManager.hpp>
+#include <service-appmgr/Controller.hpp>
#include <service-cellular/ServiceCellular.hpp>
#include <application-calllog/ApplicationCallLog.hpp>
#include <messages/QueryMessage.hpp>
@@ 146,7 146,7 @@ namespace app
assert(msg);
if (msg->request == cellular::State::ST::URCReady) {
if (need_sim_select && !lockHandler.lock.isLocked()) {
- sapm::ApplicationManager::messageSwitchApplication(this, app::name_settings, app::sim_select, nullptr);
+ app::manager::Controller::switchApplication(this, app::name_settings, app::sim_select, nullptr);
return true;
}
else if (need_sim_select == false) {
@@ 164,7 164,7 @@ namespace app
bool ApplicationDesktop::showCalls()
{
LOG_DEBUG("show calls!");
- return sapm::ApplicationManager::messageSwitchApplication(
+ return app::manager::Controller::switchApplication(
this, app::CallLogAppStr, gui::name::window::main_window, nullptr);
}
M module-apps/application-desktop/windows/DesktopMainWindow.cpp => module-apps/application-desktop/windows/DesktopMainWindow.cpp +3 -3
@@ 12,7 12,7 @@
#include "application-desktop/data/LockPhoneData.hpp"
#include "application-messages/ApplicationMessages.hpp"
#include "gui/widgets/Image.hpp"
-#include "service-appmgr/ApplicationManager.hpp"
+#include "service-appmgr/Controller.hpp"
#include "service-time/ServiceTime.hpp"
#include "service-time/messages/TimeMessage.hpp"
#include <UiCommonActions.hpp>
@@ 113,7 113,7 @@ namespace gui
LOG_ERROR("Couldn't fit in all notifications");
}
if (app->need_sim_select && Store::GSM::get()->sim == Store::GSM::SIM::SIM_UNKNOWN) {
- sapm::ApplicationManager::messageSwitchApplication(
+ app::manager::Controller::switchApplication(
this->application, app::name_settings, app::sim_select, nullptr);
}
@@ 373,7 373,7 @@ namespace gui
utils::localize.get("app_desktop_unread_messages"),
std::to_string(app->notifications.notSeen.SMS),
[this]() -> bool {
- return sapm::ApplicationManager::messageSwitchApplication(
+ return app::manager::Controller::switchApplication(
application, app::name_messages, gui::name::window::main_window, nullptr);
},
[app]() -> bool { return app->clearMessagesNotification(); });
M module-apps/application-desktop/windows/LockedInfoWindow.cpp => module-apps/application-desktop/windows/LockedInfoWindow.cpp +3 -3
@@ 3,7 3,7 @@
#include "LockedInfoWindow.hpp"
-#include "service-appmgr/ApplicationManager.hpp"
+#include "service-appmgr/Controller.hpp"
#include "gui/widgets/BottomBar.hpp"
#include "gui/widgets/TopBar.hpp"
#include "RichTextParser.hpp"
@@ 44,8 44,8 @@ bool LockedInfoWindow::onInput(const InputEvent &inputEvent)
{
if (inputEvent.isShortPress()) {
if (inputEvent.keyCode == KeyCode::KEY_LF && bottomBar->isActive(BottomBar::Side::LEFT)) {
- sapm::ApplicationManager::messageSwitchApplication(
- application, app::name_phonebook, gui::window::name::ice_contacts, nullptr);
+ app::manager::Controller::switchApplication(
+ application, app::name_phonebook, gui::window::name::ice_contacts);
return true;
}
else if (inputEvent.keyCode == KeyCode::KEY_RF && bottomBar->isActive(BottomBar::Side::RIGHT)) {
M => +11 -11
@@ 6,7 6,7 @@
#include "InputEvent.hpp"
#include "Item.hpp"
#include "Navigation.hpp"
#include "service-appmgr/ApplicationManager.hpp"
#include "service-appmgr/Controller.hpp"
#include <tools/Common.hpp>
#include <Style.hpp>
@@ 129,7 129,7 @@ namespace gui
new gui::Tile("menu_calendar_W_G",
"app_desktop_menu_calendar",
[=](gui::Item &item) {
sapm::ApplicationManager::messageSwitchApplication(
app::manager::Controller::switchApplication(
application, "ApplicationCalendar", gui::name::window::main_window, nullptr);
return true;
}),
@@ 138,7 138,7 @@ namespace gui
"app_desktop_menu_phone",
[=](gui::Item &item) {
LOG_INFO("Call Log");
sapm::ApplicationManager::messageSwitchApplication(
app::manager::Controller::switchApplication(
application, "ApplicationCallLog", gui::name::window::main_window, nullptr);
return true;
},
@@ 147,7 147,7 @@ namespace gui
"app_desktop_menu_contacts",
[=](gui::Item &item) {
LOG_INFO("Phonebook");
sapm::ApplicationManager::messageSwitchApplication(
app::manager::Controller::switchApplication(
application, "ApplicationPhonebook", gui::name::window::main_window, nullptr);
return true;
}),
@@ 156,7 156,7 @@ namespace gui
"app_desktop_menu_messages",
[=](gui::Item &item) {
LOG_INFO("Messages");
sapm::ApplicationManager::messageSwitchApplication(
app::manager::Controller::switchApplication(
application, "ApplicationMessages", gui::name::window::main_window, nullptr);
return true;
},
@@ 165,7 165,7 @@ namespace gui
"app_desktop_menu_music",
[=](gui::Item &item) {
LOG_INFO("Music Player");
sapm::ApplicationManager::messageSwitchApplication(
app::manager::Controller::switchApplication(
application, "ApplicationMusicPlayer", gui::name::window::main_window, nullptr);
return true;
}},
@@ 173,7 173,7 @@ namespace gui
"app_desktop_menu_meditation",
[=](gui::Item &item) {
LOG_INFO("Meditation");
sapm::ApplicationManager::messageSwitchApplication(
app::manager::Controller::switchApplication(
application, "ApplicationMeditation", gui::name::window::main_window, nullptr);
return true;
}},
@@ 181,7 181,7 @@ namespace gui
"app_desktop_menu_settings_new",
[=](gui::Item &item) {
LOG_INFO("page 1 settings");
sapm::ApplicationManager::messageSwitchApplication(
app::manager::Controller::switchApplication(
application, APP_SETTINGS_NEW, gui::name::window::main_window, nullptr);
return true;
}},
@@ 194,21 194,21 @@ namespace gui
new gui::Tile{"menu_tools_notes_W_G",
"app_desktop_tools_notes",
[=](gui::Item &item) {
sapm::ApplicationManager::messageSwitchApplication(
app::manager::Controller::switchApplication(
application, "ApplicationNotes", gui::name::window::main_window, nullptr);
return true;
}},
new gui::Tile{"menu_tools_calculator_W_G",
"app_desktop_tools_calculator",
[=](gui::Item &item) {
sapm::ApplicationManager::messageSwitchApplication(
app::manager::Controller::switchApplication(
application, "ApplicationCalculator", gui::name::window::main_window, nullptr);
return true;
}},
new gui::Tile{"menu_tools_recorder_W_G",
"app_desktop_tools_antenna",
[=](gui::Item &item) {
sapm::ApplicationManager::messageSwitchApplication(
app::manager::Controller::switchApplication(
application, "ApplicationAntenna", gui::name::window::main_window, nullptr);
return true;
}},
M module-apps/application-desktop/windows/PinLockWindow.cpp => module-apps/application-desktop/windows/PinLockWindow.cpp +2 -2
@@ 3,7 3,7 @@
// application manager
#include "InputEvent.hpp"
-#include "service-appmgr/ApplicationManager.hpp"
+#include "service-appmgr/Controller.hpp"
// module-gui
#include "gui/widgets/BottomBar.hpp"
@@ 95,7 95,7 @@ namespace gui
}
// accept only LF, enter, RF, #, and numeric values;
if (inputEvent.keyCode == KeyCode::KEY_LF && bottomBar->isActive(BottomBar::Side::LEFT)) {
- sapm::ApplicationManager::messageSwitchApplication(
+ app::manager::Controller::switchApplication(
application, app::name_phonebook, gui::window::name::ice_contacts, nullptr);
return true;
}
M module-apps/application-messages/ApplicationMessages.cpp => module-apps/application-messages/ApplicationMessages.cpp +1 -1
@@ 88,7 88,7 @@ namespace app
case MessageType::DBQuery:
if (auto queryResponse = dynamic_cast<db::QueryResponse *>(resp)) {
auto result = queryResponse->getResult();
- if (result->hasListener()) {
+ if (result && result->hasListener()) {
if (result->handle()) {
refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST);
}
M module-apps/application-messages/windows/NewMessage.cpp => module-apps/application-messages/windows/NewMessage.cpp +2 -2
@@ 9,7 9,7 @@
#include <application-phonebook/ApplicationPhonebook.hpp>
#include <application-phonebook/windows/PhonebookSearchResults.hpp>
-#include <service-appmgr/ApplicationManager.hpp>
+#include <service-appmgr/Controller.hpp>
#include <service-db/api/DBServiceAPI.hpp>
#include <i18/i18.hpp>
#include <BoxLayout.hpp>
@@ 80,7 80,7 @@ namespace gui
if (recipient->getText().empty()) {
auto data = std::make_unique<PhonebookSearchReuqest>();
data->disableAppClose = true;
- return sapm::ApplicationManager::messageSwitchApplication(
+ return app::manager::Controller::switchApplication(
application, app::name_phonebook, name::window::main_window, std::move(data));
}
return true;
M module-apps/application-messages/windows/SMSTemplatesWindow.cpp => module-apps/application-messages/windows/SMSTemplatesWindow.cpp +4 -4
@@ 7,7 7,7 @@
#include "application-messages/widgets/SMSTemplateItem.hpp"
#include "application-messages/data/MessagesStyle.hpp"
-#include <service-appmgr/ApplicationManager.hpp>
+#include <service-appmgr/Controller.hpp>
#include <service-db/messages/DBSMSTemplateMessage.hpp>
#include <i18/i18.hpp>
#include <Style.hpp>
@@ 82,9 82,9 @@ namespace gui
app->templatesCallback = [=](std::shared_ptr<SMSTemplateRecord> templ) {
LOG_DEBUG("SMS template id = %" PRIu32 "sent to %s", templ->ID, phoneNumber.getFormatted().c_str());
app->sendSms(phoneNumber, templ->text);
- sapm::ApplicationManager::messageSwitchPreviousApplication(
- app,
- std::make_unique<sapm::APMSwitchPrevApp>(application->GetName(), std::make_unique<SMSTemplateSent>()));
+ app::manager::Controller::switchBack(app,
+ std::make_unique<app::manager::APMSwitchPrevApp>(
+ application->GetName(), std::make_unique<SMSTemplateSent>()));
return true;
};
}
M module-apps/application-phonebook/ApplicationPhonebook.cpp => module-apps/application-phonebook/ApplicationPhonebook.cpp +3 -3
@@ 15,7 15,7 @@
#include "windows/PhonebookSearch.hpp"
#include "windows/PhonebookSearchResults.hpp"
#include "windows/PhonebookIceContacts.hpp"
-#include <service-appmgr/ApplicationManager.hpp>
+#include <service-appmgr/Controller.hpp>
namespace app
{
@@ 161,8 161,8 @@ namespace app
std::unique_ptr<PhonebookSearchReuqest> data = std::make_unique<PhonebookSearchReuqest>();
data->result = item->contact;
data->setDescription("PhonebookSearchRequest");
- return sapm::ApplicationManager::messageSwitchPreviousApplication(
- this, std::make_unique<sapm::APMSwitchPrevApp>(GetName(), std::move(data)));
+ return app::manager::Controller::switchBack(
+ this, std::make_unique<app::manager::APMSwitchPrevApp>(GetName(), std::move(data)));
};
}
LOG_DEBUG("Switching to search results window.");
M module-apps/application-phonebook/windows/PhonebookMainWindow.cpp => module-apps/application-phonebook/windows/PhonebookMainWindow.cpp +4 -3
@@ 9,7 9,7 @@
#include <messages/QueryMessage.hpp>
#include <queries/phonebook/QueryContactGet.hpp>
-#include <service-appmgr/ApplicationManager.hpp>
+#include <service-appmgr/Controller.hpp>
#include <module-services/service-db/messages/DBNotificationMessage.hpp>
namespace gui
@@ 106,8 106,9 @@ namespace gui
std::unique_ptr<PhonebookSearchReuqest> data = std::make_unique<PhonebookSearchReuqest>();
data->result = item->contact;
data->setDescription("PhonebookSearchRequest");
- return sapm::ApplicationManager::messageSwitchPreviousApplication(
- application, std::make_unique<sapm::APMSwitchPrevApp>(application->GetName(), std::move(data)));
+ return app::manager::Controller::switchBack(
+ application,
+ std::make_unique<app::manager::APMSwitchPrevApp>(application->GetName(), std::move(data)));
};
leftArrowImage->setVisible(false);
M module-apps/application-settings-new/windows/SettingsMainWindow.cpp => module-apps/application-settings-new/windows/SettingsMainWindow.cpp +2 -2
@@ 6,7 6,7 @@
#include <i18/i18.hpp>
#include <log/log.hpp>
-#include <service-appmgr/ApplicationManager.hpp>
+#include <service-appmgr/Controller.hpp>
std::list<gui::Option> mainWindowOptionsNew(app::Application *app)
{
@@ 32,7 32,7 @@ std::list<gui::Option> mainWindowOptionsNew(app::Application *app)
return false;
}
LOG_INFO("switching to %s page", window.c_str());
- sapm::ApplicationManager::messageSwitchApplication(
+ app::manager::Controller::switchApplication(
app, "ApplicationSettings", gui::name::window::main_window, nullptr);
app->switchWindow(window, nullptr);
return true;
M module-apps/application-settings/windows/LanguageWindow.cpp => module-apps/application-settings/windows/LanguageWindow.cpp +5 -5
@@ 4,7 4,7 @@
#include <memory>
#include <functional>
-#include "service-appmgr/ApplicationManager.hpp"
+#include "service-appmgr/Controller.hpp"
#include "../ApplicationSettings.hpp"
@@ 53,27 53,27 @@ namespace gui
// add option connectivity option
options.push_back(addOptionLabel(utils::localize.get("app_settings_language_english"), [=](gui::Item &item) {
LOG_INFO("selected language: english");
- sapm::ApplicationManager::messageChangeLanguage(application, utils::Lang::En);
+ app::manager::Controller::changeLanguage(application, utils::Lang::En);
return true;
}));
// add option date and time option
options.push_back(addOptionLabel(utils::localize.get("app_settings_language_polish"), [=](gui::Item &) {
LOG_INFO("selected language: polish");
- sapm::ApplicationManager::messageChangeLanguage(application, utils::Lang::Pl);
+ app::manager::Controller::changeLanguage(application, utils::Lang::Pl);
return true;
}));
// add option display option
options.push_back(addOptionLabel(utils::localize.get("app_settings_language_german"), [=](gui::Item &) {
LOG_INFO("selected language: german");
- sapm::ApplicationManager::messageChangeLanguage(application, utils::Lang::De);
+ app::manager::Controller::changeLanguage(application, utils::Lang::De);
return true;
}));
options.push_back(addOptionLabel(utils::localize.get("app_settings_language_spanish"), [=](gui::Item &) {
LOG_INFO("selected language: spanish");
- sapm::ApplicationManager::messageChangeLanguage(application, utils::Lang::Sp);
+ app::manager::Controller::changeLanguage(application, utils::Lang::Sp);
return true;
}));
M module-apps/application-special-input/widgets/SpecialInputTableWidget.cpp => module-apps/application-special-input/widgets/SpecialInputTableWidget.cpp +5 -2
@@ 7,10 7,13 @@
#include "application-special-input/data/SpecialCharactersTableStyle.hpp"
#include <cassert>
#include <module-apps/application-special-input/ApplicationSpecialInput.hpp>
-#include <module-services/service-appmgr/ApplicationManager.hpp>
+#include <module-services/service-appmgr/Controller.hpp>
#include "Style.hpp"
#include "messages/AppMessage.hpp"
+
+#include "UiCommonActions.hpp"
+
namespace gui
{
@@ 78,7 81,7 @@ namespace gui
it->activatedCallback = [=](Item &it) {
setFocusItem(nullptr);
LOG_INFO("handled special char for %s", application->getCurrentWindow()->getName().c_str());
- sapm::ApplicationManager::messageSwitchSpecialInput(
+ app::specialInput(
application,
std::make_unique<gui::SwitchSpecialChar>(gui::SwitchSpecialChar::Type::Response, app->requester, str));
return true;
M module-apps/messages/AppMessage.hpp => module-apps/messages/AppMessage.hpp +6 -0
@@ 163,5 163,11 @@ namespace app
virtual ~AppRebuildMessage(){};
};
+ class AppLostFocusMessage : public AppMessage
+ {
+ public:
+ AppLostFocusMessage() : AppMessage{MessageType::AppFocusLost}
+ {}
+ };
}; // namespace app
#endif /* MODULE_APPS_MESSAGES_APPMESSAGE_HPP_ */
M module-apps/windows/AppWindow.cpp => module-apps/windows/AppWindow.cpp +4 -3
@@ 4,10 4,11 @@
#include "AppWindow.hpp"
#include "Application.hpp"
#include "InputEvent.hpp"
+#include "UiCommonActions.hpp"
#include <Style.hpp>
#include <application-desktop/ApplicationDesktop.hpp>
#include <i18/i18.hpp>
-#include <service-appmgr/ApplicationManager.hpp>
+#include <service-appmgr/Controller.hpp>
#include <service-audio/api/AudioServiceAPI.hpp>
using namespace style::header;
@@ 131,7 132,7 @@ namespace gui
if (inputEvent.state == InputEvent::State::keyReleasedLong && inputEvent.keyCode == gui::KeyCode::KEY_RF) {
LOG_INFO("exit to main menu");
- sapm::ApplicationManager::messageSwitchApplication(
+ app::manager::Controller::switchApplication(
application, app::name_desktop, gui::name::window::main_window, nullptr);
}
// process only if key is released
@@ 217,7 218,7 @@ namespace gui
bool AppWindow::selectSpecialCharacter()
{
- return sapm::ApplicationManager::messageSwitchSpecialInput(
+ return app::specialInput(
application,
std::make_unique<gui::SwitchSpecialChar>(gui::SwitchSpecialChar::Type::Request, application->GetName()));
}
M module-apps/windows/NoEvents.cpp => module-apps/windows/NoEvents.cpp +2 -6
@@ 5,12 5,8 @@
#include "Dialog.hpp"
#include "DialogMetadataMessage.hpp"
#include "log/log.hpp"
-#include <service-appmgr/ApplicationManager.hpp>
-#include <i18/i18.hpp>
-#include <module-services/service-db/messages/QueryMessage.hpp>
-#include <module-db/Interface/EventsRecord.hpp>
-#include <module-apps/application-calendar/ApplicationCalendar.hpp>
-#include <module-db/queries/calendar/QueryEventsGetFiltered.hpp>
+
+#include <service-appmgr/Controller.hpp>
using namespace gui;
M module-gui/README.md => module-gui/README.md +2 -2
@@ 20,11 20,11 @@ This article includes details on how MuditaOS widgets are rendered and how the G
### How does it work on the application side
-Please see `app::Application`, `sapm::ApplicationManager` for detailed information on how messages are handled between both. This is just general documentation.
+Please see `app::Application`, `app::manager::ApplicationManager` for detailed information on how messages are handled between both. This is just general documentation.

-These actions are done on a chained bus request between: `app::Application`, `sapm::ApplicationManager` and `sapm::EventWorker`
+These actions are done on a chained bus request between: `app::Application`, `app::manager::ApplicationManager` and `sapm::EventWorker`
All of these are asynchronous and there is little state machine maintenance.
M module-services/service-appmgr/ApplicationManager.cpp => module-services/service-appmgr/ApplicationManager.cpp +447 -683
@@ 1,409 1,244 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include <memory>
-
-#include "SystemManager/SystemManager.hpp"
#include "service-appmgr/ApplicationManager.hpp"
-#include "service-evtmgr/EventManager.hpp"
-#include "messages/APMMessage.hpp"
-#include "AppMessage.hpp"
-#include "application-call/data/CallSwitchData.hpp"
-
-#include "service-db/api/DBServiceAPI.hpp"
-#include "service-cellular/ServiceCellular.hpp"
-#include "service-cellular/api/CellularServiceAPI.hpp"
+#include "service-appmgr/Controller.hpp"
-#include <memory>
#include <utility>
+#include <module-apps/application-desktop/data/LockPhoneData.hpp>
-// services
-#include "service-eink/ServiceEink.hpp"
-#include "service-gui/ServiceGUI.hpp"
-
-#include "Service/Timer.hpp"
#include "application-call/ApplicationCall.hpp"
-#include "application-desktop/ApplicationDesktop.hpp"
#include "application-special-input/ApplicationSpecialInput.hpp"
-/// Auto phone lock disabled for now till the times when it's debugged
-/// #define AUTO_PHONE_LOCK_ENABLED
+#include "Service/Message.hpp"
+#include "AppMessage.hpp"
+
+#include "Service/Timer.hpp"
+#include "service-db/api/DBServiceAPI.hpp"
+#include "service-evtmgr/EventManager.hpp"
+#include "service-eink/ServiceEink.hpp"
+#include "service-gui/ServiceGUI.hpp"
-// module-utils
#include "log/log.hpp"
-#include "i18/i18.hpp"
-#include <cassert>
-namespace sapm
-{
+// Auto phone lock disabled for now till the times when it's debugged
+// #define AUTO_PHONE_LOCK_ENABLED
- ApplicationDescription::ApplicationDescription(std::unique_ptr<app::ApplicationLauncher> launcher)
- : switchData{nullptr}
+namespace app::manager
+{
+ namespace
{
- this->launcher = std::move(launcher);
- }
+ constexpr char GUIServiceName[] = "ServiceGUI";
+ constexpr char EInkServiceName[] = "ServiceEink";
+ constexpr auto default_application_locktime_ms = 30000;
- VirtualAppManager::VirtualAppManager(std::vector<std::unique_ptr<app::ApplicationLauncher>> &launchers)
- {
- for (uint32_t i = 0; i < launchers.size(); ++i) {
- applications.push_back(new ApplicationDescription(std::move(launchers[i])));
+ utils::Lang toUtilsLanguage(SettingsLanguage language)
+ {
+ switch (language) {
+ case SettingsLanguage::ENGLISH:
+ return utils::Lang::En;
+ case SettingsLanguage::POLISH:
+ return utils::Lang::Pl;
+ case SettingsLanguage::GERMAN:
+ return utils::Lang::De;
+ case SettingsLanguage::SPANISH:
+ return utils::Lang::Sp;
+ default:
+ return utils::Lang::En;
+ }
}
- }
- VirtualAppManager::~VirtualAppManager()
- {
- for (auto it = applications.begin(); it != applications.end(); it++) {
- delete *it;
+ SettingsLanguage toSettingsLanguage(utils::Lang language)
+ {
+ switch (language) {
+ case utils::Lang::En:
+ return SettingsLanguage::ENGLISH;
+ case utils::Lang::Pl:
+ return SettingsLanguage::POLISH;
+ case utils::Lang::De:
+ return SettingsLanguage::GERMAN;
+ case utils::Lang::Sp:
+ return SettingsLanguage::SPANISH;
+ default:
+ return SettingsLanguage::ENGLISH;
+ }
}
- }
+ } // namespace
+
+ ApplicationHandle::ApplicationHandle(std::unique_ptr<app::ApplicationLauncher> &&_launcher)
+ : launcher{std::move(_launcher)}
+ {}
- const char *VirtualAppManager::stateStr(State st)
+ auto ApplicationHandle::name() const -> Name
{
- switch (st) {
- case State::IDLE:
- return "IDLE";
- case State::CLOSING_PREV_APP:
- return "CLOSING_PREV_APP";
- case State::WAITING_CLOSE_CONFIRMATION:
- return "WAITING_CLOSE_CONFIRMATION";
- case State::STARTING_NEW_APP:
- return "STARTING_NEW_APP";
- case State::WAITING_NEW_APP_REGISTRATION:
- return "WAITING_NEW_APP_REGISTRATION";
- case State::WAITING_LOST_FOCUS_CONFIRMATION:
- return "WAITING_LOST_FOCUS_CONFIRMATION";
- case State::WAITING_GET_FOCUS_CONFIRMATION:
- return "WAITING_GET_FOCUS_CONFIRMATION";
- }
- // there was enum added - fix it adding it to case
- return "FIX_ME";
+ return launcher ? launcher->getName() : InvalidAppName.data();
}
- ApplicationDescription *VirtualAppManager::appFront()
+ auto ApplicationHandle::state() const noexcept -> State
{
- return applications.front();
+ return launcher && launcher->handle ? launcher->handle->getState() : State::NONE;
}
- ApplicationDescription *VirtualAppManager::appGet(const std::string &name)
+ void ApplicationHandle::setState(State state) noexcept
{
- auto el = std::find_if(applications.begin(), applications.end(), [=](auto a) {
- if (a->name() == name)
- return true;
- else
- return false;
- });
- if (el == applications.end())
- return nullptr;
- else {
- return *el;
+ if (launcher && launcher->handle) {
+ launcher->handle->setState(state);
}
}
- /// set application as first on the applications vector
- bool VirtualAppManager::appMoveFront(ApplicationDescription *app)
+ auto ApplicationHandle::preventsBlocking() const noexcept -> bool
{
- if (!app) {
- return false;
- }
- auto el = std::find_if(applications.begin(), applications.end(), [=](auto a) { return a == app; });
- if (el != applications.end()) {
- applications.push_front(std::move(*el));
- applications.erase(el);
- return true;
- }
- return false;
+ return launcher ? launcher->isBlocking() : false;
}
- /// get previous visible app - one on FOREGROUND
- ApplicationDescription *VirtualAppManager::appPrev()
+ auto ApplicationHandle::closeable() const noexcept -> bool
{
- static bool init = true;
- if (init) {
- init = false;
- return nullptr;
- }
- if (applications.size() < 2) {
- return nullptr;
- }
- return *std::next(applications.begin());
+ return launcher ? launcher->isCloseable() : false;
}
- void VirtualAppManager::setState(State st)
+ auto ApplicationHandle::started() const noexcept -> bool
{
- LOG_DEBUG("app: [%s] prev: [%s], state: (%s) -> (%s)",
- appFront()->name().c_str(),
- appPrev() ? appPrev()->name().c_str() : "",
- stateStr(state),
- stateStr(st));
- state = st;
+ const auto appState = state();
+ return appState == State::ACTIVE_FORGROUND || appState == State::ACTIVE_BACKGROUND ||
+ appState == State::ACTIVATING;
}
- std::list<ApplicationDescription *> &VirtualAppManager::getApps()
+ void ApplicationHandle::run(sys::Service *caller)
{
- return applications;
+ if (launcher) {
+ launcher->run(caller);
+ }
}
- void VirtualAppManager::debug_log_app_list()
+ void ApplicationHandle::runInBackground(sys::Service *caller)
{
- std::string apps = "\n";
- for (auto &el : getApps()) {
- apps += "-> " + el->name() + " " + app::Application::stateStr(el->getState()) + "\n";
+ if (launcher) {
+ launcher->runBackground(caller);
}
-
-#if DEBUG_APPLICATION_MANAGEMENT == 1
- LOG_DEBUG(apps.c_str());
-#endif
}
- ApplicationManager::ApplicationManager(const std::string &name,
- sys::SystemManager *sysmgr,
- std::vector<std::unique_ptr<app::ApplicationLauncher>> &launchers)
- : Service(name), VirtualAppManager(launchers), systemManager{sysmgr}
+ ApplicationManagerBase::ApplicationManagerBase(std::vector<std::unique_ptr<app::ApplicationLauncher>> &&launchers)
{
- blockingTimer = std::make_unique<sys::Timer>(
- "BlockTimer", this, std::numeric_limits<sys::ms>().max(), sys::Timer::Type::SingleShot);
- blockingTimer->connect([&](sys::Timer &) { phoneLockCB(); });
+ std::vector<std::unique_ptr<app::ApplicationLauncher>> container = std::move(launchers);
+ for (auto &&launcher : container) {
+ applications.push_back(std::make_unique<ApplicationHandle>(std::move(launcher)));
+ }
+ }
- connect(typeid(APMAction), [this](sys::DataMessage *request, sys::ResponseMessage *) {
- auto actionMsg = static_cast<APMAction *>(request);
- handleAction(actionMsg);
- return std::make_shared<sys::ResponseMessage>();
- });
+ void ApplicationManagerBase::setState(State _state) noexcept
+ {
+ state = _state;
}
- ApplicationManager::~ApplicationManager()
+ void ApplicationManagerBase::pushApplication(const ApplicationHandle::Name &name)
{
- systemManager = nullptr;
+ stack.push_front(name);
}
- bool ApplicationManager::closeServices()
+ void ApplicationManagerBase::popApplication()
{
- bool ret = sys::SystemManager::DestroyService("ServiceGUI", this);
- if (ret) {
- LOG_INFO("Service: %s closed", "ServiceGUI");
- }
- else {
- LOG_FATAL("Service: %s is still running", "ServiceGUI");
- }
- ret = sys::SystemManager::DestroyService("ServiceEink", this);
- if (ret) {
- LOG_INFO("Service: %s closed", "ServiceEink");
- }
- else {
- LOG_FATAL("Service: %s is still running", "ServiceEink");
+ if (!stack.empty()) {
+ stack.pop_front();
}
- return true;
}
- bool ApplicationManager::closeApplications()
+ void ApplicationManagerBase::clearStack()
{
+ stack.clear();
+ }
- // if application is started, its in first plane or it's working in background
- // it will be closed using SystemManager's API.
- for (auto &app : getApps()) {
- if (app != nullptr && ((app->getState() == app::Application::State::ACTIVE_FORGROUND) ||
- (app->getState() == app::Application::State::ACTIVE_BACKGROUND) ||
- (app->getState() == app::Application::State::ACTIVATING))) {
- LOG_INFO("Closing application: %s", app->name().c_str());
- bool ret = sys::SystemManager::DestroyService(app->name(), this);
- if (ret) {
- LOG_INFO("Application: %s closed", app->name().c_str());
- }
- else {
- LOG_FATAL("Application: %s is still running", app->name().c_str());
- }
- app->setState(app::Application::State::DEACTIVATED);
+ auto ApplicationManagerBase::getFocusedApplication() const noexcept -> ApplicationHandle *
+ {
+ for (const auto &appName : stack) {
+ if (auto app = getApplication(appName);
+ app != nullptr && app->state() == app::Application::State::ACTIVE_FORGROUND) {
+ return app;
}
}
- return true;
+ return nullptr;
}
- sys::Message_t ApplicationManager::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)
+ auto ApplicationManagerBase::getLaunchingApplication() const noexcept -> ApplicationHandle *
{
-
- auto msgType = msgl->messageType;
-
- switch (msgType) {
- case MessageType::APMCheckAppRunning: {
- auto appcheck = dynamic_cast<sapm::APMCheckApp *>(msgl);
- assert(appcheck);
- auto ret = std::make_shared<APMCheckApp>(this->GetName(), appcheck->appNameToCheck);
- if (appGet(appcheck->appNameToCheck) != nullptr) {
- ret->isRunning = true;
- }
- else {
- ret->isRunning = false;
- }
- return ret;
- } break;
- case MessageType::APMInitPowerSaveMode: {
- handlePowerSavingModeInit();
- } break;
- case MessageType::APMPreventBlocking: {
- blockingTimer->reload();
- } break;
- case MessageType::APMSwitch: {
- sapm::APMSwitch *msg = reinterpret_cast<sapm::APMSwitch *>(msgl);
- handleSwitchApplication(msg);
- } break;
- case MessageType::APMSwitchPrevApp: {
- sapm::APMSwitchPrevApp *msg = reinterpret_cast<sapm::APMSwitchPrevApp *>(msgl);
- if (!handleSwitchPrevApplication(msg)) {
- LOG_ERROR("Switch from app: %s failed", msg->getSenderName().c_str());
- }
- } break;
- case MessageType::APMConfirmSwitch: {
- sapm::APMConfirmSwitch *msg = reinterpret_cast<sapm::APMConfirmSwitch *>(msgl);
- handleSwitchConfirmation(msg);
- } break;
- case MessageType::APMConfirmClose: {
- sapm::APMConfirmClose *msg = reinterpret_cast<sapm::APMConfirmClose *>(msgl);
- LOG_INFO("APMConfirmClose %s", msg->getSenderName().c_str());
- handleCloseConfirmation(msg);
-
- // if application manager was waiting for close confirmation and name of the application
- // for launching is defined then start application function is called
- if ((getState() == State::WAITING_CLOSE_CONFIRMATION) && (launchApplicationName.empty() == false)) {
- startApplication(launchApplicationName);
- }
- } break;
- case MessageType::APMDeleydClose: {
- sapm::APMDelayedClose *msg = reinterpret_cast<sapm::APMDelayedClose *>(msgl);
- LOG_INFO("APMDeleydClose %s", msg->getApplication().c_str());
- sys::SystemManager::DestroyService(msg->getApplication().c_str(), this);
- } break;
- case MessageType::APMRegister: {
- sapm::APMRegister *msg = reinterpret_cast<sapm::APMRegister *>(msgl);
- LOG_INFO("APMregister [%s] (%s)", msg->getSenderName().c_str(), (msg->getStatus() ? "true" : "false"));
- handleRegisterApplication(msg);
- } break;
- case MessageType::APMChangeLanguage: {
- sapm::APMChangeLanguage *msg = reinterpret_cast<sapm::APMChangeLanguage *>(msgl);
- std::string lang;
- if (msg->getLanguage() == utils::Lang::En)
- lang = "English";
- if (msg->getLanguage() == utils::Lang::Pl)
- lang = "Polish";
- if (msg->getLanguage() == utils::Lang::De)
- lang = "German";
- if (msg->getLanguage() == utils::Lang::Sp)
- lang = "Spanish";
- LOG_INFO("APChangeLanguage; %s %s", msg->getSenderName().c_str(), lang.c_str());
- handleLanguageChange(msg);
- } break;
- case MessageType::APMClose: {
- closeApplications();
- closeServices();
- } break;
- default: {
- } break;
- };
-
- return std::make_shared<sys::ResponseMessage>();
+ if (stack.empty()) {
+ return nullptr;
+ }
+ auto app = getApplication(stack.front());
+ return app->state() != app::Application::State::ACTIVE_FORGROUND ? app : nullptr;
}
- void ApplicationManager::phoneLockCB()
+ auto ApplicationManagerBase::getPreviousApplication() const noexcept -> ApplicationHandle *
{
-#ifdef AUTO_PHONE_LOCK_ENABLED
-
- LOG_INFO("screen Locking Timer Triggered");
- blockingTimer->stop();
-
- // check if application that has focus doesn't have a flag that prevents system from blocking and going to
- // low power mode
- ApplicationDescription *appDescription = appGet(focusApplicationName);
- if (appDescription->preventsLocking()) {
- blockingTimer->reload();
- return;
+ if (stack.size() < 2) {
+ return nullptr;
}
+ return getApplication(stack[1]);
+ }
- // if desktop has focus switch to main window and set it locked.
- if (focusApplicationName == app::name_desktop) {
- // switch data must contain target window and information about blocking
-
- app::Application::messageSwitchApplication(
- this, app::name_desktop, gui::name::window::main_window, std::make_unique<gui::LockPhoneData>());
+ auto ApplicationManagerBase::getApplication(const ApplicationHandle::Name &name) const noexcept
+ -> ApplicationHandle *
+ {
+ auto it = std::find_if(
+ applications.begin(), applications.end(), [&name](const auto &app) { return app->name() == name; });
+ if (it == applications.end()) {
+ return nullptr;
}
- else {
- // get the application description for application that is on top and set blocking flag for it
- appDescription->blockClosing = true;
-
- std::unique_ptr<gui::LockPhoneData> data = std::make_unique<gui::LockPhoneData>();
- data->setPrevApplication(focusApplicationName);
+ return it->get();
+ }
- // run normal flow of applications change
- messageSwitchApplication(this, app::name_desktop, gui::name::window::main_window, std::move(data));
- }
-#endif
+ ApplicationManager::ApplicationManager(const std::string &serviceName,
+ std::vector<std::unique_ptr<app::ApplicationLauncher>> &&launchers,
+ const ApplicationHandle::Name &_rootApplicationName)
+ : Service{serviceName}, ApplicationManagerBase(std::move(launchers)), rootApplicationName{_rootApplicationName},
+ blockingTimer{std::make_unique<sys::Timer>(
+ "BlockTimer", this, std::numeric_limits<sys::ms>::max(), sys::Timer::Type::SingleShot)}
+ {
+ registerMessageHandlers();
+ blockingTimer->connect([this](sys::Timer &) { onPhoneLocked(); });
}
- // Invoked during initialization
sys::ReturnCodes ApplicationManager::InitHandler()
{
-
- // get settings to initialize language in applications
settings = DBServiceAPI::SettingsGet(this);
+ blockingTimer->setInterval(settings.lockTime != 0 ? settings.lockTime : default_application_locktime_ms);
+ utils::localize.Switch(toUtilsLanguage(settings.language));
- // reset blocking timer to the value specified in settings
- uint32_t lockTime = settings.lockTime;
- if (lockTime == 0) {
- lockTime = default_application_locktime;
+ startSystemServices();
+ startBackgroundApplications();
+ if (auto app = getApplication(rootApplicationName); app != nullptr) {
+ Controller::switchApplication(this, rootApplicationName, std::string{}, nullptr);
}
- blockingTimer->setInterval(lockTime);
- if (settings.language == SettingsLanguage::ENGLISH) {
- utils::localize.Switch(utils::Lang::En);
- }
- else if (settings.language == SettingsLanguage::POLISH) {
- utils::localize.Switch(utils::Lang::Pl);
- }
- else if (settings.language == SettingsLanguage::GERMAN) {
- utils::localize.Switch(utils::Lang::De);
- }
- else if (settings.language == SettingsLanguage::SPANISH) {
- utils::localize.Switch(utils::Lang::Sp);
- }
+ return sys::ReturnCodes::Success;
+ }
- bool ret;
- ret = sys::SystemManager::CreateService(std::make_shared<sgui::ServiceGUI>("ServiceGUI", GetName(), 480, 600),
- this);
- if (!ret) {
+ void ApplicationManager::startSystemServices()
+ {
+ if (bool ret = sys::SystemManager::CreateService(
+ std::make_shared<sgui::ServiceGUI>(GUIServiceName, GetName(), 480, 600), this);
+ !ret) {
LOG_ERROR("Failed to initialize GUI service");
}
- ret = sys::SystemManager::CreateService(std::make_shared<ServiceEink>("ServiceEink", GetName()), this);
- if (!ret) {
- LOG_ERROR("Failed to initialize EINK service");
+ if (bool ret =
+ sys::SystemManager::CreateService(std::make_shared<ServiceEink>(EInkServiceName, GetName()), this);
+ !ret) {
+ LOG_ERROR("Failed to initialize EInk service");
}
+ }
- // search for application with specified name and run it
-#if 1 // change to 0 if you want to run only viewer application for kickstarter
-
- // TODO this should be checked by parameter in launcher, not started by hand (if bg task -> runBackground())
- const std::string app_desktop = app::name_desktop;
- const std::vector<std::string> bg_apps = {app::name_call, app::special_input};
+ void ApplicationManager::suspendSystemServices()
+ {
+ sys::SystemManager::SuspendService(GUIServiceName, this);
+ sys::SystemManager::SuspendService(EInkServiceName, this);
+ }
- for (auto &el : bg_apps) {
- auto app = appGet(el);
- if (app != nullptr) {
- app->launcher->runBackground(this);
+ void ApplicationManager::startBackgroundApplications()
+ {
+ for (const auto &name : std::vector<ApplicationHandle::Name>{app::name_call, app::special_input}) {
+ if (auto app = getApplication(name); app != nullptr) {
+ app->runInBackground(this);
}
}
-
- auto app = appGet(app_desktop);
- if (app != nullptr) {
- messageSwitchApplication(this, app->launcher->getName(), "", nullptr);
- }
-
-#else
- std::string runCallAppName = "ApplicationViewer";
-
- auto it = applications.find(runCallAppName);
- if (it != applications.end()) {
- messageSwitchApplication(this, it->second->lanucher->getName(), "", nullptr);
- }
-#endif
-
- return sys::ReturnCodes::Success;
}
sys::ReturnCodes ApplicationManager::DeinitHandler()
@@ 413,139 248,209 @@ namespace sapm
return sys::ReturnCodes::Success;
}
+ auto ApplicationManager::DataReceivedHandler([[maybe_unused]] sys::DataMessage *msgl,
+ [[maybe_unused]] sys::ResponseMessage *resp) -> sys::Message_t
+ {
+ return std::make_shared<sys::ResponseMessage>();
+ }
+
+ void ApplicationManager::registerMessageHandlers()
+ {
+ connect(typeid(APMCheckApp), [this](sys::DataMessage *request, sys::ResponseMessage *) {
+ auto msg = static_cast<APMCheckApp *>(request);
+ auto ret = std::make_shared<APMCheckApp>(GetName(), msg->checkAppName);
+ ret->isRunning = getApplication(msg->checkAppName) != nullptr;
+ return ret;
+ });
+ connect(typeid(APMInitPowerSaveMode), [this](sys::DataMessage *, sys::ResponseMessage *) {
+ handlePowerSavingModeInit();
+ return std::make_shared<sys::ResponseMessage>();
+ });
+ connect(typeid(APMPreventBlocking), [this](sys::DataMessage *, sys::ResponseMessage *) {
+ blockingTimer->reload();
+ return std::make_shared<sys::ResponseMessage>();
+ });
+ connect(typeid(APMSwitch), [this](sys::DataMessage *request, sys::ResponseMessage *) {
+ auto msg = static_cast<APMSwitch *>(request);
+ handleSwitchApplication(msg);
+ return std::make_shared<sys::ResponseMessage>();
+ });
+ connect(typeid(APMSwitchPrevApp), [this](sys::DataMessage *request, sys::ResponseMessage *) {
+ auto msg = static_cast<APMSwitchPrevApp *>(request);
+ handleSwitchBack(msg);
+ return std::make_shared<sys::ResponseMessage>();
+ });
+ connect(typeid(APMConfirmSwitch), [this](sys::DataMessage *request, sys::ResponseMessage *) {
+ auto msg = static_cast<APMConfirmSwitch *>(request);
+ handleSwitchConfirmation(msg);
+ return std::make_shared<sys::ResponseMessage>();
+ });
+ connect(typeid(APMConfirmClose), [this](sys::DataMessage *request, sys::ResponseMessage *) {
+ auto msg = static_cast<APMConfirmClose *>(request);
+ handleCloseConfirmation(msg);
+ return std::make_shared<sys::ResponseMessage>();
+ });
+ connect(typeid(APMDelayedClose), [this](sys::DataMessage *request, sys::ResponseMessage *) {
+ auto msg = static_cast<APMDelayedClose *>(request);
+ closeService(msg->getApplication());
+ return std::make_shared<sys::ResponseMessage>();
+ });
+ connect(typeid(APMRegister), [this](sys::DataMessage *request, sys::ResponseMessage *) {
+ auto msg = static_cast<APMRegister *>(request);
+ handleRegisterApplication(msg);
+ return std::make_shared<sys::ResponseMessage>();
+ });
+ connect(typeid(APMChangeLanguage), [this](sys::DataMessage *request, sys::ResponseMessage *) {
+ auto msg = static_cast<APMChangeLanguage *>(request);
+ handleLanguageChange(msg);
+ return std::make_shared<sys::ResponseMessage>();
+ });
+ connect(typeid(APMClose), [this](sys::DataMessage *, sys::ResponseMessage *) {
+ closeApplications();
+ closeServices();
+ return std::make_shared<sys::ResponseMessage>();
+ });
+ connect(typeid(APMAction), [this](sys::DataMessage *request, sys::ResponseMessage *) {
+ auto actionMsg = static_cast<APMAction *>(request);
+ handleAction(actionMsg);
+ return std::make_shared<sys::ResponseMessage>();
+ });
+ }
+
sys::ReturnCodes ApplicationManager::SwitchPowerModeHandler(const sys::ServicePowerMode mode)
{
- LOG_FATAL("[ServiceAppMgr] PowerModeHandler: %s", c_str(mode));
+ LOG_INFO("Power mode: %s", c_str(mode));
switch (mode) {
case sys::ServicePowerMode ::Active:
- sys::SystemManager::ResumeService("ServiceEink", this);
- sys::SystemManager::ResumeService("ServiceGUI", this);
+ sys::SystemManager::ResumeService(EInkServiceName, this);
+ sys::SystemManager::ResumeService(GUIServiceName, this);
break;
case sys::ServicePowerMode ::SuspendToRAM:
+ [[fallthrough]];
case sys::ServicePowerMode ::SuspendToNVM:
- sys::SystemManager::SuspendService("ServiceGUI", this);
- sys::SystemManager::SuspendService("ServiceEink", this);
+ suspendSystemServices();
break;
}
-
return sys::ReturnCodes::Success;
}
- bool ApplicationManager::startApplication(const std::string &appName)
+ auto ApplicationManager::startApplication(ApplicationHandle &app) -> bool
{
-
- setState(State::STARTING_NEW_APP);
- // search map for application's description structure with specified name
- auto app = appGet(appName);
- if (app == nullptr) {
- LOG_ERROR("Can't run: %s no such app", appName.c_str());
- return false;
- }
-
- if (app->getState() == app::Application::State::ACTIVE_BACKGROUND) {
- setState(State::WAITING_GET_FOCUS_CONFIRMATION);
- LOG_INFO("switching focus to application: [%s] window [%s]", appName.c_str(), app->switchWindow.c_str());
- app::Application::messageSwitchApplication(
- this, launchApplicationName, app->switchWindow, std::move(app->switchData));
+ if (app.state() == ApplicationHandle::State::ACTIVE_BACKGROUND) {
+ LOG_INFO("Switching focus to application [%s] (window [%s])", app.name().c_str(), app.switchWindow.c_str());
+ setState(State::AwaitingFocusConfirmation);
+ app::Application::messageSwitchApplication(this, app.name(), app.switchWindow, std::move(app.switchData));
}
else {
- setState(State::WAITING_NEW_APP_REGISTRATION);
- LOG_INFO("starting application: %s", appName.c_str());
- app->launcher->run(this);
+ LOG_INFO("Starting application %s", app.name().c_str());
+ app.run(this);
}
-
return true;
}
- bool ApplicationManager::handlePowerSavingModeInit()
+ auto ApplicationManager::closeServices() -> bool
{
+ closeService(GUIServiceName);
+ closeService(EInkServiceName);
+ return true;
+ }
- LOG_INFO("Going to suspend mode");
+ auto ApplicationManager::closeApplications() -> bool
+ {
+ for (const auto &app : getApplications()) {
+ if (app->started()) {
+ LOG_INFO("Closing application %s", app->name().c_str());
+ closeService(app->name());
+ app->setState(ApplicationHandle::State::DEACTIVATED);
+ }
+ }
+ return true;
+ }
- sys::SystemManager::SuspendService("ServiceGUI", this);
- sys::SystemManager::SuspendService("ServiceEink", this);
+ void ApplicationManager::closeService(const std::string &name)
+ {
+ bool ret = sys::SystemManager::DestroyService(name, this);
+ if (ret) {
+ LOG_INFO("Service/Application %s closed", name.c_str());
+ }
+ else {
+ LOG_FATAL("Service/Application %s is still running", name.c_str());
+ }
+ }
+ auto ApplicationManager::handlePowerSavingModeInit() -> bool
+ {
+ LOG_INFO("Going to suspend mode");
+ suspendSystemServices();
sys::SystemManager::SuspendSystem(this);
-
return true;
}
- // tries to switch the application
- bool ApplicationManager::handleSwitchApplication(APMSwitch *msg)
+ auto ApplicationManager::handleSwitchApplication(APMSwitch *msg) -> bool
{
-
- // first check if there is application specified in the message
- auto app = appGet(msg->getName());
- if (!app) {
- LOG_ERROR("Cant switch to app: %s , doesn't exist", msg->getName().c_str());
+ auto app = getApplication(msg->getName());
+ if (app == nullptr) {
+ LOG_ERROR("Failed to switch to application %s: No such application.", msg->getName().c_str());
return false;
}
- // check if specified application is not the application that is currently running
- // this is applicable to all applications except desktop
- if ((focusApplicationName == msg->getName())) {
- LOG_WARN("Trying to return currently active application");
+ auto currentlyFocusedApp = getFocusedApplication();
+ if (currentlyFocusedApp == nullptr) {
+ LOG_INFO("No focused application at the moment. Starting new application...");
+ onApplicationSwitch(*app, std::move(msg->getData()), msg->getWindow());
+ startApplication(*app);
+ return true;
+ }
+
+ if (app->name() == currentlyFocusedApp->name()) {
+ LOG_WARN("Failed to return to currently focused application.");
return false;
}
- // store the name of the application to be executed and start closing previous application
- launchApplicationName = msg->getName();
+ onApplicationSwitch(*app, std::move(msg->getData()), msg->getWindow());
+ const bool isFocusedAppCloseable = !(app->switchData && app->switchData->disableAppClose) &&
+ currentlyFocusedApp->closeable() && !currentlyFocusedApp->blockClosing;
+ requestApplicationClose(*currentlyFocusedApp, isFocusedAppCloseable);
+ return true;
+ }
- // store window and data if there is any
- app->switchData = std::move(msg->getData());
- app->switchWindow = msg->getWindow();
- setState(State::CLOSING_PREV_APP);
+ void ApplicationManager::onApplicationSwitch(ApplicationHandle &app,
+ std::unique_ptr<gui::SwitchData> &&data,
+ std::string targetWindow)
+ {
+ if (app.name() == rootApplicationName) {
+ clearStack();
+ }
+ pushApplication(app.name());
+ app.switchData = std::move(data);
+ app.switchWindow = std::move(targetWindow);
+ }
- // check if there was previous application
- if (!focusApplicationName.empty()) {
- if (launchApplicationName == app::name_desktop) {
- appStack.clear();
- }
- else {
- appStack.push_back(focusApplicationName);
- LOG_DEBUG("LaunchApp: %s", launchApplicationName.c_str());
- }
- /// if we want to disable closing previous app - then forbid killing it - it will be moved to background
- /// instead
- bool kill_prev = true;
- if (app->switchData != nullptr && app->switchData->disableAppClose) {
- kill_prev = false;
- }
- previousApplicationName = focusApplicationName;
- auto app = appGet(previousApplicationName);
- // if application's launcher defines that it can be closed send message with close signal
- if (kill_prev && (app->closeable()) && (app->blockClosing == false)) {
- LOG_INFO("APMSwitch waiting for close confirmation from: %s", previousApplicationName.c_str());
- setState(State::WAITING_CLOSE_CONFIRMATION);
- app::Application::messageCloseApplication(this, previousApplicationName);
- }
- // if application is not closeable send lost focus message
- else {
- LOG_INFO("APMSwitch Waiting for lost focus from: %s", previousApplicationName.c_str());
- setState(State::WAITING_LOST_FOCUS_CONFIRMATION);
- app::Application::messageSwitchApplication(this, previousApplicationName, "", nullptr);
- }
+ void ApplicationManager::requestApplicationClose(ApplicationHandle &app, bool isCloseable)
+ {
+ if (isCloseable) {
+ LOG_INFO("Closing application %s", app.name().c_str());
+ setState(State::AwaitingCloseConfirmation);
+ app::Application::messageCloseApplication(this, app.name());
}
- // if there was no application to close or application can't be closed change internal state to
- // STARTING_NEW_APP and send execute lanuchers for that application
else {
- startApplication(app->name());
+ LOG_INFO("Application %s is about to lose focus.", app.name().c_str());
+ setState(State::AwaitingLostFocusConfirmation);
+ app::Application::messageApplicationLostFocus(this, app.name());
}
-
- return true;
}
auto ApplicationManager::handleAction(APMAction *actionMsg) -> bool
{
auto &action = actionMsg->getAction();
- const auto targetApp = appGet(action.targetApplication);
+ const auto targetApp = getApplication(action.targetApplication);
if (targetApp == nullptr) {
LOG_ERROR("Failed to switch to %s application: No such application.", action.targetApplication.c_str());
return false;
}
- if (targetApp->getState() == app::Application::State::ACTIVE_FORGROUND) {
+ if (targetApp->state() == app::Application::State::ACTIVE_FORGROUND) {
// If the app is already focused, then switch window.
auto msg = std::make_shared<app::AppSwitchWindowMessage>(
action.targetWindow, std::string{}, std::move(action.data), gui::ShowMode::GUI_SHOW_INIT);
@@ 556,354 461,213 @@ namespace sapm
return handleSwitchApplication(&switchRequest);
}
- // tries to switch the application
- bool ApplicationManager::handleSwitchPrevApplication(APMSwitchPrevApp *msg)
+ auto ApplicationManager::handleSwitchBack(APMSwitchPrevApp *msg) -> bool
{
-
- // if there is no previous application return false and do nothing
- if (previousApplicationName.empty()) {
+ auto previousApp = getPreviousApplication();
+ if (previousApp == nullptr) {
+ LOG_WARN("Failed to switch to the previous application: No such application.");
return false;
}
- if (appStack.empty()) {
- LOG_ERROR("appStack is empty");
- return false;
- }
-
- previousApplicationName = appStack.back();
- appStack.pop_back();
- if (previousApplicationName == app::name_desktop && appStack.size()) {
- std::string names = "";
- for (auto &el : appStack) {
- names += el + "<-";
- }
- LOG_ERROR("%s isn't top application! [%s]", app::name_desktop.c_str(), names.c_str());
- }
-
- // check if previous application is stored in the description vector
- auto app = appGet(previousApplicationName);
- if (!app) {
- // specified application was not found, exiting
- LOG_ERROR("Unable to find previous application: %s", previousApplicationName.c_str());
- return false;
+ auto currentlyFocusedApp = getFocusedApplication();
+ if (currentlyFocusedApp == nullptr) {
+ LOG_INFO("No focused application at the moment. Starting previous application...");
+ onApplicationSwitchToPrev(*previousApp, std::move(msg->getData()));
+ startApplication(*previousApp);
+ return true;
}
- // check if specified application is not the application that is currently running
- if (focusApplicationName == previousApplicationName) {
- LOG_WARN("Trying to return currently active application");
+ if (previousApp->name() == currentlyFocusedApp->name()) {
+ LOG_WARN("Failed to return to currently focused application.");
return false;
}
- LOG_DEBUG("Switch PrevApp: [%s](%s) -> [%s](%s)",
- focusApplicationName.c_str(),
- app::Application::stateStr(appGet(previousApplicationName)->getState()),
- previousApplicationName.c_str(),
- app::Application::stateStr(appGet(previousApplicationName)->getState()));
- // set name of the application to be executed and start closing previous application
- launchApplicationName = previousApplicationName;
- // store window and data if there is any
- app->switchData = std::move(msg->getData());
- app->switchWindow = "LastWindow";
- setState(State::CLOSING_PREV_APP);
-
- // check if there was previous application
- if (!focusApplicationName.empty()) {
- previousApplicationName = focusApplicationName;
- auto app = appGet(previousApplicationName);
-
- // if application's launcher defines that it can be closed send message with close signal
- if (app->closeable()) {
- LOG_INFO("Closing application: %s", previousApplicationName.c_str());
- setState(State::WAITING_CLOSE_CONFIRMATION);
- app::Application::messageCloseApplication(this, previousApplicationName);
- }
- // if application is not closeable send lost focus message
- else {
- setState(State::WAITING_LOST_FOCUS_CONFIRMATION);
- app::Application::messageSwitchApplication(this, previousApplicationName, "", nullptr);
- }
- }
- // if there was no application to close or application can't be closed change internal state to
- // STARTING_NEW_APP and send execute lanuchers for that application
- else {
- startApplication(app->name());
- }
+ LOG_DEBUG("Switch applications: [%s](%s) -> [%s](%s)",
+ currentlyFocusedApp->name().c_str(),
+ app::Application::stateStr(currentlyFocusedApp->state()),
+ previousApp->name().c_str(),
+ app::Application::stateStr(previousApp->state()));
+ onApplicationSwitchToPrev(*previousApp, std::move(msg->getData()));
+ requestApplicationClose(*currentlyFocusedApp, currentlyFocusedApp->closeable());
return true;
}
- bool ApplicationManager::handleRegisterApplication(APMRegister *msg)
+ void ApplicationManager::onApplicationSwitchToPrev(ApplicationHandle &previousApp,
+ std::unique_ptr<gui::SwitchData> &&data,
+ std::string targetWindow)
{
- auto app = appGet(msg->getSenderName());
+ popApplication();
+ previousApp.switchData = std::move(data);
+ previousApp.switchWindow = std::move(targetWindow);
+ }
+
+ auto ApplicationManager::handleRegisterApplication(APMRegister *msg) -> bool
+ {
+ auto app = getApplication(msg->getSenderName());
if (app == nullptr) {
- LOG_ERROR("can't register: %s no such app in `applicationsk`", msg->getSenderName().c_str());
+ LOG_ERROR("Failed to register %s: No such application.", msg->getSenderName().c_str());
return false;
}
- LOG_DEBUG("Register ---------> %s", msg->getSenderName().c_str());
- if (msg->getSenderName() == launchApplicationName) {
- // application starts in background
- if (msg->getStartBackground()) {
- app->setState(app::Application::State::ACTIVE_BACKGROUND);
- setState(State::IDLE);
- }
- else {
- app->setState(app::Application::State::ACTIVATING);
- setState(State::WAITING_GET_FOCUS_CONFIRMATION);
- LOG_INFO("switchApplication %s %s",
- launchApplicationName.c_str(),
- app->switchData ? app->switchData->getDescription().c_str() : "");
- app::Application::messageSwitchApplication(
- this, launchApplicationName, app->switchWindow, std::move(app->switchData));
- }
+ if (msg->getStatus()) {
+ onApplicationRegistered(*app, msg->getStartBackground());
}
else {
- app->setState(app::Application::State::ACTIVE_BACKGROUND);
+ onApplicationRegistrationFailure(*app);
}
- LOG_DEBUG("Send notification!");
- auto notification = std::make_shared<APMCheckApp>(this->GetName(), msg->getSenderName());
+ auto notification = std::make_shared<APMCheckApp>(GetName(), app->name());
sys::Bus::SendMulticast(notification, sys::BusChannels::AppManagerNotifications, this);
-
return true;
}
- bool ApplicationManager::handleLanguageChange(sapm::APMChangeLanguage *msg)
+ void ApplicationManager::onApplicationRegistered(ApplicationHandle &app, bool startInBackground)
{
+ LOG_DEBUG("Application %s registered successfully.", app.name().c_str());
- // check if selected language is different than the one that is in the settings
- // if they are the same, return doing nothing
- SettingsLanguage requestedLanguage;
- switch (msg->getLanguage()) {
- case utils::Lang::En:
- requestedLanguage = SettingsLanguage::ENGLISH;
- break;
- case utils::Lang::Pl:
- requestedLanguage = SettingsLanguage::POLISH;
- break;
- case utils::Lang::De:
- requestedLanguage = SettingsLanguage::GERMAN;
- break;
- case utils::Lang::Sp:
- requestedLanguage = SettingsLanguage::SPANISH;
- break;
- default:
- requestedLanguage = SettingsLanguage::ENGLISH;
- break;
- };
+ auto launchingApp = getLaunchingApplication();
+ if (launchingApp == nullptr || launchingApp->name() != app.name()) {
+ app.setState(ApplicationHandle::State::ACTIVE_BACKGROUND);
+ return;
+ }
- // if requested language is different than current update settings and i18 translations
- if (requestedLanguage != settings.language) {
- settings = DBServiceAPI::SettingsGet(this);
- settings.language = requestedLanguage;
- DBServiceAPI::SettingsUpdate(this, settings);
- utils::localize.Switch(msg->getLanguage());
+ if (startInBackground) {
+ setState(State::Running);
+ app.setState(ApplicationHandle::State::ACTIVE_BACKGROUND);
}
else {
- LOG_WARN("Selected language is already set. Ignoring command.");
- return true;
- }
-
- // iterate over all applications in the background or foreground state and send them rebuild command
- for (auto &app : getApps()) {
- if (app && app->launcher && app->launcher->handle &&
- (app->launcher->handle->getState() == app::Application::State::ACTIVE_BACKGROUND ||
- app->launcher->handle->getState() == app::Application::State::ACTIVE_FORGROUND)) {
- app::Application::messageRebuildApplication(this, app->name());
- }
+ LOG_INFO("Switch application to %s", app.name().c_str());
+ app.setState(ApplicationHandle::State::ACTIVATING);
+ setState(State::AwaitingFocusConfirmation);
+ app::Application::messageSwitchApplication(this, app.name(), app.switchWindow, std::move(app.switchData));
}
-
- return true;
}
- bool ApplicationManager::handleSwitchConfirmation(APMConfirmSwitch *msg)
+ void ApplicationManager::onApplicationRegistrationFailure(ApplicationHandle &app)
{
- std::string app_name =
- getState() == State::WAITING_GET_FOCUS_CONFIRMATION ? msg->getSenderName() : focusApplicationName;
- ApplicationDescription *app = appGet(app_name);
- if (app == nullptr) {
- LOG_ERROR("Can't handle switch confirmation to: %s", app_name.c_str());
- return false;
- }
-
- /// move application with focus to front
- {
- auto app = appGet(msg->getSenderName());
- if (app && app->getState() == app::Application::State::ACTIVE_FORGROUND) {
- appMoveFront(app);
- debug_log_app_list();
- // notify event manager which application should receive keyboard messages
- EventManager::messageSetApplication(this, app->name());
- }
- else {
- LOG_DEBUG("Focus switch ingored cause: %d %s",
- app == nullptr,
- app == nullptr ? "" : app::Application::stateStr(app->getState()));
- }
- }
- // this is the case when application manager is waiting for newly started application to confim that it has
- // successfully gained focus.
- if (getState() == State::WAITING_GET_FOCUS_CONFIRMATION || getState() == State::IDLE) {
- LOG_INFO("APMConfirmSwitch focus confirmed by: [%s]", msg->getSenderName().c_str());
- focusApplicationName = launchApplicationName;
- launchApplicationName = "";
-
- app->blockClosing = false;
- app->setState(app::Application::State::ACTIVE_FORGROUND);
- setState(State::IDLE);
- return true;
- }
- // this is the case where application manager is waiting for non-closeable application
- // to confirm that app has lost focus.
- else if (getState() == State::WAITING_LOST_FOCUS_CONFIRMATION) {
- if (msg->getSenderName() == focusApplicationName) {
- LOG_INFO("APMConfirmSwitch Lost focus confirmed by: %s", msg->getSenderName().c_str());
- previousApplicationName = focusApplicationName;
- focusApplicationName = "";
- app->setState(app::Application::State::ACTIVE_BACKGROUND);
- app->switchWindow = "LastWindow";
- startApplication(launchApplicationName);
- return true;
- }
- }
- LOG_ERROR("APMConfirmSwitch %s : %s state %s",
- msg->getSenderName().c_str(),
- focusApplicationName.c_str(),
- stateStr(getState()));
- return false;
+ LOG_ERROR("Failed to register %s: Application initialisation error.", app.name().c_str());
+ Controller::switchBack(this);
}
- bool ApplicationManager::handleCloseConfirmation(APMConfirmClose *msg)
+ auto ApplicationManager::handleLanguageChange(app::manager::APMChangeLanguage *msg) -> bool
{
- auto app = appGet(msg->getSenderName());
- if (app == nullptr) {
- LOG_ERROR("can't handle: %s app: %s doesn't exist", __FUNCTION__, msg->getSenderName().c_str());
- return false;
+ const auto requestedLanguage = toSettingsLanguage(msg->getLanguage());
+ if (requestedLanguage == settings.language) {
+ LOG_WARN("The selected language is already set. Ignore.");
+ return true;
}
- // if application is running and it's not closeable set state to active background
- // otherwise it means that application is ready to be closed by using DestroyService api
- if (app->closeable()) {
- // internally send close message to allow response message to be sended to application
- // that has confirmed close request.
- app->setState(app::Application::State::DEACTIVATED);
- auto msg = std::make_shared<sapm::APMDelayedClose>(this->GetName(), previousApplicationName);
- sys::Bus::SendUnicast(msg, "ApplicationManager", this);
- }
- else {
- app->setState(app::Application::State::ACTIVE_BACKGROUND);
- }
+ settings = DBServiceAPI::SettingsGet(this);
+ settings.language = requestedLanguage;
+ DBServiceAPI::SettingsUpdate(this, settings);
+ utils::localize.Switch(msg->getLanguage());
+ rebuildActiveApplications();
return true;
}
- // Static methods
- auto ApplicationManager::sendAction(sys::Service *sender, Action &&action) -> bool
+ void ApplicationManager::rebuildActiveApplications()
{
- auto msg = std::make_shared<APMAction>(sender->GetName(), std::move(action));
- return sys::Bus::SendUnicast(msg, "ApplicationManager", sender);
+ for (const auto &app : getApplications()) {
+ if (app && app->launcher && app->launcher->handle) {
+ if (const auto appState = app->state(); appState == ApplicationHandle::State::ACTIVE_FORGROUND ||
+ appState == ApplicationHandle::State::ACTIVE_BACKGROUND) {
+ app::Application::messageRebuildApplication(this, app->name());
+ }
+ }
+ }
}
- bool ApplicationManager::messageSwitchApplication(sys::Service *sender,
- const std::string &applicationName,
- const std::string &windowName,
- std::unique_ptr<gui::SwitchData> data)
+ auto ApplicationManager::handleSwitchConfirmation(APMConfirmSwitch *msg) -> bool
{
- auto msg = std::make_shared<sapm::APMSwitch>(sender->GetName(), applicationName, windowName, std::move(data));
- return sys::Bus::SendUnicast(msg, "ApplicationManager", sender);
+ auto senderApp = getApplication(msg->getSenderName());
+ if (senderApp == nullptr) {
+ LOG_ERROR("Failed to switch to %s. No such application.", msg->getSenderName().c_str());
+ return false;
+ }
+ LOG_INFO(
+ "Switch confirmed by %s (%s).", senderApp->name().c_str(), app::Application::stateStr(senderApp->state()));
+ return onSwitchConfirmed(*senderApp);
}
- bool ApplicationManager::messageSwitchSpecialInput(sys::Service *sender,
- std::unique_ptr<gui::SwitchSpecialChar> data)
+ auto ApplicationManager::onSwitchConfirmed(ApplicationHandle &app) -> bool
{
- auto val = data->requester;
- // forbid killing prev app, it could be done better - i.e. with state (not this disableAppClose parameter)
- data->disableAppClose = true;
- return (gui::SwitchSpecialChar::Type::Request == data->type)
- ? messageSwitchApplication(sender, app::special_input, app::char_select, std::move(data))
- : messageSwitchPreviousApplication(
- sender, std::make_unique<APMSwitchPrevApp>(data->requester, std::move(data)));
+ if (getState() == State::AwaitingFocusConfirmation || getState() == State::Running) {
+ app.blockClosing = false;
+ app.setState(ApplicationHandle::State::ACTIVE_FORGROUND);
+ setState(State::Running);
+ EventManager::messageSetApplication(this, app.name());
+ return true;
+ }
+ if (getState() == State::AwaitingLostFocusConfirmation) {
+ if (auto launchingApp = getLaunchingApplication(); launchingApp != nullptr) {
+ LOG_INFO("Lost focus confirmed by %s. Starting %s application.",
+ app.name().c_str(),
+ launchingApp->name().c_str());
+ app.setState(ApplicationHandle::State::ACTIVE_BACKGROUND);
+ app.switchWindow.clear();
+ startApplication(*launchingApp);
+ return true;
+ }
+ }
+ return false;
}
- bool ApplicationManager::messageConfirmSwitch(sys::Service *sender)
+ auto ApplicationManager::handleCloseConfirmation(APMConfirmClose *msg) -> bool
{
-
- auto msg = std::make_shared<sapm::APMConfirmSwitch>(sender->GetName());
- sys::Bus::SendUnicast(msg, "ApplicationManager", sender);
- return true;
+ auto senderApp = getApplication(msg->getSenderName());
+ if (senderApp == nullptr) {
+ LOG_ERROR("Failed to handle close confirmation from %s: No such application.",
+ msg->getSenderName().c_str());
+ return false;
+ }
+ return onCloseConfirmed(*senderApp);
}
- bool ApplicationManager::messageConfirmClose(sys::Service *sender)
- {
- auto msg = std::make_shared<sapm::APMConfirmClose>(sender->GetName());
- sys::Bus::SendUnicast(msg, "ApplicationManager", sender);
- return true;
- }
- bool ApplicationManager::messageSwitchPreviousApplication(sys::Service *sender,
- std::unique_ptr<APMSwitchPrevApp> msg)
+ auto ApplicationManager::onCloseConfirmed(ApplicationHandle &app) -> bool
{
-
- std::shared_ptr<APMSwitchPrevApp> sendMsg;
- if (!msg) {
- sendMsg = std::make_shared<sapm::APMSwitchPrevApp>(sender->GetName());
+ if (app.closeable()) {
+ app.setState(ApplicationHandle::State::DEACTIVATED);
+ Controller::closeApplication(this, app.name());
}
else {
- sendMsg = std::move(msg);
+ app.setState(ApplicationHandle::State::ACTIVE_BACKGROUND);
}
- sys::Bus::SendUnicast(sendMsg, "ApplicationManager", sender);
- return true;
- }
-
- bool ApplicationManager::messageRegisterApplication(sys::Service *sender,
- const bool &status,
- const bool &startBackground)
- {
- auto msg = std::make_shared<sapm::APMRegister>(sender->GetName(), status, startBackground);
- sys::Bus::SendUnicast(msg, "ApplicationManager", sender);
- return true;
- }
-
- bool ApplicationManager::messageChangeLanguage(sys::Service *sender, utils::Lang language)
- {
- auto msg = std::make_shared<sapm::APMChangeLanguage>(sender->GetName(), language);
- sys::Bus::SendUnicast(msg, "ApplicationManager", sender);
- return true;
- }
- bool ApplicationManager::messageCloseApplicationManager(sys::Service *sender)
- {
- auto msg = std::make_shared<sapm::APMClose>(sender->GetName());
- sys::Bus::SendUnicast(msg, "ApplicationManager", sender);
+ if (const auto launchingApp = getLaunchingApplication();
+ launchingApp != nullptr && getState() == State::AwaitingCloseConfirmation) {
+ startApplication(*launchingApp);
+ }
return true;
}
- bool ApplicationManager::messagePreventBlocking(sys::Service *sender)
+ void ApplicationManager::onPhoneLocked()
{
- auto msg = std::make_shared<sapm::APMPreventBlocking>(sender->GetName());
- sys::Bus::SendUnicast(msg, "ApplicationManager", sender);
- return true;
- }
+#ifdef AUTO_PHONE_LOCK_ENABLED
+ LOG_INFO("Screen lock timer triggered.");
+ blockingTimer->stop();
- bool ApplicationManager::messageInitPowerSaveMode(sys::Service *sender)
- {
- auto msg = std::make_shared<sapm::APMInitPowerSaveMode>(sender->GetName());
- sys::Bus::SendUnicast(msg, "ApplicationManager", sender);
- return true;
- }
+ auto focusedApp = getFocusedApplication();
+ if (focusedApp == nullptr || focusedApp->preventsBlocking()) {
+ blockingTimer->reload();
+ return;
+ }
- bool ApplicationManager::appRunning(sys::Service *sender, const std::string &name)
- {
- auto msg = std::make_shared<sapm::APMCheckApp>(sender->GetName(), name);
- auto msg_ret = sys::Bus::SendUnicast(msg, "ApplicationManager", sender, 5000);
- if (msg_ret.first != sys::ReturnCodes::Success) {
- LOG_ERROR("Cant send message!");
+ if (focusedApp->name() == rootApplicationName) {
+ app::Application::messageSwitchApplication(
+ this,
+ rootApplicationName,
+ gui::name::window::main_window,
+ std::make_unique<gui::LockPhoneData>(gui::LockPhoneData::Request::NoPin));
}
- auto ret = dynamic_cast<sapm::APMCheckApp *>(msg_ret.second.get());
- if (ret != nullptr && ret->isRunning) {
- return true;
+ else {
+ focusedApp->blockClosing = true;
+ std::unique_ptr<gui::LockPhoneData> data =
+ std::make_unique<gui::LockPhoneData>(gui::LockPhoneData::Request::NoPin);
+ data->setPrevApplication(focusedApp->name());
+ Controller::switchApplication(this, rootApplicationName, gui::name::window::main_window, std::move(data));
}
- return false;
- // return true;
+#endif
}
-
-} /* namespace sapm */
+} // namespace app::manager
M module-services/service-appmgr/ApplicationManager.hpp => module-services/service-appmgr/ApplicationManager.hpp +106 -227
@@ 1,267 1,146 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#ifndef MODULE_SERVICES_SERVICE_APPMGR_APPLICATIONMANAGER_HPP_
-#define MODULE_SERVICES_SERVICE_APPMGR_APPLICATIONMANAGER_HPP_
+#pragma once
-#include <cstdint>
#include <memory>
#include <string>
-#include <map>
-#include <string.h>
+
#include "Application.hpp"
#include "ApplicationLauncher.hpp"
-#include "SystemManager/SystemManager.hpp"
#include "messages/APMMessage.hpp"
-#include "i18/i18.hpp"
-
-inline uint32_t default_application_locktime = 30000;
namespace app
{
class ApplicationLauncher;
}
-namespace sapm
+namespace app::manager
{
-
- class ApplicationDescription
+ class ApplicationHandle
{
public:
- ApplicationDescription(std::unique_ptr<app::ApplicationLauncher> launcher);
- virtual ~ApplicationDescription()
- {}
- // name of the application. It's used to find proper application during switching
- std::string name()
- {
- if (launcher) {
- return launcher->getName();
- }
- else {
- return "NONE";
- }
- }
- // launcher to application to the application's start function
- std::unique_ptr<app::ApplicationLauncher> launcher = nullptr;
- // informs application manager that this application temporary musn't be closed.
- // This flag is used to prevent application closing when application is closeable and there is incoming call.
- // This flag is also used when closeable application is on front and there is a timeout to block the
- // applicatioin.
- bool blockClosing = false;
- // switching data stored when application manager had to run init function
- std::unique_ptr<gui::SwitchData> switchData = nullptr;
- std::string switchWindow = "";
-
- // prevents from blocking the system
- bool preventsLocking()
- {
- if (launcher != nullptr) {
- return launcher->isBlocking();
- }
- else {
- return false;
- }
- }
-
- // informs if it is possible to close application when it looses focus.
- bool closeable()
- {
- if (launcher != nullptr) {
- return launcher->isCloseable();
- }
- return false;
- }
-
- app::Application::State getState()
- {
- if ((launcher == nullptr) || (launcher->handle == nullptr)) {
- return app::Application::State::NONE;
- }
- else {
- return launcher->handle->getState();
- }
- }
-
- void setState(app::Application::State st)
- {
- if ((launcher == nullptr) || (launcher->handle == nullptr)) {
- LOG_ERROR("No %s", launcher == nullptr ? "launcher" : "handle");
- }
- else {
- launcher->handle->setState(st);
- }
- }
+ static inline constexpr std::string_view InvalidAppName{"NONE"};
+
+ using State = app::Application::State;
+ using Name = std::string;
+
+ explicit ApplicationHandle(std::unique_ptr<app::ApplicationLauncher> &&_launcher);
+
+ void setState(State state) noexcept;
+ void run(sys::Service *caller);
+ void runInBackground(sys::Service *caller);
+
+ auto name() const -> Name;
+ auto state() const noexcept -> State;
+ auto preventsBlocking() const noexcept -> bool;
+ auto closeable() const noexcept -> bool;
+ auto started() const noexcept -> bool;
+
+ std::unique_ptr<app::ApplicationLauncher> launcher; // Handle to the application's start function.
+ std::unique_ptr<gui::SwitchData> switchData;
+ std::string switchWindow;
+ bool blockClosing =
+ false; //< Informs the application manager that this application mustn't be closed temporarily.
+ // This flag is used to prevent application closing when application is closeable and there is
+ // incoming call. This flag is also used when closeable application is on front and there is a
+ // timeout to block the application.
};
- /// this is only to force usage of get/set methods in ApplicatioManager
- class VirtualAppManager
+ class ApplicationManagerBase
{
public:
+ using ApplicationsContainer = std::vector<std::unique_ptr<ApplicationHandle>>;
+ using ApplicationsStack = std::deque<ApplicationHandle::Name>;
enum class State
{
- IDLE,
- CLOSING_PREV_APP,
- WAITING_CLOSE_CONFIRMATION,
- STARTING_NEW_APP,
- WAITING_NEW_APP_REGISTRATION,
- WAITING_LOST_FOCUS_CONFIRMATION,
- WAITING_GET_FOCUS_CONFIRMATION
+ Running,
+ AwaitingFocusConfirmation,
+ AwaitingCloseConfirmation,
+ AwaitingLostFocusConfirmation
};
- VirtualAppManager(std::vector<std::unique_ptr<app::ApplicationLauncher>> &launchers);
- virtual ~VirtualAppManager();
+ explicit ApplicationManagerBase(std::vector<std::unique_ptr<app::ApplicationLauncher>> &&launchers);
+ virtual ~ApplicationManagerBase() = default;
- private:
- State state = State::IDLE;
- std::list<ApplicationDescription *> applications;
+ void pushApplication(const ApplicationHandle::Name &name);
+ void popApplication();
+ void clearStack();
- public:
- std::list<std::string> appStack;
- State getState()
+ auto getFocusedApplication() const noexcept -> ApplicationHandle *;
+ auto getLaunchingApplication() const noexcept -> ApplicationHandle *;
+ auto getPreviousApplication() const noexcept -> ApplicationHandle *;
+ auto getApplication(const ApplicationHandle::Name &name) const noexcept -> ApplicationHandle *;
+ auto getApplications() const noexcept -> const ApplicationsContainer &
+ {
+ return applications;
+ }
+
+ void setState(State _state) noexcept;
+ auto getState() const noexcept -> State
{
return state;
}
- static const char *stateStr(State st);
- ApplicationDescription *appFront();
- ApplicationDescription *appGet(const std::string &name);
- /// set application as first on the applications vector
- bool appMoveFront(ApplicationDescription *app);
- /// get previous visible app - one on FOREGROUND
- ApplicationDescription *appPrev();
- void setState(State st);
- std::list<ApplicationDescription *> &getApps();
- void debug_log_app_list();
+
+ private:
+ State state = State::Running;
+ ApplicationsContainer applications;
+ ApplicationsStack stack;
};
- class ApplicationManager : public sys::Service, public VirtualAppManager
+ class ApplicationManager : public sys::Service, private ApplicationManagerBase
{
-
- SettingsRecord settings;
-
- sys::SystemManager *systemManager;
-
- //
- std::unique_ptr<utils::i18> i18;
-
- // application that currently has focus. This means that is has rights to display screens and receive keyboard
- // events.
- std::string focusApplicationName = "";
- // after loosing focus application becomes previous application and this is its name
- std::string previousApplicationName = "";
- // name of the application scheduled for launching
- std::string launchApplicationName = "";
- // timer to count time from last user's activity. If it reaches time defined in settings database application
- // manager is sending signal to power manager and changing window to the desktop window in the blocked state.
- std::unique_ptr<sys::Timer> blockingTimer;
-
- // tries to switch the application
- bool handleSwitchApplication(APMSwitch *msg);
- auto handleAction(APMAction *actionMsg) -> bool;
- // bool handleSwitchApplicationWithData( APMSwitchWithData* msg);
- bool handleCloseConfirmation(APMConfirmClose *msg);
- bool handleSwitchConfirmation(APMConfirmSwitch *msg);
- bool handleSwitchPrevApplication(APMSwitchPrevApp *msg);
- bool handleRegisterApplication(APMRegister *msg);
- bool handleLanguageChange(sapm::APMChangeLanguage *msg);
- bool handlePowerSavingModeInit();
- /**
- * @brief Closes all running applications.
- */
- bool startApplication(const std::string &appName);
- /**
- * @brief Closes eink and gui services.
- */
- bool closeApplications();
- bool closeServices();
-
public:
- ApplicationManager(const std::string &name,
- sys::SystemManager *sysmgr,
- std::vector<std::unique_ptr<app::ApplicationLauncher>> &launchers);
- virtual ~ApplicationManager();
+ static inline const std::string ServiceName = "ApplicationManager";
- sys::Message_t DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) override;
+ ApplicationManager(const std::string &serviceName,
+ std::vector<std::unique_ptr<app::ApplicationLauncher>> &&launchers,
+ const ApplicationHandle::Name &_rootApplicationName);
- // Invoked during initialization
- sys::ReturnCodes InitHandler() override;
-
- sys::ReturnCodes DeinitHandler() override;
-
- sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override final;
-
- /**
- * @brief Sends the action request to application manager.
- * @param sender Sender service name.
- * @param action Action request
- * @return true on success, false otherwise.
- */
- static auto sendAction(sys::Service *sender, Action &&action) -> bool;
-
- /**
- * @brief Sends request to application manager to switch from current application to specific window in
- * application with specified name .
- */
- static bool messageSwitchApplication(sys::Service *sender,
- const std::string &applicationName,
- const std::string &windowName,
- std::unique_ptr<gui::SwitchData> data = nullptr);
-
- static bool messageSwitchSpecialInput(sys::Service *sender, std::unique_ptr<gui::SwitchSpecialChar> data);
- /**
- * @brief Sends request to application manager to switch from current application to specific window in
- * application with specified name. Allows sending data to destination application.
- */
- // static bool messageSwitchApplicationWithData( sys::Service* sender, const std::string& applicationName,
- // const std::string& windowName, std::unique_ptr<app::SwitchData>& switchData );
- /**
- * @Brief Function allows sending confirmation to the switch request. This is sent both by application that
- * gains and looses focus.
- */
- static bool messageConfirmSwitch(sys::Service *sender);
- /**
- * @brief Function allows application to confirm close request.
- */
- static bool messageConfirmClose(sys::Service *sender);
- /**
- * @brief Allows requesting Application Manager to run previous application.
- */
- static bool messageSwitchPreviousApplication(sys::Service *sender,
- std::unique_ptr<APMSwitchPrevApp> msg = nullptr);
- /**
- * @brief Sends information from application to manager about result of application's init function.
- * If successful message will contain name and true value, otherwise false value will be transmitted.
- */
- static bool messageRegisterApplication(sys::Service *sender, const bool &status, const bool &startBackground);
- /**
- * @brief Sends message to application manager to inform it about change of the phone's language performed by
- * the user.
- */
- static bool messageChangeLanguage(sys::Service *sender, utils::Lang language);
- /**
- * @brief Sends message to application manager that it should close itself and as a result.
- */
- static bool messageCloseApplicationManager(sys::Service *sender);
- /**
- * @brief Sends message to inform Application Manager to reset timer responsible for blocking phone
- */
- static bool messagePreventBlocking(sys::Service *sender);
- /**
- * @brief Sends message to Application Manager. This will initialize procedure of switching to power saving
- * mode.
- */
- static bool messageInitPowerSaveMode(sys::Service *sender);
-
- /**
- * @brief Sends message to Application Manager.
- *
- * \returns true if app manager running and app is registered == running, false othervise
- */
- static bool appRunning(sys::Service *sender, const std::string &name);
+ auto InitHandler() -> sys::ReturnCodes override;
+ auto DeinitHandler() -> sys::ReturnCodes override;
+ auto SwitchPowerModeHandler(const sys::ServicePowerMode mode) -> sys::ReturnCodes override;
+ auto DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) -> sys::Message_t override;
private:
- void phoneLockCB();
+ auto startApplication(ApplicationHandle &app) -> bool;
+ void startSystemServices();
+ void startBackgroundApplications();
+ void rebuildActiveApplications();
+ void suspendSystemServices();
+ auto closeServices() -> bool;
+ auto closeApplications() -> bool;
+ void closeService(const std::string &name);
+
+ // Message handlers
+ void registerMessageHandlers();
+ auto handleAction(APMAction *actionMsg) -> bool;
+ auto handleSwitchApplication(APMSwitch *msg) -> bool;
+ auto handleCloseConfirmation(APMConfirmClose *msg) -> bool;
+ auto handleSwitchConfirmation(APMConfirmSwitch *msg) -> bool;
+ auto handleSwitchBack(APMSwitchPrevApp *msg) -> bool;
+ auto handleRegisterApplication(APMRegister *msg) -> bool;
+ auto handleLanguageChange(APMChangeLanguage *msg) -> bool;
+ auto handlePowerSavingModeInit() -> bool;
+
+ void requestApplicationClose(ApplicationHandle &app, bool isCloseable);
+ void onApplicationSwitch(ApplicationHandle &app,
+ std::unique_ptr<gui::SwitchData> &&data,
+ std::string targetWindow);
+ void onApplicationSwitchToPrev(ApplicationHandle &previousApp,
+ std::unique_ptr<gui::SwitchData> &&data,
+ std::string targetWindow = {});
+ void onApplicationRegistered(ApplicationHandle &app, bool startInBackground);
+ void onApplicationRegistrationFailure(ApplicationHandle &app);
+ auto onSwitchConfirmed(ApplicationHandle &app) -> bool;
+ auto onCloseConfirmed(ApplicationHandle &app) -> bool;
+ void onPhoneLocked();
+
+ ApplicationHandle::Name rootApplicationName;
+ SettingsRecord settings;
+ std::unique_ptr<sys::Timer> blockingTimer; //< timer to count time from last user's activity. If it reaches time
+ // defined in settings database application
+ // manager is sending signal to power manager and changing window to
+ // the desktop window in the blocked state.
};
-
-} /* namespace sapm */
-
-#endif /* MODULE_SERVICES_SERVICE_APPMGR_APPLICATIONMANAGER_HPP_ */
+} // namespace app::manager
M module-services/service-appmgr/CMakeLists.txt => module-services/service-appmgr/CMakeLists.txt +6 -9
@@ 1,25 1,22 @@
-include_directories( ${CMAKE_PROJECT_NAME}
-
+include_directories(${CMAKE_PROJECT_NAME}
PUBLIC
"${CMAKE_CURRENT_LIST_DIR}"
-# "${CMAKE_CURRENT_LIST_DIR}/messages"
)
-include_directories( ${PROJECT_NAME}
-
+include_directories(${PROJECT_NAME}
PUBLIC
"${CMAKE_CURRENT_LIST_DIR}"
"${CMAKE_CURRENT_LIST_DIR}/.."
-# "${CMAKE_CURRENT_LIST_DIR}/messages"
)
-message( "${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}" )
-
-target_sources( ${PROJECT_NAME}
+message("${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}")
+target_sources(${PROJECT_NAME}
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/ApplicationManager.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/Controller.cpp"
PUBLIC
"${CMAKE_CURRENT_LIST_DIR}/ApplicationManager.hpp"
+ "${CMAKE_CURRENT_LIST_DIR}/Controller.hpp"
)
A module-services/service-appmgr/Controller.cpp => module-services/service-appmgr/Controller.cpp +82 -0
@@ 0,0 1,82 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "Controller.hpp"
+
+#include "module-sys/Service/Bus.hpp"
+
+namespace app::manager
+{
+ auto Controller::registerApplication(sys::Service *sender, bool status, bool startBackground) -> bool
+ {
+ auto msg = std::make_shared<app::manager::APMRegister>(sender->GetName(), status, startBackground);
+ return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
+ }
+
+ auto Controller::sendAction(sys::Service *sender, Action &&action) -> bool
+ {
+ auto msg = std::make_shared<app::manager::APMAction>(sender->GetName(), std::move(action));
+ return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
+ }
+
+ auto Controller::switchApplication(sys::Service *sender,
+ const ApplicationHandle::Name &applicationName,
+ const std::string &windowName,
+ std::unique_ptr<gui::SwitchData> data) -> bool
+ {
+ auto msg =
+ std::make_shared<app::manager::APMSwitch>(sender->GetName(), applicationName, windowName, std::move(data));
+ return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
+ }
+
+ auto Controller::confirmSwitch(sys::Service *sender) -> bool
+ {
+
+ auto msg = std::make_shared<app::manager::APMConfirmSwitch>(sender->GetName());
+ return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
+ }
+
+ auto Controller::confirmClose(sys::Service *sender) -> bool
+ {
+ auto msg = std::make_shared<app::manager::APMConfirmClose>(sender->GetName());
+ return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
+ }
+
+ auto Controller::closeApplication(sys::Service *sender, const ApplicationHandle::Name &name) -> bool
+ {
+ auto msg = std::make_shared<app::manager::APMDelayedClose>(sender->GetName(), name);
+ return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
+ }
+
+ auto Controller::switchBack(sys::Service *sender, std::unique_ptr<APMSwitchPrevApp> msg) -> bool
+ {
+
+ std::shared_ptr<APMSwitchPrevApp> switchMsg =
+ msg ? std::move(msg) : std::make_shared<app::manager::APMSwitchPrevApp>(sender->GetName());
+ return sys::Bus::SendUnicast(switchMsg, ApplicationManager::ServiceName, sender);
+ }
+
+ auto Controller::changeLanguage(sys::Service *sender, utils::Lang language) -> bool
+ {
+ auto msg = std::make_shared<app::manager::APMChangeLanguage>(sender->GetName(), language);
+ return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
+ }
+
+ auto Controller::stopApplicationManager(sys::Service *sender) -> bool
+ {
+ auto msg = std::make_shared<app::manager::APMClose>(sender->GetName());
+ return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
+ }
+
+ auto Controller::preventBlockingDevice(sys::Service *sender) -> bool
+ {
+ auto msg = std::make_shared<app::manager::APMPreventBlocking>(sender->GetName());
+ return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
+ }
+
+ auto Controller::changePowerSaveMode(sys::Service *sender) -> bool
+ {
+ auto msg = std::make_shared<app::manager::APMInitPowerSaveMode>(sender->GetName());
+ return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
+ }
+} // namespace app::manager
A module-services/service-appmgr/Controller.hpp => module-services/service-appmgr/Controller.hpp +32 -0
@@ 0,0 1,32 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "ApplicationManager.hpp"
+
+#include "module-sys/Service/Service.hpp"
+
+namespace app::manager
+{
+ class Controller
+ {
+ public:
+ Controller() = delete;
+
+ static auto sendAction(sys::Service *sender, Action &&action) -> bool;
+ static auto registerApplication(sys::Service *sender, bool status, bool startBackground) -> bool;
+ static auto switchApplication(sys::Service *sender,
+ const ApplicationHandle::Name &applicationName,
+ const std::string &windowName,
+ std::unique_ptr<gui::SwitchData> data = nullptr) -> bool;
+ static auto switchBack(sys::Service *sender, std::unique_ptr<APMSwitchPrevApp> msg = nullptr) -> bool;
+ static auto closeApplication(sys::Service *sender, const ApplicationHandle::Name &name) -> bool;
+ static auto changeLanguage(sys::Service *sender, utils::Lang language) -> bool;
+ static auto changePowerSaveMode(sys::Service *sender) -> bool;
+ static auto stopApplicationManager(sys::Service *sender) -> bool;
+ static auto preventBlockingDevice(sys::Service *sender) -> bool;
+ static auto confirmSwitch(sys::Service *sender) -> bool;
+ static auto confirmClose(sys::Service *sender) -> bool;
+ };
+} // namespace app::manager
M module-services/service-appmgr/messages/APMMessage.hpp => module-services/service-appmgr/messages/APMMessage.hpp +52 -50
@@ 1,8 1,7 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#ifndef MODULE_SERVICES_SERVICE_APPMGR_MESSAGES_APMMESSAGE_HPP_
-#define MODULE_SERVICES_SERVICE_APPMGR_MESSAGES_APMMESSAGE_HPP_
+#pragma once
#include "Service/Message.hpp"
#include "MessageType.hpp"
@@ 11,36 10,27 @@
#include "i18/i18.hpp"
-namespace sapm
+namespace app::manager
{
-
- /*
- * @brief Template for all messages that go to application manager
- */
+ /// A template for all messages to application manager.
class APMMessage : public sys::DataMessage
{
protected:
- // name of the application that is sending message to application manager.
+ /// name of the application that is sending message to application manager.
std::string senderName;
public:
- APMMessage(MessageType messageType, const std::string &senderName)
- : sys::DataMessage(messageType), senderName{senderName} {};
- virtual ~APMMessage(){};
+ APMMessage(MessageType messageType, std::string senderName)
+ : sys::DataMessage(messageType), senderName{std::move(senderName)}
+ {}
- std::string getSenderName()
+ [[nodiscard]] auto getSenderName() const noexcept -> std::string
{
return senderName;
}
};
- // APMSwitch, //request to switch to given application, optionally also to specified window
- // APMSwitchToNotification, //request to switch to given notification (application and specified window)
- // APMSwitchData, //request to switch to given application, optionally also to specified window with provided data.
- // APMSwitchPrevApp, //Request to switch to previous application.
- // APMConfirmSwitch, //Used when application confirms that it is loosing focus and also when application confirms
- // that is has gained focus APMConfirmClose, //Sent by application to confirm completion of the close procedure
-
+ /// Requests a switch to a given application. Optionally to a specified window, too.
class APMSwitch : public APMMessage
{
std::string application;
@@ 49,26 39,30 @@ namespace sapm
public:
APMSwitch(const std::string &senderName,
- const std::string &applicationName,
- const std::string &windowName,
+ std::string applicationName,
+ std::string windowName,
std::unique_ptr<gui::SwitchData> data)
: APMMessage(MessageType::APMSwitch, senderName),
- application{applicationName}, window{windowName}, data{std::move(data)}
+ application{std::move(applicationName)}, window{std::move(windowName)}, data{std::move(data)}
{}
- const std::string &getName() const
+
+ [[nodiscard]] auto getName() const noexcept -> const std::string &
{
return application;
- };
- const std::string &getWindow() const
+ }
+
+ [[nodiscard]] auto getWindow() const noexcept -> const std::string &
{
return window;
- };
- std::unique_ptr<gui::SwitchData> &getData()
+ }
+
+ [[nodiscard]] auto getData() noexcept -> std::unique_ptr<gui::SwitchData> &
{
return data;
- };
+ }
};
+ /// Requests a switch to a previous application.
class APMSwitchPrevApp : public APMMessage
{
std::unique_ptr<gui::SwitchData> data;
@@ 77,12 71,14 @@ namespace sapm
APMSwitchPrevApp(const std::string &name, std::unique_ptr<gui::SwitchData> data = nullptr)
: APMMessage(MessageType::APMSwitchPrevApp, name), data{std::move(data)}
{}
- std::unique_ptr<gui::SwitchData> &getData()
+
+ [[nodiscard]] auto getData() noexcept -> std::unique_ptr<gui::SwitchData> &
{
return data;
- };
+ }
};
+ /// Confirms that the applications lost/gained focus.
class APMConfirmSwitch : public APMMessage
{
public:
@@ 90,6 86,7 @@ namespace sapm
{}
};
+ /// Confirms that the application closed successfully.
class APMConfirmClose : public APMMessage
{
public:
@@ 97,46 94,47 @@ namespace sapm
{}
};
+ /// Confirms that the application registered successfully.
class APMRegister : public APMMessage
{
- protected:
bool status;
bool startBackground;
public:
- APMRegister(const std::string &senderName, const bool &status, const bool &startBackground)
+ APMRegister(const std::string &senderName, bool status, bool startBackground)
: APMMessage(MessageType::APMRegister, senderName), status{status}, startBackground{startBackground}
{}
- const bool &getStatus()
+ [[nodiscard]] auto getStatus() const noexcept -> bool
{
return status;
- };
- const bool &getStartBackground()
+ }
+
+ [[nodiscard]] auto getStartBackground() const noexcept -> bool
{
return startBackground;
- };
+ }
};
+ /// Requests the application to close.
class APMDelayedClose : public APMMessage
{
- protected:
std::string application;
public:
APMDelayedClose(const std::string &senderName, std::string application)
- : APMMessage(MessageType::APMDeleydClose, senderName), application{application}
+ : APMMessage(MessageType::APMDelayedClose, senderName), application{std::move(application)}
{}
- const std::string &getApplication()
+ [[nodiscard]] auto getApplication() const noexcept -> const std::string &
{
return application;
- };
+ }
};
+ /// Requests to change the language.
class APMChangeLanguage : public APMMessage
{
- protected:
utils::Lang language;
public:
@@ 144,12 142,13 @@ namespace sapm
: APMMessage(MessageType::APMChangeLanguage, senderName), language{language}
{}
- const utils::Lang &getLanguage()
+ [[nodiscard]] auto getLanguage() const noexcept -> utils::Lang
{
return language;
- };
+ }
};
+ /// Requests the application manager to close.
class APMClose : public APMMessage
{
public:
@@ 157,6 156,7 @@ namespace sapm
{}
};
+ /// Requests application manager to prevent device blocking.
class APMPreventBlocking : public APMMessage
{
public:
@@ 164,6 164,7 @@ namespace sapm
{}
};
+ /// Requests the application manager to enter power save mode.
class APMInitPowerSaveMode : public APMMessage
{
public:
@@ 171,14 172,17 @@ namespace sapm
{}
};
+ /// Requests the application manager to check the status of the application.
class APMCheckApp : public APMMessage
{
public:
- APMCheckApp(const std::string &senderName, const std::string &appNameToCheck)
- : APMMessage(MessageType::APMCheckAppRunning, senderName), appNameToCheck(appNameToCheck)
+ APMCheckApp(const std::string &senderName, std::string applicationName)
+ : APMMessage(MessageType::APMCheckAppRunning, senderName),
+ checkAppName(std::move(applicationName)), isRunning{false}
{}
- const std::string appNameToCheck;
- bool isRunning = false;
+
+ std::string checkAppName;
+ bool isRunning;
};
struct Action
@@ 203,6 207,4 @@ namespace sapm
private:
Action action;
};
-} /* namespace sapm */
-
-#endif /* MODULE_SERVICES_SERVICE_APPMGR_MESSAGES_APMMESSAGE_HPP_ */
+} // namespace app::manager
M module-services/service-evtmgr/EventManager.cpp => module-services/service-evtmgr/EventManager.cpp +2 -2
@@ 19,7 19,7 @@
#include "vfs.hpp"
#include "bsp/battery-charger/battery_charger.hpp"
-#include "service-appmgr/ApplicationManager.hpp"
+#include "service-appmgr/Controller.hpp"
#include "service-db/api/DBServiceAPI.hpp"
#include "service-db/messages/DBNotificationMessage.hpp"
#include "AudioServiceAPI.hpp"
@@ 98,7 98,7 @@ sys::Message_t EventManager::DataReceivedHandler(sys::DataMessage *msgl, sys::Re
sys::Bus::SendUnicast(message, targetApplication, this);
}
// notify application manager to prevent screen locking
- sapm::ApplicationManager::messagePreventBlocking(this);
+ app::manager::Controller::preventBlockingDevice(this);
handled = true;
}
else if (msgl->messageType == MessageType::EVMFocusApplication) {
M module-services/service-evtmgr/alarm/EventManagerAlarm.cpp => module-services/service-evtmgr/alarm/EventManagerAlarm.cpp +2 -2
@@ 19,7 19,7 @@
#include "vfs.hpp"
#include "service-db/api/DBServiceAPI.hpp"
-#include "service-appmgr/ApplicationManager.hpp"
+#include "service-appmgr/Controller.hpp"
void EventManager::HandleAlarmTrigger(sys::DataMessage *msgl)
{
@@ 55,7 55,7 @@ void EventManager::HandleAlarmTrigger(sys::DataMessage *msgl)
alarmIsValid = false;
// run bell application
std::unique_ptr<gui::SwitchData> switchMessage = std::make_unique<sevm::EVMAlarmSwitchData>(alarmID);
- sapm::ApplicationManager::messageSwitchApplication(this, "bell", "main", std::move(switchMessage));
+ app::manager::Controller::switchApplication(this, "bell", "main", std::move(switchMessage));
}
// check if alarm is not obsolete
else if ((alarmTimestamp < (currentTime % 86400)) && ((currentTime + 60) % 86400) > (currentTime % 86400)) {
M module-services/service-gui/ServiceGUI.cpp => module-services/service-gui/ServiceGUI.cpp +2 -2
@@ 19,7 19,7 @@
#include "service-eink/messages/ImageMessage.hpp"
#include "ServiceGUI.hpp"
-#include "service-appmgr/ApplicationManager.hpp"
+#include "service-appmgr/Controller.hpp"
#include "../gui/core/ImageManager.hpp"
#include "log/log.hpp"
@@ 198,7 198,7 @@ namespace sgui
suspendInProgress = false;
LOG_DEBUG("last rendering before suspend is finished.");
- sapm::ApplicationManager::messageInitPowerSaveMode(this);
+ app::manager::Controller::changePowerSaveMode(this);
}
// mode = gui::RefreshModes::GUI_REFRESH_FAST;
// check if something new was rendered. If so render counter has greater value than
M module-services/service-time/timeEvents/CalendarTimeEvents.cpp => module-services/service-time/timeEvents/CalendarTimeEvents.cpp +2 -2
@@ 3,7 3,7 @@
#include "CalendarTimeEvents.hpp"
-#include <module-services/service-appmgr/ApplicationManager.hpp>
+#include <module-services/service-appmgr/Controller.hpp>
#include <module-services/service-db/api/DBServiceAPI.hpp>
#include <module-services/service-db/messages/DBNotificationMessage.hpp>
#include <module-db/queries/calendar/QueryEventsSelectFirstUpcoming.hpp>
@@ 71,7 71,7 @@ namespace stm
auto event = std::make_shared<EventsRecord>(eventRecord);
eventData->setData(event);
- sapm::ApplicationManager::messageSwitchApplication(
+ app::manager::Controller::switchApplication(
service(), app::name_calendar, style::window::calendar::name::event_reminder_window, std::move(eventData));
}
} // namespace stm
M source/MessageType.hpp => source/MessageType.hpp +14 -13
@@ 125,19 125,19 @@ enum class MessageType
AudioMessage,
// application manager
- APMAction, ///< Used to send an action request to application manager.
- APMCheckAppRunning, ///< check if application is running in application manager
- APMSwitch, ///< request to switch to given application, optionally also to specified window
- APMSwitchToNotification, ///< request to switch to given notification (application and specified window)
- APMSwitchPrevApp, ///< Request to switch to previous application.
- APMConfirmSwitch, ///< Used when application confirms that it is loosing focus and also when application confirms
- ///< that is has gained focus
- APMConfirmClose, ///< Sent by application to confirm completion of the close procedure
- APMRegister, ///< when application finishes initHandler it is sending this messag to inform whether init was
- ///< successful or not.
- APMDeleydClose, ///< this message is sent internally from and to application manager to close specified application.
- APMChangeLanguage, ///< this message is sent from any application to inform application manager that it should send
- ///< gui rebuild command to all applications in background and currently active application.
+ APMAction, ///< Used to send an action request to application manager.
+ APMCheckAppRunning, ///< check if application is running in application manager
+ APMSwitch, ///< request to switch to given application, optionally also to specified window
+ APMSwitchPrevApp, ///< Request to switch to previous application.
+ APMConfirmSwitch, ///< Used when application confirms that it is loosing focus and also when application confirms
+ ///< that is has gained focus
+ APMConfirmClose, ///< Sent by application to confirm completion of the close procedure
+ APMRegister, ///< when application finishes initHandler it is sending this messag to inform whether init was
+ ///< successful or not.
+ APMDelayedClose, ///< this message is sent internally from and to application manager to close specified
+ ///< application.
+ APMChangeLanguage, ///< this message is sent from any application to inform application manager that it should send
+ ///< gui rebuild command to all applications in background and currently active application.
APMClose, ///< this message will trigger application manager to close itself, all running applications gui and eink
///< services.
APMPreventBlocking, ///< Prevents application manager from initializing device blocking.
@@ 156,6 156,7 @@ enum class MessageType
///< by the user)
AppClose,
AppFocus,
+ AppFocusLost,
EVMFocusApplication,
EVMKeyboardProfile,
M source/main.cpp => source/main.cpp +3 -1
@@ 143,7 143,9 @@ int main()
// start application manager
ret &= sysmgr->CreateService(
- std::make_shared<sapm::ApplicationManager>("ApplicationManager", sysmgr.get(), applications), sysmgr.get());
+ std::make_shared<app::manager::ApplicationManager>(
+ app::manager::ApplicationManager::ServiceName, std::move(applications), app::name_desktop),
+ sysmgr.get());
return ret;
});