From 4f0c3c82afe3811fa66c9110038b946c6d903d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ta=C5=84ski?= Date: Thu, 18 Mar 2021 10:40:23 +0100 Subject: [PATCH] [EGD-6209] Tethering confirmation popup added Provided a tethering confirmation popup. The popup shows up once a USB cable is connected to a PC. --- enabled_unittests | 1 + image/assets/lang/English.json | 4 +- module-apps/Application.cpp | 36 ++++++++++++- module-apps/Application.hpp | 22 +++++++- module-apps/CMakeLists.txt | 2 + .../ApplicationAlarmClock.cpp | 2 +- .../ApplicationAntenna.cpp | 2 +- .../ApplicationCalculator.cpp | 2 +- .../ApplicationCalendar.cpp | 2 +- .../application-call/ApplicationCall.cpp | 7 ++- .../application-call/ApplicationCall.hpp | 1 + .../ApplicationCallLog.cpp | 2 +- .../application-clock/ApplicationClock.cpp | 2 +- .../ApplicationDesktop.cpp | 2 +- .../ApplicationMeditation.cpp | 2 +- .../windows/MeditationTimerWindow.cpp | 1 - .../ApplicationMessages.cpp | 2 +- .../ApplicationMusicPlayer.cpp | 2 +- .../application-notes/ApplicationNotes.cpp | 2 +- .../ApplicationOnBoarding.cpp | 2 +- .../ApplicationPhonebook.cpp | 2 +- .../ApplicationSettings.cpp | 3 +- .../ApplicationSettings.cpp | 2 +- module-apps/popups/Popups.cpp | 22 ++++++++ module-apps/popups/Popups.hpp | 4 ++ .../popups/TetheringConfirmationPopup.cpp | 32 +++++++++++ .../popups/TetheringConfirmationPopup.hpp | 19 +++++++ module-apps/popups/VolumeWindow.cpp | 1 + module-apps/popups/VolumeWindow.hpp | 13 ++++- .../service-appmgr/model/ActionsRegistry.cpp | 18 +++++-- .../model/ApplicationManager.cpp | 53 +++++++++++++------ .../service-appmgr/service-appmgr/Actions.hpp | 2 + .../service-appmgr/model/ActionsRegistry.hpp | 11 +++- .../model/ApplicationManager.hpp | 9 ++-- .../tests/test-ActionsRegistry.cpp | 50 +++++++++++++---- .../service-desktop/ServiceDesktop.cpp | 3 ++ module-sys/PhoneModes/Subject.cpp | 18 ++++--- module-sys/PhoneModes/Subject.hpp | 24 +++++++-- module-sys/SystemManager/SystemManager.cpp | 24 ++++++++- module-sys/SystemManager/SystemManager.hpp | 2 + .../messages/TetheringQuestionRequest.hpp | 43 +++++++++++++++ 41 files changed, 387 insertions(+), 66 deletions(-) create mode 100644 module-apps/popups/Popups.cpp create mode 100644 module-apps/popups/TetheringConfirmationPopup.cpp create mode 100644 module-apps/popups/TetheringConfirmationPopup.hpp create mode 100644 module-sys/SystemManager/messages/TetheringQuestionRequest.hpp diff --git a/enabled_unittests b/enabled_unittests index a7c968d111567fac2c4fe73d0b025ef98a922323..15b2cac3c03b7c8e55b3745a80e8bd67809e4e95 100644 --- a/enabled_unittests +++ b/enabled_unittests @@ -25,6 +25,7 @@ TESTS_LIST["catch2-actions-registry-tests"]=" Given actions registry when enqueue multiple actions at once then count handled actions; Given actions registry when enqueue multiple actions at once then wait for them to expire.; Given actions registry when enqueue multiple actions at once then process the specific ones only.; + Process the specific actions only and skip others.; " #--------- TESTS_LIST["catch2-audio-test"]=" diff --git a/image/assets/lang/English.json b/image/assets/lang/English.json index 30f75a4cf51ff83bcfd1ac105be46080b0ae043b..1b7bb494c93c7caef48f6f26bac22c6d54616f9e 100644 --- a/image/assets/lang/English.json +++ b/image/assets/lang/English.json @@ -578,5 +578,7 @@ "app_desktop_update_in_progress": "Update in progress...", "app_desktop_update_ready_for_reset": "Ready for reset...", "app_desktop_update_success": "MuditaOS has been updated to ver. $VERSION succesfully.", - "app_call_private_number": "Private number" + "app_call_private_number": "Private number", + "tethering": "Tethering", + "tethering_enable_question": "You're connected to the computer.
Turn tethering on?
(some functions may be disabled)
" } diff --git a/module-apps/Application.cpp b/module-apps/Application.cpp index 4a9c44bd763e9185fe730e830efa0c36b0fa933c..ae59901f7769ec2ce2a4eaa623c14399081f95e8 100644 --- a/module-apps/Application.cpp +++ b/module-apps/Application.cpp @@ -8,6 +8,7 @@ #include "MessageType.hpp" // for MessageType #include "module-sys/Timers/TimerFactory.hpp" // for Timer #include "TopBar.hpp" +#include "popups/TetheringConfirmationPopup.hpp" #include "Translator.hpp" // for KeyInputSim... #include "common_data/EventStore.hpp" // for Battery #include "common_data/RawKey.hpp" // for RawKey, key... @@ -115,6 +116,20 @@ namespace app [&](sys::phone_modes::PhoneMode phoneMode, sys::phone_modes::Tethering tetheringMode) { handlePhoneModeChanged(phoneMode, tetheringMode); }); + + addActionReceiver(app::manager::actions::ShowPopup, [this](auto &¶ms) { + auto popupParams = static_cast(params.get()); + if (const auto popupId = popupParams->getPopupId(); isPopupPermitted(popupId)) { + switchWindow(gui::popup::resolveWindowName(popupId)); + } + return actionHandled(); + }); + addActionReceiver(app::manager::actions::AbortPopup, [this](auto &¶ms) { + auto popupParams = static_cast(params.get()); + const auto popupId = popupParams->getPopupId(); + abortPopup(popupId); + return actionHandled(); + }); } Application::~Application() noexcept @@ -647,7 +662,6 @@ namespace app void Application::messageCloseApplication(sys::Service *sender, std::string application) { - auto msg = std::make_shared(MessageType::AppClose); sender->bus.sendUnicast(msg, application); } @@ -698,6 +712,13 @@ namespace app return std::make_unique(app, window::volume_window); }); break; + case ID::Tethering: + windowsFactory.attach(window::tethering_confirmation_window, + [](Application *app, const std::string &name) { + return std::make_unique( + app, window::tethering_confirmation_window); + }); + break; case ID::PhoneModes: windowsFactory.attach(window::phone_modes_window, [](Application *app, const std::string &name) { return std::make_unique(app, window::phone_modes_window); @@ -709,6 +730,19 @@ namespace app } } + void Application::abortPopup(gui::popup::ID id) + { + const auto popupName = gui::popup::resolveWindowName(id); + if (getCurrentWindow()->getName() == popupName) { + returnToPreviousWindow(); + } + } + + bool Application::isPopupPermitted([[maybe_unused]] gui::popup::ID popupId) const + { + return true; + } + bool Application::popToWindow(const std::string &window) { if (window == gui::name::window::no_window) { diff --git a/module-apps/Application.hpp b/module-apps/Application.hpp index 5b9a123537670913e7491cd8c7221e1af11f9b45..4da881541c454cc026a300166f08600d56bce99c 100644 --- a/module-apps/Application.hpp +++ b/module-apps/Application.hpp @@ -31,6 +31,7 @@ #include "popups/Popups.hpp" #include "WindowsFactory.hpp" #include "WindowsStack.hpp" +#include "Popups.hpp" namespace app { @@ -176,6 +177,8 @@ namespace app sys::MessagePointer handleSIMMessage(sys::Message *msgl); sys::MessagePointer handleAudioKeyMessage(sys::Message *msgl); + virtual bool isPopupPermitted(gui::popup::ID popupId) const; + std::list> gui_timers; std::unordered_map receivers; @@ -331,6 +334,7 @@ namespace app /// Method used to attach popups windows to application void attachPopups(const std::vector &popupsList); + void abortPopup(gui::popup::ID id); public: /// @ingrup AppWindowStack @@ -399,7 +403,7 @@ namespace app class ApplicationLaunchData : public manager::actions::ActionParams { public: - ApplicationLaunchData(const app::ApplicationName &appName) + explicit ApplicationLaunchData(const app::ApplicationName &appName) : manager::actions::ActionParams{"Application launch parameters"}, targetAppName{appName} {} @@ -411,4 +415,20 @@ namespace app private: ApplicationName targetAppName; }; + + class PopupRequestParams : public manager::actions::ActionParams + { + public: + explicit PopupRequestParams(gui::popup::ID popupId) + : manager::actions::ActionParams{"Popup request parameters"}, popupId{popupId} + {} + + [[nodiscard]] auto getPopupId() const noexcept + { + return popupId; + } + + private: + gui::popup::ID popupId; + }; } /* namespace app */ diff --git a/module-apps/CMakeLists.txt b/module-apps/CMakeLists.txt index 1ba5a93e80c24362397c980106e6d1062c624bf1..770be9e276766da28009dbd46260dc07697b8c86 100644 --- a/module-apps/CMakeLists.txt +++ b/module-apps/CMakeLists.txt @@ -28,9 +28,11 @@ set( SOURCES "windows/NoEvents.cpp" "widgets/ButtonOnOff.cpp" "widgets/InputBox.cpp" + "popups/Popups.cpp" "popups/VolumeWindow.cpp" "popups/WindowWithTimer.cpp" "popups/HomeModesWindow.cpp" + "popups/TetheringConfirmationPopup.cpp" "windows/BrightnessWindow.cpp" "widgets/BrightnessBox.cpp" "widgets/ModesBox.cpp" diff --git a/module-apps/application-alarm-clock/ApplicationAlarmClock.cpp b/module-apps/application-alarm-clock/ApplicationAlarmClock.cpp index da5607b7868c16ba4d9eed971e9c222a3d2c16e2..ad79cb46cf9794c84d2c51b374c7d9bf14304b22 100644 --- a/module-apps/application-alarm-clock/ApplicationAlarmClock.cpp +++ b/module-apps/application-alarm-clock/ApplicationAlarmClock.cpp @@ -108,7 +108,7 @@ namespace app style::alarmClock::window::name::dialogYesNo, [](Application *app, const std::string &name) { return std::make_unique(app, name); }); - attachPopups({gui::popup::ID::Volume, gui::popup::ID::PhoneModes}); + attachPopups({gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes}); } void ApplicationAlarmClock::destroyUserInterface() diff --git a/module-apps/application-antenna/ApplicationAntenna.cpp b/module-apps/application-antenna/ApplicationAntenna.cpp index ea1192514169ad38a026c295bd3c6568fd32e345..e68d62067970c58e7110db8b6a8822a939ca405b 100644 --- a/module-apps/application-antenna/ApplicationAntenna.cpp +++ b/module-apps/application-antenna/ApplicationAntenna.cpp @@ -178,7 +178,7 @@ namespace app return std::make_unique(app); }); - attachPopups({gui::popup::ID::Volume, gui::popup::ID::PhoneModes}); + attachPopups({gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes}); } void ApplicationAntenna::destroyUserInterface() diff --git a/module-apps/application-calculator/ApplicationCalculator.cpp b/module-apps/application-calculator/ApplicationCalculator.cpp index e707babbd97db9e6d0a5bf6af279a13d67ed3b45..2518243ae19ee676c1b6537cfa1c0a813fbcc595 100644 --- a/module-apps/application-calculator/ApplicationCalculator.cpp +++ b/module-apps/application-calculator/ApplicationCalculator.cpp @@ -43,7 +43,7 @@ namespace app return std::make_unique(app, name); }); - attachPopups({gui::popup::ID::Volume, gui::popup::ID::PhoneModes}); + attachPopups({gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes}); } void ApplicationCalculator::destroyUserInterface() diff --git a/module-apps/application-calendar/ApplicationCalendar.cpp b/module-apps/application-calendar/ApplicationCalendar.cpp index bd9e6c745176d15f5a044331b6cd6fd8ae18b177..47a0762deeb97c81f9a34815c19583dbd1c7498b 100644 --- a/module-apps/application-calendar/ApplicationCalendar.cpp +++ b/module-apps/application-calendar/ApplicationCalendar.cpp @@ -143,7 +143,7 @@ namespace app return std::make_unique(app, event_reminder_window); }); - attachPopups({gui::popup::ID::Volume, gui::popup::ID::PhoneModes}); + attachPopups({gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes}); } void ApplicationCalendar::destroyUserInterface() diff --git a/module-apps/application-call/ApplicationCall.cpp b/module-apps/application-call/ApplicationCall.cpp index dc024b8d67785edcd748785f4d3c24b2738ae07b..6a63aab2948080fe62311abc2e0dffacce197f19 100644 --- a/module-apps/application-call/ApplicationCall.cpp +++ b/module-apps/application-call/ApplicationCall.cpp @@ -84,6 +84,11 @@ namespace app }); } + bool ApplicationCall::isPopupPermitted(gui::popup::ID popupId) const + { + return getState() == call::State::IDLE; + } + // number of seconds after end call to switch back to previous application const inline utils::time::Duration delayToSwitchToPreviousApp = 3; @@ -232,7 +237,7 @@ namespace app windowsFactory.attach(app::window::name_dialogConfirm, [](Application *app, const std::string &name) { return std::make_unique(app, name); }); - attachPopups({gui::popup::ID::Volume, gui::popup::ID::PhoneModes}); + attachPopups({gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes}); } bool ApplicationCall::showNotification(std::function action, diff --git a/module-apps/application-call/ApplicationCall.hpp b/module-apps/application-call/ApplicationCall.hpp index 6ac39c9564328b77188ba24a22d8ee222638fd8e..9073a5d8fade79dd58e4fa7ca6390e7c6b635b6e 100644 --- a/module-apps/application-call/ApplicationCall.hpp +++ b/module-apps/application-call/ApplicationCall.hpp @@ -86,6 +86,7 @@ namespace app sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) override; sys::ReturnCodes InitHandler() override; sys::ReturnCodes DeinitHandler() override; + bool isPopupPermitted(gui::popup::ID popupId) const override; sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override final { diff --git a/module-apps/application-calllog/ApplicationCallLog.cpp b/module-apps/application-calllog/ApplicationCallLog.cpp index 9577c3d50232fd48e0103ab16ee4cb5de700d1ca..e82842576782c5791d4b400dd8b165d28e17b8df 100644 --- a/module-apps/application-calllog/ApplicationCallLog.cpp +++ b/module-apps/application-calllog/ApplicationCallLog.cpp @@ -98,7 +98,7 @@ namespace app return std::make_unique(app, name); }); - attachPopups({gui::popup::ID::Volume, gui::popup::ID::PhoneModes}); + attachPopups({gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes}); } void ApplicationCallLog::destroyUserInterface() diff --git a/module-apps/application-clock/ApplicationClock.cpp b/module-apps/application-clock/ApplicationClock.cpp index 4dc51de45747de8fced55be70862f1c963fe9f2a..14a5a720e3940ca61ad293d00cebc1d0cdfb6ea5 100644 --- a/module-apps/application-clock/ApplicationClock.cpp +++ b/module-apps/application-clock/ApplicationClock.cpp @@ -86,7 +86,7 @@ namespace app return std::make_unique(app, name); }); - attachPopups({gui::popup::ID::Volume, gui::popup::ID::PhoneModes}); + attachPopups({gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes}); } void ApplicationClock::destroyUserInterface() diff --git a/module-apps/application-desktop/ApplicationDesktop.cpp b/module-apps/application-desktop/ApplicationDesktop.cpp index b10a92673c389a4bfe92bf8b3e66e1cec937d225..be33f13054420c709abfce0ac2bf9679a8a1b0ae 100644 --- a/module-apps/application-desktop/ApplicationDesktop.cpp +++ b/module-apps/application-desktop/ApplicationDesktop.cpp @@ -493,7 +493,7 @@ namespace app return std::make_unique(app, desktop_mmi_internal); }); - attachPopups({gui::popup::ID::Volume, gui::popup::ID::PhoneModes}); + attachPopups({gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes}); } void ApplicationDesktop::destroyUserInterface() diff --git a/module-apps/application-meditation/ApplicationMeditation.cpp b/module-apps/application-meditation/ApplicationMeditation.cpp index 4cf58888bfcfedd6567f50a25da5e53cbb78fe8c..c5772558e6d74d50e8be34174bf0f24bc987ed6d 100644 --- a/module-apps/application-meditation/ApplicationMeditation.cpp +++ b/module-apps/application-meditation/ApplicationMeditation.cpp @@ -53,7 +53,7 @@ namespace app return std::make_unique(app); }); - attachPopups({gui::popup::ID::Volume, gui::popup::ID::PhoneModes}); + attachPopups({gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes}); } void ApplicationMeditation::destroyUserInterface() diff --git a/module-apps/application-meditation/windows/MeditationTimerWindow.cpp b/module-apps/application-meditation/windows/MeditationTimerWindow.cpp index d16d41c4c50aa7ac582cabdf4e6f5353c094930f..a849b59f91398a78726cf422a6a778c4b28ae771 100644 --- a/module-apps/application-meditation/windows/MeditationTimerWindow.cpp +++ b/module-apps/application-meditation/windows/MeditationTimerWindow.cpp @@ -75,7 +75,6 @@ void MeditationTimerWindow::onBeforeShow(ShowMode mode, SwitchData *data) timer->start(); application->refreshWindow(RefreshModes::GUI_REFRESH_FAST); }; - timer->registerTimeoutCallback(onPreparation); timer->setCounterVisible(timerData->isCounterEnabled()); timer->reset(timerData->getPreparationTime()); diff --git a/module-apps/application-messages/ApplicationMessages.cpp b/module-apps/application-messages/ApplicationMessages.cpp index b821911671da46973a9fba3855d6a0adec61dd5d..6910a8c7cad082c96b8e081f6e50ec2e353e2ff8 100644 --- a/module-apps/application-messages/ApplicationMessages.cpp +++ b/module-apps/application-messages/ApplicationMessages.cpp @@ -160,7 +160,7 @@ namespace app return std::make_unique(app); }); - attachPopups({gui::popup::ID::Volume, gui::popup::ID::PhoneModes}); + attachPopups({gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes}); } void ApplicationMessages::destroyUserInterface() diff --git a/module-apps/application-music-player/ApplicationMusicPlayer.cpp b/module-apps/application-music-player/ApplicationMusicPlayer.cpp index 22ba98e8469699a37640a3709278d46ec5d2bed5..ee9a30b7ef867f959f76bc5572388ba670a2ec07 100644 --- a/module-apps/application-music-player/ApplicationMusicPlayer.cpp +++ b/module-apps/application-music-player/ApplicationMusicPlayer.cpp @@ -69,7 +69,7 @@ namespace app return std::make_unique(app); }); - attachPopups({gui::popup::ID::Volume, gui::popup::ID::PhoneModes}); + attachPopups({gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes}); } void ApplicationMusicPlayer::destroyUserInterface() diff --git a/module-apps/application-notes/ApplicationNotes.cpp b/module-apps/application-notes/ApplicationNotes.cpp index d9c18a5762d04b23af5108c9628bbaa6615870a0..96495fff452a8e523e31713752b4d05cbd86a88a 100644 --- a/module-apps/application-notes/ApplicationNotes.cpp +++ b/module-apps/application-notes/ApplicationNotes.cpp @@ -122,7 +122,7 @@ namespace app utils::localize.get("app_phonebook_options_title"), [](Application *app, const std::string &name) { return std::make_unique(app, name); }); - attachPopups({gui::popup::ID::Volume, gui::popup::ID::PhoneModes}); + attachPopups({gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes}); } void ApplicationNotes::destroyUserInterface() diff --git a/module-apps/application-onboarding/ApplicationOnBoarding.cpp b/module-apps/application-onboarding/ApplicationOnBoarding.cpp index ba5937b35d7adb71921d26199f3ba3b9f725875e..ab0aa5539bc1b83a119f8a65d254b6117f56a5ee 100644 --- a/module-apps/application-onboarding/ApplicationOnBoarding.cpp +++ b/module-apps/application-onboarding/ApplicationOnBoarding.cpp @@ -139,7 +139,7 @@ namespace app return std::make_unique(app); }); - attachPopups({gui::popup::ID::Volume, gui::popup::ID::PhoneModes}); + attachPopups({gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes}); } void ApplicationOnBoarding::destroyUserInterface() diff --git a/module-apps/application-phonebook/ApplicationPhonebook.cpp b/module-apps/application-phonebook/ApplicationPhonebook.cpp index 3d4c41d7c55cfcf1467072fc85619b7948ff02d8..3f537c94c20049505fee46ed7e2b3df2e2325693 100644 --- a/module-apps/application-phonebook/ApplicationPhonebook.cpp +++ b/module-apps/application-phonebook/ApplicationPhonebook.cpp @@ -147,7 +147,7 @@ namespace app return std::make_unique(app); }); - attachPopups({gui::popup::ID::Volume, gui::popup::ID::PhoneModes}); + attachPopups({gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes}); } void ApplicationPhonebook::destroyUserInterface() diff --git a/module-apps/application-settings-new/ApplicationSettings.cpp b/module-apps/application-settings-new/ApplicationSettings.cpp index 9ac91bfb13dc2d5ad213c7b7e7382c2fac0fe2a3..70bd5794fa89f0809a6560662b9eff1d4b70ff57 100644 --- a/module-apps/application-settings-new/ApplicationSettings.cpp +++ b/module-apps/application-settings-new/ApplicationSettings.cpp @@ -524,8 +524,6 @@ namespace app windowsFactory.attach(gui::window::name::quote_categories, [](Application *app, const std::string &name) { return std::make_unique(app); }); - - attachPopups({gui::popup::ID::Volume}); windowsFactory.attach(gui::window::name::phone_modes, [](Application *app, const std::string &name) { return std::make_unique( app, static_cast(app), static_cast(app)); @@ -539,6 +537,7 @@ namespace app windowsFactory.attach(gui::window::name::connection_frequency, [](Application *app, const std::string &name) { return std::make_unique(app, static_cast(app)); }); + attachPopups({gui::popup::ID::Volume, gui::popup::ID::Tethering}); } void ApplicationSettingsNew::destroyUserInterface() diff --git a/module-apps/application-settings/ApplicationSettings.cpp b/module-apps/application-settings/ApplicationSettings.cpp index 24502c2edbc4c35a4deb1ce818ce87017e0f94fb..9ba522631bc8cc6773dfe9839ef1a6ab8779ce70 100644 --- a/module-apps/application-settings/ApplicationSettings.cpp +++ b/module-apps/application-settings/ApplicationSettings.cpp @@ -163,7 +163,7 @@ namespace app }); } - attachPopups({gui::popup::ID::Volume, gui::popup::ID::PhoneModes}); + attachPopups({gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes}); } void ApplicationSettings::destroyUserInterface() diff --git a/module-apps/popups/Popups.cpp b/module-apps/popups/Popups.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f9a5a00659f4c19f3130cd2d0e35fdf2dcb20153 --- /dev/null +++ b/module-apps/popups/Popups.cpp @@ -0,0 +1,22 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "Popups.hpp" + +namespace gui::popup +{ + std::string resolveWindowName(ID id) + { + switch (id) { + case ID::Volume: + return gui::popup::window::volume_window; + case ID::PhoneModes: + return gui::popup::window::phone_modes_window; + case ID::Brightness: + return gui::popup::window::brightness_window; + case ID::Tethering: + return gui::popup::window::tethering_confirmation_window; + } + return {}; + } +} // namespace gui::popup diff --git a/module-apps/popups/Popups.hpp b/module-apps/popups/Popups.hpp index 5e57c99769de562988e2183e2dfa492101c2efc0..a42c6a1af792bcc607ee5061c185e8ae11720bb2 100644 --- a/module-apps/popups/Popups.hpp +++ b/module-apps/popups/Popups.hpp @@ -17,6 +17,7 @@ namespace gui Volume, PhoneModes, Brightness, + Tethering }; namespace window @@ -24,6 +25,9 @@ namespace gui inline constexpr auto volume_window = "VolumePopup"; inline constexpr auto phone_modes_window = "PhoneModesPopup"; inline constexpr auto brightness_window = "BrightnessPopup"; + inline constexpr auto tethering_confirmation_window = "TetheringConfirmationPopup"; } // namespace window + + std::string resolveWindowName(ID id); } // namespace popup } // namespace gui diff --git a/module-apps/popups/TetheringConfirmationPopup.cpp b/module-apps/popups/TetheringConfirmationPopup.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ccb1f4758f73627b5b21d535630e4b6b8af2a62f --- /dev/null +++ b/module-apps/popups/TetheringConfirmationPopup.cpp @@ -0,0 +1,32 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "TetheringConfirmationPopup.hpp" +#include "DialogMetadataMessage.hpp" +#include "Application.hpp" + +#include +#include + +namespace gui +{ + TetheringConfirmationPopup::TetheringConfirmationPopup(app::Application *app, const std::string &name) + : DialogYesNo{app, name} + {} + + void TetheringConfirmationPopup::onBeforeShow(ShowMode mode, [[maybe_unused]] SwitchData *data) + { + DialogMetadata metadata; + metadata.title = utils::translateI18("tethering"); + metadata.text = utils::translateI18("tethering_enable_question"); + metadata.icon = "info_big_circle_W_G"; + metadata.action = [this]() { + application->bus.sendUnicast(std::make_shared(), + service::name::system_manager); + app::manager::Controller::sendAction(application, app::manager::actions::Home); + return true; + }; + auto msg = std::make_unique(std::move(metadata)); + DialogYesNo::onBeforeShow(mode, msg.get()); + } +} // namespace gui diff --git a/module-apps/popups/TetheringConfirmationPopup.hpp b/module-apps/popups/TetheringConfirmationPopup.hpp new file mode 100644 index 0000000000000000000000000000000000000000..68afc19151ddf85541dbc7c4d22bdf420f21f405 --- /dev/null +++ b/module-apps/popups/TetheringConfirmationPopup.hpp @@ -0,0 +1,19 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include + +#include "Dialog.hpp" + +namespace gui +{ + class TetheringConfirmationPopup : public DialogYesNo + { + public: + TetheringConfirmationPopup(app::Application *app, const std::string &name); + + void onBeforeShow(ShowMode mode, SwitchData *data) override; + }; +}; // namespace gui diff --git a/module-apps/popups/VolumeWindow.cpp b/module-apps/popups/VolumeWindow.cpp index 893a2d39283a3a94634cf2c9a149483afbb69e3d..0e2ae9d5492b5b73e5fb6ad719b50aba3738107e 100644 --- a/module-apps/popups/VolumeWindow.cpp +++ b/module-apps/popups/VolumeWindow.cpp @@ -3,6 +3,7 @@ #include #include +#include "Application.hpp" #include "VolumeWindow.hpp" #include "popups/data/PopupData.hpp" diff --git a/module-apps/popups/VolumeWindow.hpp b/module-apps/popups/VolumeWindow.hpp index db78ac6fe899c02a34513e804304104d1e762756..106dc6dbe5fd87ecb1b3e32962e104b25961aab4 100644 --- a/module-apps/popups/VolumeWindow.hpp +++ b/module-apps/popups/VolumeWindow.hpp @@ -3,9 +3,12 @@ #pragma once -#include "Application.hpp" -#include "widgets/BarGraph.hpp" +#include "module-apps/widgets/BarGraph.hpp" #include "WindowWithTimer.hpp" + +#include +#include + #include namespace style::window::volume @@ -23,6 +26,12 @@ namespace style::window::volume } // namespace bar } // namespace style::window::volume + +namespace app +{ + class Application; +} // namespace app + namespace gui { class VolumeWindow : public WindowWithTimer diff --git a/module-services/service-appmgr/model/ActionsRegistry.cpp b/module-services/service-appmgr/model/ActionsRegistry.cpp index 7490ca1448e93ea29477912f142375016800ad4a..9025af1c725d1d0b85d3bb1ecb2a8e477309bf0c 100644 --- a/module-services/service-appmgr/model/ActionsRegistry.cpp +++ b/module-services/service-appmgr/model/ActionsRegistry.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include @@ -70,13 +70,25 @@ namespace app::manager void ActionsRegistry::notifyAboutNextAction() { - for (auto &action : actions) { - if (const auto handled = nextActionReady(action); handled) { + for (auto it = actions.begin(); it != actions.end();) { + auto &action = *it; + switch (const auto status = nextActionReady(action); status) { + case ActionProcessStatus::Accepted: { LOG_INFO( "Pending action %s to %s", magic_enum::enum_name(action.actionId).data(), action.target.c_str()); actionInProgress = &action; return; } + case ActionProcessStatus::Dropped: { + // Drop the action, so it'll not be processed again. + it = actions.erase(it); + break; + } + case ActionProcessStatus::Skipped: + // Skip the action and check the next one. + ++it; + break; + } } } diff --git a/module-services/service-appmgr/model/ApplicationManager.cpp b/module-services/service-appmgr/model/ApplicationManager.cpp index 48af5933d015dccfb72faac28370aa60394c5a9d..bfa693bee953afff88755b5cc8a3de0c6a914ecc 100644 --- a/module-services/service-appmgr/model/ApplicationManager.cpp +++ b/module-services/service-appmgr/model/ApplicationManager.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -331,7 +332,7 @@ namespace app::manager }); connect(typeid(ActionHandledResponse), [this](sys::Message *response) { actionsRegistry.finished(); - return nullptr; + return sys::MessageNone{}; }); connect(typeid(GetCurrentDisplayLanguageRequest), [&](sys::Message *request) { return std::make_shared(utils::localize.getDisplayLanguage()); @@ -364,6 +365,8 @@ namespace app::manager connect(typeid(sdesktop::passcode::ScreenPasscodeRequest), convertibleToActionHandler); connect(typeid(CellularSMSRejectedByOfflineNotification), convertibleToActionHandler); connect(typeid(CellularCallRejectedByOfflineNotification), convertibleToActionHandler); + connect(typeid(sys::TetheringQuestionRequest), convertibleToActionHandler); + connect(typeid(sys::TetheringQuestionAbort), convertibleToActionHandler); } sys::ReturnCodes ApplicationManager::SwitchPowerModeHandler(const sys::ServicePowerMode mode) @@ -467,15 +470,17 @@ namespace app::manager LOG_INFO("No focused application at the moment. Starting new application..."); onApplicationSwitch(*app, std::move(msg->getData()), msg->getWindow()); startApplication(*app); - return true; + return false; } + onApplicationSwitch(*app, std::move(msg->getData()), msg->getWindow()); if (app->name() == currentlyFocusedApp->name()) { - LOG_WARN("Failed to return to currently focused application."); + // Switch window only. + app::Application::messageSwitchApplication( + this, app->name(), app->switchWindow, std::move(app->switchData)); return false; } - onApplicationSwitch(*app, std::move(msg->getData()), msg->getWindow()); const bool isFocusedAppCloseable = closeCurrentlyFocusedApp && currentlyFocusedApp->closeable() && !currentlyFocusedApp->blockClosing; requestApplicationClose(*currentlyFocusedApp, isFocusedAppCloseable); @@ -514,48 +519,65 @@ namespace app::manager actionsRegistry.enqueue(std::move(entry)); } - bool ApplicationManager::handleAction(ActionEntry &action) + ActionProcessStatus ApplicationManager::handleAction(ActionEntry &action) { switch (action.actionId) { case actions::Home: return handleHomeAction(action); case actions::Launch: return handleLaunchAction(action); + case actions::ShowPopup: + [[fallthrough]]; + case actions::AbortPopup: + return handlePopupAction(action); default: return handleCustomAction(action); } } - auto ApplicationManager::handleHomeAction(ActionEntry &action) -> bool + auto ApplicationManager::handleHomeAction(ActionEntry &action) -> ActionProcessStatus { action.setTargetApplication(rootApplicationName); SwitchRequest switchRequest(ServiceName, rootApplicationName, gui::name::window::main_window, nullptr); - return handleSwitchApplication(&switchRequest); + return handleSwitchApplication(&switchRequest) ? ActionProcessStatus::Accepted : ActionProcessStatus::Dropped; } - auto ApplicationManager::handleLaunchAction(ActionEntry &action) -> bool + auto ApplicationManager::handleLaunchAction(ActionEntry &action) -> ActionProcessStatus { auto launchParams = static_cast(action.params.get()); auto targetApp = getApplication(launchParams->getTargetApplicationName()); if (targetApp == nullptr || !targetApp->handles(actions::Launch)) { - return false; + return ActionProcessStatus::Dropped; } action.setTargetApplication(targetApp->name()); SwitchRequest switchRequest(ServiceName, targetApp->name(), gui::name::window::main_window, nullptr); - return handleSwitchApplication(&switchRequest); + return handleSwitchApplication(&switchRequest) ? ActionProcessStatus::Accepted : ActionProcessStatus::Dropped; } - auto ApplicationManager::handleCustomAction(ActionEntry &action) -> bool + auto ApplicationManager::handlePopupAction(ActionEntry &action) -> ActionProcessStatus + { + auto targetApp = getFocusedApplication(); + if (targetApp == nullptr) { + return ActionProcessStatus::Skipped; + } + action.setTargetApplication(targetApp->name()); + + auto ¶ms = action.params; + app::Application::requestAction(this, targetApp->name(), action.actionId, std::move(params)); + return ActionProcessStatus::Accepted; + } + + auto ApplicationManager::handleCustomAction(ActionEntry &action) -> ActionProcessStatus { const auto actionHandlers = applications.findByAction(action.actionId); if (actionHandlers.empty()) { LOG_ERROR("No applications handling action #%d.", action.actionId); - return false; + return ActionProcessStatus::Dropped; } if (actionHandlers.size() > 1) { LOG_FATAL("Choosing amongst multiple action handler applications is not yet implemented."); - return false; + return ActionProcessStatus::Dropped; } const auto targetApp = actionHandlers.front(); @@ -565,11 +587,12 @@ namespace app::manager const auto focusedAppClose = !(actionParams && actionParams->disableAppClose); SwitchRequest switchRequest( ServiceName, targetApp->name(), targetApp->switchWindow, std::move(targetApp->switchData)); - return handleSwitchApplication(&switchRequest, focusedAppClose); + return handleSwitchApplication(&switchRequest, focusedAppClose) ? ActionProcessStatus::Accepted + : ActionProcessStatus::Skipped; } app::Application::requestAction(this, targetApp->name(), action.actionId, std::move(actionParams)); - return true; + return ActionProcessStatus::Accepted; } auto ApplicationManager::handleSwitchBack(SwitchBackRequest *msg) -> bool diff --git a/module-services/service-appmgr/service-appmgr/Actions.hpp b/module-services/service-appmgr/service-appmgr/Actions.hpp index 4eaf506f754ce191989b455002942341e7656e02..82cb68e0eec4738a082d602a64faff6222b8ed34 100644 --- a/module-services/service-appmgr/service-appmgr/Actions.hpp +++ b/module-services/service-appmgr/service-appmgr/Actions.hpp @@ -60,6 +60,8 @@ namespace app::manager DisplayLogoAtExit, SMSRejectedByOfflineNotification, CallRejectedByOfflineNotification, + ShowPopup, + AbortPopup, UserAction // The last enumerator in the Action enum. // All user-defined actions shall have values greater than UserAction. // All system-wide actions shall have values lesser than UserAction. diff --git a/module-services/service-appmgr/service-appmgr/model/ActionsRegistry.hpp b/module-services/service-appmgr/service-appmgr/model/ActionsRegistry.hpp index 13d37c233074118224bb6bb12c2915cc83755e0e..ca8662e9359555eb6a693620973eef1730127116 100644 --- a/module-services/service-appmgr/service-appmgr/model/ActionsRegistry.hpp +++ b/module-services/service-appmgr/service-appmgr/model/ActionsRegistry.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once @@ -38,10 +38,17 @@ namespace app::manager bool operator==(const ActionEntry &lhs, const ActionEntry &rhs) noexcept; bool operator!=(const ActionEntry &lhs, const ActionEntry &rhs) noexcept; + enum class ActionProcessStatus + { + Accepted, + Skipped, + Dropped + }; + class ActionsRegistry { public: - using OnNextActionReadyCallback = std::function; + using OnNextActionReadyCallback = std::function; explicit ActionsRegistry(OnNextActionReadyCallback &&callback); diff --git a/module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp b/module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp index d1e329c869b296770196ff599e786a812afa41ff..71a2ef1cd583d4196c2b91f7106f8dafb9aee80d 100644 --- a/module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp +++ b/module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp @@ -116,11 +116,12 @@ namespace app::manager // Message handlers void registerMessageHandlers(); - bool handleAction(ActionEntry &action); + auto handleAction(ActionEntry &action) -> ActionProcessStatus; void handleActionRequest(ActionRequest *actionMsg); - auto handleHomeAction(ActionEntry &action) -> bool; - auto handleLaunchAction(ActionEntry &action) -> bool; - auto handleCustomAction(ActionEntry &action) -> bool; + auto handleHomeAction(ActionEntry &action) -> ActionProcessStatus; + auto handleLaunchAction(ActionEntry &action) -> ActionProcessStatus; + auto handlePopupAction(ActionEntry &action) -> ActionProcessStatus; + auto handleCustomAction(ActionEntry &action) -> ActionProcessStatus; auto handleSwitchApplication(SwitchRequest *msg, bool closeCurrentlyFocusedApp = true) -> bool; auto handleCloseConfirmation(CloseConfirmation *msg) -> bool; auto handleSwitchConfirmation(SwitchConfirmation *msg) -> bool; diff --git a/module-services/service-appmgr/tests/test-ActionsRegistry.cpp b/module-services/service-appmgr/tests/test-ActionsRegistry.cpp index 05cccf09afe49aeb8b778f02feeae60423f3a818..6ee992989c38d8a9956390e5ab5ce8a2dad97356 100644 --- a/module-services/service-appmgr/tests/test-ActionsRegistry.cpp +++ b/module-services/service-appmgr/tests/test-ActionsRegistry.cpp @@ -14,7 +14,7 @@ TEST_CASE("Given actions registry when initialise it incorrectly then verify") TEST_CASE("Given empty actions registry when verify its state then no pending actions") { - auto nextActionCallback = [](ActionEntry & /*entry*/) { return true; }; + auto nextActionCallback = [](ActionEntry & /*entry*/) { return ActionProcessStatus::Accepted; }; ActionsRegistry registry{std::move(nextActionCallback)}; REQUIRE(!registry.hasPendingAction()); @@ -22,7 +22,7 @@ TEST_CASE("Given empty actions registry when verify its state then no pending ac TEST_CASE("Given actions registry when enqueue then check pending action") { - auto nextActionCallback = [](ActionEntry & /*entry*/) { return true; }; + auto nextActionCallback = [](ActionEntry & /*entry*/) { return ActionProcessStatus::Accepted; }; ActionsRegistry registry{std::move(nextActionCallback)}; registry.enqueue(ActionEntry{actions::Launch}); @@ -35,7 +35,7 @@ TEST_CASE("Given actions registry when enqueue then check if action was processe bool handled = false; auto nextActionCallback = [&handled](ActionEntry & /*entry*/) { handled = true; - return true; + return ActionProcessStatus::Accepted; }; ActionsRegistry registry{std::move(nextActionCallback)}; @@ -45,7 +45,7 @@ TEST_CASE("Given actions registry when enqueue then check if action was processe TEST_CASE("Given actions registry when finished queued action then no pending actions") { - auto nextActionCallback = [](ActionEntry & /*entry*/) { return true; }; + auto nextActionCallback = [](ActionEntry & /*entry*/) { return ActionProcessStatus::Accepted; }; ActionsRegistry registry{std::move(nextActionCallback)}; registry.enqueue(ActionEntry{actions::Launch}); @@ -58,7 +58,7 @@ TEST_CASE("Given actions registry when enqueue multiple actions sequentially the int counter = 0; auto nextActionCallback = [&counter](ActionEntry & /*entry*/) { ++counter; - return true; + return ActionProcessStatus::Accepted; }; ActionsRegistry registry{std::move(nextActionCallback)}; @@ -79,7 +79,7 @@ TEST_CASE("Given actions registry when enqueue multiple actions at once then cou int counter = 0; auto nextActionCallback = [&counter](ActionEntry & /*entry*/) { ++counter; - return true; + return ActionProcessStatus::Accepted; }; ActionsRegistry registry{std::move(nextActionCallback)}; @@ -104,7 +104,7 @@ TEST_CASE("Given actions registry when enqueue multiple actions at once then cou TEST_CASE("Given actions registry when enqueue multiple actions at once then wait for them to expire.") { - auto nextActionCallback = [](ActionEntry & /*entry*/) { return true; }; + auto nextActionCallback = [](ActionEntry & /*entry*/) { return ActionProcessStatus::Accepted; }; ActionsRegistry registry{std::move(nextActionCallback)}; registry.enqueue(ActionEntry{actions::Launch}); @@ -126,9 +126,9 @@ TEST_CASE("Given actions registry when enqueue multiple actions at once then pro auto nextActionCallback = [&counter](ActionEntry &entry) { if (entry.actionId == actions::UserAction) { ++counter; - return true; + return ActionProcessStatus::Accepted; } - return false; + return ActionProcessStatus::Skipped; }; ActionsRegistry registry{std::move(nextActionCallback)}; @@ -143,3 +143,35 @@ TEST_CASE("Given actions registry when enqueue multiple actions at once then pro REQUIRE(counter == 1); REQUIRE(!registry.hasPendingAction()); } + +TEST_CASE("Process the specific actions only and skip others.") +{ + int acceptedCounter = 0; + int skippedCounter = 0; + int droppedCounter = 0; + auto nextActionCallback = [&acceptedCounter, &skippedCounter, &droppedCounter](ActionEntry &entry) { + if (entry.actionId == actions::UserAction) { + ++acceptedCounter; + return ActionProcessStatus::Accepted; + } + if (entry.actionId == actions::Home) { + ++skippedCounter; + return ActionProcessStatus::Skipped; + } + ++droppedCounter; + return ActionProcessStatus::Dropped; + }; + ActionsRegistry registry{std::move(nextActionCallback)}; + + registry.enqueue(ActionEntry{actions::Launch}); + REQUIRE(droppedCounter == 1); + REQUIRE(!registry.hasPendingAction()); + + registry.enqueue(ActionEntry{actions::Home}); + REQUIRE(skippedCounter == 1); + REQUIRE(!registry.hasPendingAction()); + + registry.enqueue(ActionEntry{actions::UserAction}); + registry.finished(); + REQUIRE(acceptedCounter == 1); +} diff --git a/module-services/service-desktop/ServiceDesktop.cpp b/module-services/service-desktop/ServiceDesktop.cpp index 6ee66fbe40a8f7d213115dc44e5664135b05054a..09546e5628b1462e3a29b213337b24994a205fc6 100644 --- a/module-services/service-desktop/ServiceDesktop.cpp +++ b/module-services/service-desktop/ServiceDesktop.cpp @@ -211,6 +211,9 @@ sys::ReturnCodes ServiceDesktop::InitHandler() }); connect(sdesktop::usb::USBConfigured(), [&](sys::Message *msg) { + bus.sendUnicast(std::make_shared(sys::phone_modes::Tethering::On), + service::name::system_manager); + if (!usbSecurityModel->isSecurityEnabled()) { LOG_INFO("Endpoint security disabled."); return sys::MessageNone{}; diff --git a/module-sys/PhoneModes/Subject.cpp b/module-sys/PhoneModes/Subject.cpp index fa74c5445de28af0e4307fce016d760ef5963e33..930a32927b9d67f0c8673f8114b2be6bf3182ef4 100644 --- a/module-sys/PhoneModes/Subject.cpp +++ b/module-sys/PhoneModes/Subject.cpp @@ -19,18 +19,22 @@ namespace sys::phone_modes } } - void Subject::setMode(PhoneMode _phoneMode, Tethering _tetheringMode) + bool Subject::setMode(PhoneMode _phoneMode, Tethering _tetheringMode) { - if (const bool changed = changePhoneMode(_phoneMode) || changeTetheringMode(_tetheringMode); changed) { + const bool changed = changePhoneMode(_phoneMode) || changeTetheringMode(_tetheringMode); + if (changed) { notifyChange(); } + return changed; } - void Subject::setPhoneMode(PhoneMode mode) + bool Subject::setPhoneMode(PhoneMode mode) { - if (const auto changed = changePhoneMode(mode); changed) { + const auto changed = changePhoneMode(mode); + if (changed) { notifyChange(); } + return changed; } bool Subject::changePhoneMode(PhoneMode mode) noexcept @@ -38,11 +42,13 @@ namespace sys::phone_modes return std::exchange(phoneMode, mode) != mode; } - void Subject::setTetheringMode(Tethering mode) + bool Subject::setTetheringMode(Tethering mode) { - if (const auto changed = changeTetheringMode(mode); changed) { + const auto changed = changeTetheringMode(mode); + if (changed) { notifyChange(); } + return changed; } bool Subject::changeTetheringMode(Tethering mode) noexcept diff --git a/module-sys/PhoneModes/Subject.hpp b/module-sys/PhoneModes/Subject.hpp index ff6f383f1a38b3a3f9879ecbd09a9591004569a5..212bdb6fd23cf8d7f53f9ca3afd8963bdcae1906 100644 --- a/module-sys/PhoneModes/Subject.hpp +++ b/module-sys/PhoneModes/Subject.hpp @@ -17,9 +17,27 @@ namespace sys::phone_modes public: explicit Subject(Service *owner); - void setMode(PhoneMode _phoneMode, Tethering _tetheringMode); - void setPhoneMode(PhoneMode mode); - void setTetheringMode(Tethering mode); + /** + * Sets phone and tethering modes + * @param _phoneMode Phone mode + * @param _tetheringMode Tethering mode + * @return true if modes changed, false otherwise + */ + bool setMode(PhoneMode _phoneMode, Tethering _tetheringMode); + + /** + * Sets the phone mode + * @param mode Phone mode + * @return true if phone mode changed, false otherwise + */ + bool setPhoneMode(PhoneMode mode); + + /** + * Sets the tethering mode + * @param mode Tethering mode + * @return true if tethering mode changed, false otherwise + */ + bool setTetheringMode(Tethering mode); private: void notifyChange(); diff --git a/module-sys/SystemManager/SystemManager.cpp b/module-sys/SystemManager/SystemManager.cpp index 3a3d7ba4954dba80a914d4112cd0290a747fc4f8..ee9ae57152bfa4e6adba0fe6fb0693626e2941d7 100644 --- a/module-sys/SystemManager/SystemManager.cpp +++ b/module-sys/SystemManager/SystemManager.cpp @@ -27,6 +27,7 @@ #include "messages/RequestCpuFrequencyMessage.hpp" #include "messages/PhoneModeRequest.hpp" #include "messages/TetheringStateRequest.hpp" +#include "messages/TetheringQuestionRequest.hpp" #include