Skip to content

Commit 3a32820

Browse files
committed
Update FindMyPhone UI in case disconnect.
1 parent f7276d2 commit 3a32820

5 files changed

Lines changed: 105 additions & 54 deletions

File tree

src/components/ble/ImmediateAlertClient.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,24 @@ int ImmediateAlertClient::OnCharacteristicDiscoveryEvent(uint16_t conn_handle,
6363
if (characteristic != nullptr && ble_uuid_cmp(&alertLevelCharacteristicUuid.u, &characteristic->uuid.u) == 0) {
6464
NRF_LOG_INFO("[IAS] Characteristic discovered : 0x%x", characteristic->val_handle);
6565
alertLevelHandle = characteristic->val_handle;
66+
state = State::Connected;
6667
}
6768
return 0;
6869
}
6970

7071
void ImmediateAlertClient::Discover(uint16_t connectionHandle, std::function<void(uint16_t)> onServiceDiscovered) {
7172
NRF_LOG_INFO("[IAS] Starting discovery");
7273
this->onServiceDiscovered = onServiceDiscovered;
74+
state = State::NoIAS;
7375
ble_gattc_disc_svc_by_uuid(connectionHandle, &immediateAlertClientUuid.u, OnDiscoveryEventCallback, this);
7476
}
7577

78+
void ImmediateAlertClient::Reset() {
79+
state = State::NoConnection;
80+
iasHandles = std::nullopt;
81+
alertLevelHandle = std::nullopt;
82+
}
83+
7684
bool ImmediateAlertClient::SendImmediateAlert(ImmediateAlertClient::Levels level) {
7785

7886
auto* om = ble_hs_mbuf_from_flat(&level, 1);

src/components/ble/ImmediateAlertClient.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,23 @@ namespace Pinetime {
1818
class ImmediateAlertClient : public BleClient {
1919
public:
2020
enum class Levels : uint8_t { NoAlert = 0, MildAlert = 1, HighAlert = 2 };
21+
enum class State {
22+
NoConnection,
23+
NoIAS,
24+
Connected,
25+
};
2126

2227
explicit ImmediateAlertClient(Pinetime::System::SystemTask& systemTask);
2328
void Init();
2429

2530
bool SendImmediateAlert(Levels level);
2631

32+
State GetState() const {
33+
return state;
34+
}
35+
2736
void Discover(uint16_t connectionHandle, std::function<void(uint16_t)> lambda) override;
37+
void Reset();
2838

2939
private:
3040
bool OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_svc* service);
@@ -61,6 +71,7 @@ namespace Pinetime {
6171
std::optional<HandleRange> iasHandles;
6272
std::optional<uint16_t> alertLevelHandle;
6373
std::function<void(uint16_t)> onServiceDiscovered;
74+
State state {State::NoConnection};
6475
};
6576
}
6677
}

src/components/ble/NimbleController.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) {
202202
/* Connection failed; resume advertising. */
203203
currentTimeClient.Reset();
204204
alertNotificationClient.Reset();
205+
iaClient.Reset();
205206
connectionHandle = BLE_HS_CONN_HANDLE_NONE;
206207
bleController.Disconnect();
207208
fastAdvCount = 0;
@@ -225,6 +226,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) {
225226

226227
currentTimeClient.Reset();
227228
alertNotificationClient.Reset();
229+
iaClient.Reset();
228230
connectionHandle = BLE_HS_CONN_HANDLE_NONE;
229231
if (bleController.IsConnected()) {
230232
bleController.Disconnect();

src/displayapp/screens/FindMyPhone.cpp

Lines changed: 69 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,43 @@
77
using namespace Pinetime::Applications::Screens;
88

99
namespace {
10-
static constexpr char defaultLabelText[] = "Find my phone";
11-
static constexpr char alertSentLabelText[] = "Alert sent";
12-
static constexpr char noConnectionLabelText[] = "No connection";
10+
static constexpr char alertSentLabelText[] = "Alerting";
11+
1312
static constexpr char noneLabelText[] = "Stop";
1413
static constexpr char highLabelText[] = "Ring";
15-
static constexpr int restoreLabelTimeoutSec = 2;
16-
static constexpr TickType_t restoreLabelTimeoutTicks = restoreLabelTimeoutSec * configTICK_RATE_HZ;
1714

1815
void btnImmediateAlertEventHandler(lv_obj_t* obj, lv_event_t event) {
1916
auto* screen = static_cast<FindMyPhone*>(obj->user_data);
2017
screen->OnImmediateAlertEvent(obj, event);
2118
}
22-
23-
void RestoreLabelTaskCallback(lv_task_t* task) {
24-
auto* screen = static_cast<FindMyPhone*>(task->user_data);
25-
screen->RestoreLabelText();
26-
screen->StopRestoreLabelTask();
27-
}
2819
}
2920

30-
FindMyPhone::FindMyPhone(Pinetime::Controllers::ImmediateAlertClient& immediateAlertClient) : immediateAlertClient {immediateAlertClient} {
31-
lastLevel = Pinetime::Controllers::ImmediateAlertClient::Levels::NoAlert;
21+
const FindMyPhone::LabelState FindMyPhone::stoppedLabelState {
22+
.text = "Alert stopped",
23+
.color = LV_COLOR_WHITE,
24+
};
25+
26+
const FindMyPhone::LabelState FindMyPhone::noConnectionLabelState {
27+
.text = "No connection",
28+
.color = LV_COLOR_WHITE,
29+
};
30+
31+
const FindMyPhone::LabelState FindMyPhone::noServiceLabelState {
32+
.text = "No service",
33+
.color = LV_COLOR_WHITE,
34+
};
35+
36+
const FindMyPhone::LabelState FindMyPhone::defaultLabelState {
37+
.text = "Ready",
38+
.color = LV_COLOR_WHITE,
39+
};
3240

41+
const FindMyPhone::LabelState FindMyPhone::alertingLabelState {
42+
.text = "Alerting",
43+
.color = LV_COLOR_RED,
44+
};
45+
46+
FindMyPhone::FindMyPhone(Pinetime::Controllers::ImmediateAlertClient& immediateAlertClient) : immediateAlertClient {immediateAlertClient} {
3347
container = lv_cont_create(lv_scr_act(), nullptr);
3448

3549
lv_obj_set_size(container, LV_HOR_RES, LV_VER_RES);
@@ -40,10 +54,6 @@ FindMyPhone::FindMyPhone(Pinetime::Controllers::ImmediateAlertClient& immediateA
4054

4155
lblTitle = lv_label_create(lv_scr_act(), nullptr);
4256

43-
lv_label_set_text_static(lblTitle, defaultLabelText);
44-
lv_obj_set_style_local_text_color(lblTitle, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
45-
lv_obj_align(lblTitle, nullptr, LV_ALIGN_CENTER, 0, -40);
46-
4757
btnNone = lv_btn_create(container, nullptr);
4858
btnNone->user_data = this;
4959
lv_obj_set_event_cb(btnNone, btnImmediateAlertEventHandler);
@@ -61,59 +71,68 @@ FindMyPhone::FindMyPhone(Pinetime::Controllers::ImmediateAlertClient& immediateA
6171
lblHigh = lv_label_create(btnHigh, nullptr);
6272
lv_label_set_text_static(lblHigh, highLabelText);
6373
lv_obj_set_style_local_bg_color(btnHigh, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
74+
refreshTask = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
6475
}
6576

6677
FindMyPhone::~FindMyPhone() {
78+
lv_task_del(refreshTask);
6779
lv_obj_clean(lv_scr_act());
6880
}
6981

7082
void FindMyPhone::OnImmediateAlertEvent(lv_obj_t* obj, lv_event_t event) {
7183
if (event == LV_EVENT_CLICKED) {
7284
if (obj == btnNone) {
73-
lastLevel = Pinetime::Controllers::ImmediateAlertClient::Levels::NoAlert;
85+
lastUserInitiatedLevel = Pinetime::Controllers::ImmediateAlertClient::Levels::NoAlert;
7486
} else if (obj == btnHigh) {
75-
lastLevel = Pinetime::Controllers::ImmediateAlertClient::Levels::HighAlert;
87+
lastUserInitiatedLevel = Pinetime::Controllers::ImmediateAlertClient::Levels::HighAlert;
88+
} else {
89+
// Unknown button?
90+
ASSERT(false);
91+
return;
7692
}
77-
UpdateImmediateAlerts();
93+
immediateAlertClient.SendImmediateAlert(*lastUserInitiatedLevel);
7894
}
7995
}
8096

81-
void FindMyPhone::UpdateImmediateAlerts() {
82-
switch (lastLevel) {
83-
case Pinetime::Controllers::ImmediateAlertClient::Levels::NoAlert:
84-
lv_obj_set_style_local_text_color(lblTitle, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
97+
const FindMyPhone::LabelState& FindMyPhone::GetLabelState() const {
98+
const auto service_state = immediateAlertClient.GetState();
99+
switch (service_state) {
100+
case Pinetime::Controllers::ImmediateAlertClient::State::NoConnection:
101+
return noConnectionLabelState;
102+
case Pinetime::Controllers::ImmediateAlertClient::State::NoIAS:
103+
return noServiceLabelState;
104+
case Pinetime::Controllers::ImmediateAlertClient::State::Connected:
85105
break;
106+
}
107+
// Conntected state handling.
108+
if (!lastUserInitiatedLevel.has_value()) {
109+
return defaultLabelState;
110+
}
111+
switch (*lastUserInitiatedLevel) {
112+
case Pinetime::Controllers::ImmediateAlertClient::Levels::NoAlert:
113+
return stoppedLabelState;
86114
case Pinetime::Controllers::ImmediateAlertClient::Levels::HighAlert:
87-
lv_obj_set_style_local_text_color(lblTitle, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
88-
break;
115+
return alertingLabelState;
89116
case Pinetime::Controllers::ImmediateAlertClient::Levels::MildAlert:
90-
// Not supported.
117+
// Not supported
118+
default:
91119
ASSERT(false);
92-
break;
120+
return alertingLabelState;
93121
}
94-
if (immediateAlertClient.SendImmediateAlert(lastLevel)) {
95-
lv_label_set_text_static(lblTitle, alertSentLabelText);
96-
} else {
97-
lv_label_set_text_static(lblTitle, noConnectionLabelText);
98-
}
99-
ScheduleRestoreLabelTask();
100122
}
101123

102-
void FindMyPhone::ScheduleRestoreLabelTask() {
103-
if (taskRestoreLabelText) {
104-
return;
105-
}
106-
taskRestoreLabelText = lv_task_create(RestoreLabelTaskCallback, restoreLabelTimeoutTicks, LV_TASK_PRIO_MID, this);
107-
}
108-
109-
void FindMyPhone::StopRestoreLabelTask() {
110-
if (taskRestoreLabelText) {
111-
lv_task_del(taskRestoreLabelText);
112-
taskRestoreLabelText = nullptr;
124+
void FindMyPhone::Refresh() {
125+
const auto service_state = immediateAlertClient.GetState();
126+
if (service_state == Pinetime::Controllers::ImmediateAlertClient::State::Connected) {
127+
lv_obj_clear_state(btnNone, LV_STATE_DISABLED);
128+
lv_obj_clear_state(btnHigh, LV_STATE_DISABLED);
129+
} else {
130+
lv_obj_add_state(btnNone, LV_STATE_DISABLED);
131+
lv_obj_add_state(btnHigh, LV_STATE_DISABLED);
132+
lastUserInitiatedLevel = std::nullopt;
113133
}
114-
}
115-
116-
void FindMyPhone::RestoreLabelText() {
117-
lv_label_set_text_static(lblTitle, defaultLabelText);
118-
lv_obj_set_style_local_text_color(lblTitle, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
134+
const auto& label_state = GetLabelState();
135+
lv_obj_set_style_local_text_color(lblTitle, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, label_state.color);
136+
lv_label_set_text_static(lblTitle, label_state.text);
137+
lv_obj_align(lblTitle, nullptr, LV_ALIGN_CENTER, 0, -40);
119138
}

src/displayapp/screens/FindMyPhone.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <cstdint>
44
#include <chrono>
5+
#include <optional>
56
#include "displayapp/screens/Screen.h"
67
#include "Symbols.h"
78
#include "systemtask/SystemTask.h"
@@ -26,24 +27,34 @@ namespace Pinetime {
2627

2728
void OnImmediateAlertEvent(lv_obj_t* obj, lv_event_t event);
2829

29-
void ScheduleRestoreLabelTask();
3030
void StopRestoreLabelTask();
3131
void RestoreLabelText();
32+
void Refresh() override;
3233

3334
private:
3435
Pinetime::Controllers::ImmediateAlertClient& immediateAlertClient;
3536

36-
void UpdateImmediateAlerts();
37+
struct LabelState {
38+
const char* text;
39+
lv_color_t color;
40+
};
41+
42+
static const LabelState stoppedLabelState;
43+
static const LabelState noConnectionLabelState;
44+
static const LabelState noServiceLabelState;
45+
static const LabelState defaultLabelState;
46+
static const LabelState alertingLabelState;
47+
const LabelState& GetLabelState() const;
3748

3849
lv_obj_t* container;
3950
lv_obj_t* lblTitle;
4051
lv_obj_t* btnNone;
4152
lv_obj_t* btnHigh;
4253
lv_obj_t* lblNone;
4354
lv_obj_t* lblHigh;
44-
lv_task_t* taskRestoreLabelText = nullptr;
55+
lv_task_t* refreshTask = nullptr;
4556

46-
Pinetime::Controllers::ImmediateAlertClient::Levels lastLevel;
57+
std::optional<Pinetime::Controllers::ImmediateAlertClient::Levels> lastUserInitiatedLevel;
4758
};
4859
}
4960

0 commit comments

Comments
 (0)