Skip to content

Commit 57b3397

Browse files
authored
Multiple wakeup sources (#290)
* Allow multiple wakeup modes at the same time. This commit adds multiple wakeup modes support. It does so by storing them as a uint8_t bitfield enum. It changes the following functions: Since multiple modes can be on now, older version would not cut it: WakeUpMode getWakeupMode() -> std::bitset<3> getWakeUpModes() Where each bit corresponds to a WakeUpMode We still need a way to check whether a specific wakeup mode is on, so: bool isWakeUpModeOn(const WakeUpMode mode) This function was changed to work correctly with the new implementation. setWakeUpMode(WakeupMode mode, bool enable) Previously, systemtask would exit SystemTask::OnTouchEvent() if the wake up mode was None or RaiseWrist, to prevent waking up when a touch was received. However, after enabling using multiple WakeUpModes, this caused a bug where when RaiseWrist was checked with SingleTap or DoubleTap, the tap detection wouldn't work. This commit fixes that bug. Next commit will update the settings WakeUpMode select UI to reflect these changes. Signed-off-by: Kozova1 <mug66kk@gmail.com> * Updated UI to reflect multiple WakeUp sources being available. Signed-off-by: Kozova1 <mug66kk@gmail.com>
1 parent 7133287 commit 57b3397

4 files changed

Lines changed: 73 additions & 49 deletions

File tree

src/components/settings/Settings.h

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22
#include <cstdint>
3+
#include <bitset>
34
#include "components/datetime/DateTimeController.h"
45
#include "components/brightness/BrightnessController.h"
56
#include "components/fs/FS.h"
@@ -11,7 +12,11 @@ namespace Pinetime {
1112
public:
1213
enum class ClockType : uint8_t { H24, H12 };
1314
enum class Vibration : uint8_t { ON, OFF };
14-
enum class WakeUpMode : uint8_t { None, SingleTap, DoubleTap, RaiseWrist };
15+
enum class WakeUpMode : uint8_t {
16+
SingleTap = 0,
17+
DoubleTap = 1,
18+
RaiseWrist = 2,
19+
};
1520

1621
Settings(Pinetime::Controllers::FS& fs);
1722

@@ -72,15 +77,33 @@ namespace Pinetime {
7277
return settings.screenTimeOut;
7378
};
7479

75-
void setWakeUpMode(WakeUpMode wakeUp) {
76-
if (wakeUp != settings.wakeUpMode) {
80+
void setWakeUpMode(WakeUpMode wakeUp, bool enabled) {
81+
if (!isWakeUpModeOn(wakeUp)) {
7782
settingsChanged = true;
7883
}
79-
settings.wakeUpMode = wakeUp;
84+
settings.wakeUpMode.set(static_cast<size_t>(wakeUp), enabled);
85+
// Handle special behavior
86+
if (enabled) {
87+
switch (wakeUp) {
88+
case WakeUpMode::SingleTap:
89+
settings.wakeUpMode.set(static_cast<size_t>(WakeUpMode::DoubleTap), false);
90+
break;
91+
case WakeUpMode::DoubleTap:
92+
settings.wakeUpMode.set(static_cast<size_t>(WakeUpMode::SingleTap), false);
93+
break;
94+
case WakeUpMode::RaiseWrist:
95+
break;
96+
}
97+
}
8098
};
81-
WakeUpMode getWakeUpMode() const {
99+
100+
std::bitset<3> getWakeUpModes() const {
82101
return settings.wakeUpMode;
83-
};
102+
}
103+
104+
bool isWakeUpModeOn(const WakeUpMode mode) const {
105+
return getWakeUpModes()[static_cast<size_t>(mode)];
106+
}
84107

85108
void SetBrightness(Controllers::BrightnessController::Levels level) {
86109
if (level != settings.brightLevel) {
@@ -116,7 +139,7 @@ namespace Pinetime {
116139

117140
uint8_t clockFace = 0;
118141

119-
WakeUpMode wakeUpMode = WakeUpMode::None;
142+
std::bitset<3> wakeUpMode {0};
120143

121144
Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium;
122145
};
@@ -131,4 +154,4 @@ namespace Pinetime {
131154
void SaveSettingsToFile();
132155
};
133156
}
134-
}
157+
}

src/displayapp/screens/settings/SettingWakeUp.cpp

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace {
1616

1717
SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController)
1818
: Screen(app), settingsController {settingsController} {
19-
19+
ignoringEvents = false;
2020
lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr);
2121

2222
lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP);
@@ -42,34 +42,26 @@ SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime::
4242

4343
optionsTotal = 0;
4444
cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr);
45-
lv_checkbox_set_text_static(cbOption[optionsTotal], " None");
46-
cbOption[optionsTotal]->user_data = this;
47-
lv_obj_set_event_cb(cbOption[optionsTotal], event_handler);
48-
if (settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::None) {
49-
lv_checkbox_set_checked(cbOption[optionsTotal], true);
50-
}
51-
optionsTotal++;
52-
cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr);
5345
lv_checkbox_set_text_static(cbOption[optionsTotal], " Single Tap");
5446
cbOption[optionsTotal]->user_data = this;
5547
lv_obj_set_event_cb(cbOption[optionsTotal], event_handler);
56-
if (settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::SingleTap) {
48+
if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap)) {
5749
lv_checkbox_set_checked(cbOption[optionsTotal], true);
5850
}
5951
optionsTotal++;
6052
cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr);
6153
lv_checkbox_set_text_static(cbOption[optionsTotal], " Double Tap");
6254
cbOption[optionsTotal]->user_data = this;
6355
lv_obj_set_event_cb(cbOption[optionsTotal], event_handler);
64-
if (settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::DoubleTap) {
56+
if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) {
6557
lv_checkbox_set_checked(cbOption[optionsTotal], true);
6658
}
6759
optionsTotal++;
6860
cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr);
6961
lv_checkbox_set_text_static(cbOption[optionsTotal], " Raise Wrist");
7062
cbOption[optionsTotal]->user_data = this;
7163
lv_obj_set_event_cb(cbOption[optionsTotal], event_handler);
72-
if (settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) {
64+
if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist)) {
7365
lv_checkbox_set_checked(cbOption[optionsTotal], true);
7466
}
7567
optionsTotal++;
@@ -85,27 +77,31 @@ bool SettingWakeUp::Refresh() {
8577
}
8678

8779
void SettingWakeUp::UpdateSelected(lv_obj_t* object, lv_event_t event) {
88-
if (event == LV_EVENT_VALUE_CHANGED) {
89-
for (int i = 0; i < optionsTotal; i++) {
90-
if (object == cbOption[i]) {
91-
lv_checkbox_set_checked(cbOption[i], true);
80+
using WakeUpMode = Pinetime::Controllers::Settings::WakeUpMode;
81+
if (event == LV_EVENT_VALUE_CHANGED && !ignoringEvents) {
82+
ignoringEvents = true;
9283

93-
if (i == 0) {
94-
settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::None);
95-
};
96-
if (i == 1) {
97-
settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::SingleTap);
98-
};
99-
if (i == 2) {
100-
settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap);
101-
};
102-
if (i == 3) {
103-
settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist);
104-
};
105-
106-
} else {
107-
lv_checkbox_set_checked(cbOption[i], false);
84+
// Find the index of the checkbox that triggered the event
85+
int index = 0;
86+
for (; index < optionsTotal; ++index) {
87+
if (cbOption[index] == object) {
88+
break;
10889
}
10990
}
91+
92+
// Toggle needed wakeup mode
93+
auto mode = static_cast<WakeUpMode>(index);
94+
auto currentState = settingsController.isWakeUpModeOn(mode);
95+
settingsController.setWakeUpMode(mode, !currentState);
96+
97+
// Update checkbox according to current wakeup modes.
98+
// This is needed because we can have extra logic when setting or unsetting wakeup modes,
99+
// for example, when setting SingleTap, DoubleTap is unset and vice versa.
100+
auto modes = settingsController.getWakeUpModes();
101+
for (int i = 0; i < optionsTotal; ++i) {
102+
lv_checkbox_set_checked(cbOption[i], modes[i]);
103+
}
104+
105+
ignoringEvents = false;
110106
}
111-
}
107+
}

src/displayapp/screens/settings/SettingWakeUp.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ namespace Pinetime {
2222
Controllers::Settings& settingsController;
2323
uint8_t optionsTotal;
2424
lv_obj_t* cbOption[4];
25+
// When UpdateSelected is called, it uses lv_checkbox_set_checked,
26+
// which can cause extra events to be fired,
27+
// which might trigger UpdateSelected again, causing a loop.
28+
// This variable is used as a mutex to prevent that.
29+
bool ignoringEvents;
2530
};
2631
}
2732
}

src/systemtask/SystemTask.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ void SystemTask::Work() {
211211
twiMaster.Wakeup();
212212

213213
// Double Tap needs the touch screen to be in normal mode
214-
if (settingsController.getWakeUpMode() != Pinetime::Controllers::Settings::WakeUpMode::DoubleTap) {
214+
if (!settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) {
215215
touchPanel.Wakeup();
216216
}
217217

@@ -232,9 +232,9 @@ void SystemTask::Work() {
232232
auto touchInfo = touchPanel.GetTouchInfo();
233233
twiMaster.Sleep();
234234
if (touchInfo.isTouch and ((touchInfo.gesture == Pinetime::Drivers::Cst816S::Gestures::DoubleTap and
235-
settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::DoubleTap) or
235+
settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) or
236236
(touchInfo.gesture == Pinetime::Drivers::Cst816S::Gestures::SingleTap and
237-
settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::SingleTap))) {
237+
settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap)))) {
238238
GoToRunning();
239239
}
240240
} break;
@@ -296,7 +296,7 @@ void SystemTask::Work() {
296296
spi.Sleep();
297297

298298
// Double Tap needs the touch screen to be in normal mode
299-
if (settingsController.getWakeUpMode() != Pinetime::Controllers::Settings::WakeUpMode::DoubleTap) {
299+
if (!settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) {
300300
touchPanel.Sleep();
301301
}
302302
twiMaster.Sleep();
@@ -348,7 +348,7 @@ void SystemTask::UpdateMotion() {
348348
if (isGoingToSleep or isWakingUp)
349349
return;
350350

351-
if (isSleeping && settingsController.getWakeUpMode() != Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist)
351+
if (isSleeping && !settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist))
352352
return;
353353

354354
if (isSleeping)
@@ -399,10 +399,10 @@ void SystemTask::OnTouchEvent() {
399399
PushMessage(Messages::OnTouchEvent);
400400
displayApp.PushMessage(Pinetime::Applications::Display::Messages::TouchEvent);
401401
} else if (!isWakingUp) {
402-
if (settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::None or
403-
settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist)
404-
return;
405-
PushMessage(Messages::TouchWakeUp);
402+
if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap) or
403+
settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) {
404+
PushMessage(Messages::TouchWakeUp);
405+
}
406406
}
407407
}
408408

0 commit comments

Comments
 (0)