M harmony_changelog.md => harmony_changelog.md +1 -0
@@ 15,6 15,7 @@
* Fixed "Next alarm will ring in 24h" popup on shutdown screen
* Fixed redundant clock face display while shutting down Harmony
* Fixed problem with disabling the frontlight in pre-wake up
+* Fixed occasional crash when a deep press occurs during popups
### Added
M module-apps/application-call/ApplicationCall.cpp => module-apps/application-call/ApplicationCall.cpp +2 -2
@@ 43,9 43,9 @@ namespace app
getPopupFilter().addAppDependentFilter([&](const gui::PopupRequestParams &popupParams) {
if (popupParams.getPopupId() == gui::popup::ID::Volume) {
- return true;
+ return gui::popup::FilterType::Show;
}
- return true;
+ return gui::popup::FilterType::Show;
});
statusBarManager->enableIndicators(
{Indicator::Signal, Indicator::Time, Indicator::Battery, Indicator::SimCard});
M module-apps/application-desktop/ApplicationDesktop.cpp => module-apps/application-desktop/ApplicationDesktop.cpp +3 -2
@@ 33,8 33,9 @@ namespace app
std::make_shared<SIMConfiguration>(SIMConfiguration::DisplayMode::OnlyInactiveState));
bus.channels.push_back(sys::BusChannel::ServiceDBNotifications);
- getPopupFilter().addAppDependentFilter(
- [&](const gui::PopupRequestParams & /*popupParams*/) { return !blockAllPopups; });
+ getPopupFilter().addAppDependentFilter([&](const gui::PopupRequestParams & /*popupParams*/) {
+ return blockAllPopups ? gui::popup::FilterType::Ignore : gui::popup::FilterType::Show;
+ });
addActionReceiver(app::manager::actions::ShowMMIResponse, [this](auto &&data) {
switchWindow(app::window::name::desktop_mmi_pull, std::move(data));
M module-apps/application-onboarding/ApplicationOnBoarding.cpp => module-apps/application-onboarding/ApplicationOnBoarding.cpp +3 -2
@@ 47,7 47,8 @@ namespace app
bus.channels.push_back(sys::BusChannel::ServiceCellularNotifications);
getPopupFilter().addAppDependentFilter([&](const gui::PopupRequestParams & /*popupParams*/) {
- return gui::name::window::main_window != getCurrentWindow()->getName();
+ return gui::name::window::main_window != getCurrentWindow()->getName() ? gui::popup::FilterType::Show
+ : gui::popup::FilterType::Ignore;
});
}
@@ 146,7 147,7 @@ namespace app
const auto eulaDirPath = purefs::dir::getSystemDataDirPath() / "licenses";
const auto eulaFilename = "eula.txt";
auto eulaRepository = std::make_unique<app::onBoarding::EULARepository>(eulaDirPath, eulaFilename);
- auto presenter = std::make_unique<app::onBoarding::EULALicenseWindowPresenter>([&]() { acceptEULA(); },
+ auto presenter = std::make_unique<app::onBoarding::EULALicenseWindowPresenter>([&]() { acceptEULA(); },
std::move(eulaRepository));
return std::make_unique<app::onBoarding::EULALicenseWindow>(app, std::move(presenter));
});
M module-apps/apps-common/ApplicationCommon.cpp => module-apps/apps-common/ApplicationCommon.cpp +8 -3
@@ 864,9 864,14 @@ namespace app
data->setDisposition(gui::popup::Disposition{
gui::popup::Disposition::Priority::Normal, gui::popup::Disposition::WindowType::Popup, id});
}
- windowsPopupQueue->pushRequest(gui::popup::Request(id, std::move(data), *blueprint));
- auto result = tryShowPopup();
- LOG_INFO("tryShowPopup %s status: %s", magic_enum::enum_name(id).data(), result ? "shown" : "ignored");
+ if (popupFilter->addPopup(gui::PopupRequestParams(id))) {
+ windowsPopupQueue->pushRequest(gui::popup::Request(id, std::move(data), *blueprint));
+ auto result = tryShowPopup();
+ LOG_INFO("Try to show Popup %s status: %s", magic_enum::enum_name(id).data(), result ? "shown" : "ignored");
+ }
+ else {
+ LOG_INFO("Popup %s removed", magic_enum::enum_name(id).data());
+ }
}
gui::popup::Filter &ApplicationCommon::getPopupFilter() const
M => +12 -2
@@ 16,7 16,7 @@ namespace gui::popup
bool Filter::isPermitted(const gui::PopupRequestParams ¶ms) const
{
for (const auto &filter : appDependentFilter) {
if (filter != nullptr && not filter(params)) {
if (filter != nullptr && filter(params) != FilterType::Show) {
return false;
}
}
@@ 40,7 40,17 @@ namespace gui::popup
return true;
}
void Filter::addAppDependentFilter(std::function<bool(const gui::PopupRequestParams &)> f)
bool Filter::addPopup(const gui::PopupRequestParams ¶ms) const
{
for (const auto &filter : appDependentFilter) {
if (filter == nullptr || filter(params) == FilterType::Remove) {
return false;
}
}
return true;
}
void Filter::addAppDependentFilter(std::function<FilterType(const gui::PopupRequestParams &)> f)
{
appDependentFilter.push_back(f);
}
M => +12 -3
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 16,12 16,20 @@ namespace app
}
namespace gui::popup
{
enum class FilterType
{
Show = 0, // Show popup
Ignore, // Ignore popup but add to the popup's queue
Remove // Remove and don't add to the popup's queue
};
/// This filter class is used just to filter next popup to handle if any
/// it can and should be overriden to filter out only desired ones at the time
class Filter
{
private:
std::list<std::function<bool(const gui::PopupRequestParams &)>> appDependentFilter;
std::list<std::function<FilterType(const gui::PopupRequestParams &)>> appDependentFilter;
/// non-owning pointer to existing stack - @see attachWindowsStack()
app::WindowsStack *stack = nullptr;
@@ 29,7 37,8 @@ namespace gui::popup
virtual ~Filter() = default;
void attachWindowsStack(app::WindowsStack *stack);
void addAppDependentFilter(std::function<bool(const gui::PopupRequestParams &)> f);
void addAppDependentFilter(std::function<FilterType(const gui::PopupRequestParams &)> f);
virtual bool isPermitted(const gui::PopupRequestParams ¶ms) const;
virtual bool addPopup(const gui::PopupRequestParams ¶ms) const;
};
} // namespace gui::popup
M => +5 -3
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "WindowsPopupFilter.hpp"
@@ 14,7 14,8 @@ TEST_CASE("WindowsPopupQueue::isPermitted", "[!mayfail]")
gui::popup::Filter filter;
SECTION("filter is ok, there is not stack")
{
filter.addAppDependentFilter([](const gui::PopupRequestParams &) -> bool { return true; });
filter.addAppDependentFilter(
[](const gui::PopupRequestParams &) -> gui::popup::FilterType { return gui::popup::FilterType::Show; });
REQUIRE(filter.isPermitted(prp));
}
@@ 84,6 85,7 @@ TEST_CASE("WindowsPopupQueue::addAppDependentFilter")
gui::popup::Filter filter;
auto prp = gui::PopupRequestParams(gui::popup::ID::Alarm);
// create filter that accepts nothing
filter.addAppDependentFilter([](const gui::PopupRequestParams &) -> bool { return false; });
filter.addAppDependentFilter(
[](const gui::PopupRequestParams &) -> gui::popup::FilterType { return gui::popup::FilterType::Ignore; });
REQUIRE(not filter.isPermitted(prp));
}
M products/BellHybrid/apps/Application.cpp => products/BellHybrid/apps/Application.cpp +1 -1
@@ 34,7 34,7 @@ namespace app
if (val == true) {
LOG_ERROR("block popup - as curent window is in higher order popup");
}
- return !val;
+ return val ? gui::popup::FilterType::Ignore : gui::popup::FilterType::Show;
});
}
M products/BellHybrid/apps/application-bell-main/ApplicationBellMain.cpp => products/BellHybrid/apps/application-bell-main/ApplicationBellMain.cpp +8 -2
@@ 42,9 42,10 @@ namespace app
const auto popupId = params.getPopupId();
if (popupId == gui::popup::ID::Alarm || popupId == gui::popup::ID::AlarmActivated ||
popupId == gui::popup::ID::AlarmDeactivated) {
- return gui::name::window::main_window != getCurrentWindow()->getName();
+ return gui::name::window::main_window != getCurrentWindow()->getName() ? gui::popup::FilterType::Show
+ : gui::popup::FilterType::Remove;
}
- return true;
+ return gui::popup::FilterType::Show;
});
bus.channels.push_back(sys::BusChannel::ServiceDBNotifications);
@@ 84,6 85,11 @@ namespace app
});
connect(typeid(AlarmDeactivated), [this](sys::Message *request) -> sys::MessagePointer {
alarmModel->turnOff();
+ alarmModel->activateAlarm(false);
+ return sys::msgHandled();
+ });
+ connect(typeid(AlarmActivated), [this](sys::Message *request) -> sys::MessagePointer {
+ alarmModel->activateAlarm(true);
return sys::msgHandled();
});
}
M products/BellHybrid/apps/common/include/common/models/AbstractAlarmModel.hpp => products/BellHybrid/apps/common/include/common/models/AbstractAlarmModel.hpp +2 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 33,6 33,7 @@ namespace app
virtual std::chrono::seconds getTimeToNextSnooze() = 0;
virtual TimePoint getTimeOfNextSnooze() = 0;
virtual alarms::AlarmStatus getAlarmStatus() = 0;
+ virtual void activateAlarm(bool state) = 0;
/// Command model to update its internal data
virtual void update(AlarmModelReadyHandler callback = AlarmModelReadyHandler()) = 0;
};
M products/BellHybrid/apps/common/include/common/models/AlarmModel.hpp => products/BellHybrid/apps/common/include/common/models/AlarmModel.hpp +2 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 37,6 37,7 @@ namespace app
bool isSnoozeActive() override;
void turnOff() override;
void snooze() override;
+ void activateAlarm(bool state) override;
std::chrono::seconds getTimeToNextSnooze() override;
TimePoint getTimeOfNextSnooze() override;
alarms::AlarmStatus getAlarmStatus() override;
M => +1 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
M => +1 -7
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 36,11 36,8 @@ namespace app::popup
{
public:
virtual ~Presenter() noexcept = default;
virtual void updateAlarmModel(AlarmModelReadyHandler callback) = 0;
virtual time_t getAlarmTime() const noexcept = 0;
virtual bool isAlarmActive() const noexcept = 0;
virtual void activate() = 0;
virtual void deactivate() = 0;
};
};
@@ 49,11 46,8 @@ namespace app::popup
public:
AlarmActivatedPresenter(AbstractAlarmModel &alarmModel);
void updateAlarmModel(AlarmModelReadyHandler callback);
time_t getAlarmTime() const noexcept;
bool isAlarmActive() const noexcept;
void activate();
void deactivate();
private:
AbstractAlarmModel &alarmModel;
M products/BellHybrid/apps/common/src/AlarmModel.cpp => products/BellHybrid/apps/common/src/AlarmModel.cpp +9 -1
@@ 153,7 153,9 @@ namespace app
{
snoozeCount = 0;
nextSnoozeTime = TIME_POINT_INVALID;
- alarms::AlarmServiceAPI::requestTurnOffRingingAlarm(app, cachedRecord.parent->ID);
+ if (cachedRecord.parent != nullptr) {
+ alarms::AlarmServiceAPI::requestTurnOffRingingAlarm(app, cachedRecord.parent->ID);
+ }
}
void AlarmModel::snooze()
@@ 220,6 222,12 @@ namespace app
updateAlarm(*alarmEventPtr);
}
+ void AlarmModel::activateAlarm(bool state)
+ {
+ auto callback = [this, state]() { activate(state); };
+ update(callback);
+ }
+
alarms::AlarmStatus AlarmModel::getAlarmStatus()
{
return alarmStatus;
M => +1 -4
@@ 28,10 28,6 @@ namespace gui
std::move(presenter))
{
getPresenter()->attach(this);
getPresenter()->updateAlarmModel([&]() {
setAlarmTime(getPresenter()->getAlarmTime());
getPresenter()->activate();
});
buildInterface();
timerCallback = [this](Item &, sys::Timer &) {
@@ 56,6 52,7 @@ namespace gui
void AlarmActivatedWindow::onBeforeShow(ShowMode mode, SwitchData *data)
{
setAlarmTime(getPresenter()->getAlarmTime());
WindowWithTimer::onBeforeShow(mode, data);
}
M => +0 -1
@@ 23,7 23,6 @@ namespace gui
{
getPresenter()->attach(this);
buildInterface();
getPresenter()->updateAlarmModel([&]() { getPresenter()->deactivate(); });
timerCallback = [this](Item &, sys::Timer &) {
returnToPreviousWindow();
M => +1 -15
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <common/popups/presenter/AlarmActivatedPresenter.hpp>
@@ 21,18 21,4 @@ namespace app::popup
return alarmModel.getAlarmTime();
}
void AlarmActivatedPresenter::activate()
{
return alarmModel.activate(true);
}
void AlarmActivatedPresenter::deactivate()
{
return alarmModel.activate(false);
}
void AlarmActivatedPresenter::updateAlarmModel(AlarmModelReadyHandler callback)
{
alarmModel.update(callback);
}
} // namespace app::popup
M products/BellHybrid/services/time/AlarmOperations.cpp => products/BellHybrid/services/time/AlarmOperations.cpp +4 -4
@@ 181,10 181,6 @@ namespace alarms
bool AlarmOperations::processPreWakeUp(TimePoint now)
{
- if (nextSingleEvents.empty()) {
- return false;
- }
-
auto nextEvent = getNextPreWakeUpEvent();
if (!nextEvent.isValid()) {
return false;
@@ 209,6 205,10 @@ namespace alarms
SingleEventRecord AlarmOperations::getNextPreWakeUpEvent()
{
+ if (nextSingleEvents.empty()) {
+ return {};
+ }
+
const auto event = *(nextSingleEvents.front());
if (getAlarmEventType(event) != alarms::AlarmType::Clock) {
return {};
M products/BellHybrid/sys/SystemManager.cpp => products/BellHybrid/sys/SystemManager.cpp +1 -1
@@ 32,7 32,7 @@ namespace sys
{
switch (request->getStatus()) {
case AlarmActivationStatus::ACTIVATED:
- bus.sendUnicast(std::make_shared<AlarmActivated>(), service::name::appmgr);
+ bus.sendMulticast(std::make_shared<AlarmActivated>(), sys::BusChannel::AlarmNotifications);
break;
case AlarmActivationStatus::DEACTIVATED:
bus.sendMulticast(std::make_shared<AlarmDeactivated>(), sys::BusChannel::AlarmNotifications);