Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions include/pbl/services/notifications/alerts_preferences_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,20 @@ bool alerts_preferences_dnd_is_smart_enabled(void);

void alerts_preferences_dnd_set_smart_enabled(bool enable);

bool alerts_preferences_dnd_is_sleep_enabled(void);

void alerts_preferences_dnd_set_sleep_enabled(bool enable);

typedef enum {
DndUntilWakeStateDisabled = 0,
DndUntilWakeStateWaitingForSleep,
DndUntilWakeStateWaitingForWake,
} DndUntilWakeState;

DndUntilWakeState alerts_preferences_dnd_get_until_wake_state(void);

void alerts_preferences_dnd_set_until_wake_state(DndUntilWakeState state);

//! Lock the alerts preferences mutex. Must be paired with alerts_preferences_unlock().
void alerts_preferences_lock(void);

Expand Down
12 changes: 12 additions & 0 deletions include/pbl/services/notifications/do_not_disturb.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ typedef enum ManualDNDFirstUseSource {
//! and automatically puts the watch into an Active DND Mode
//! Scheduled DND - Allows the user to specify a daily schedule for when the DND should be in active
//! mode. Once coming out of a schedule, if the Manual DND is enabled, it disables that setting.
//! Sleep Aware DND - Activates while activity tracking reports confirmed sleep.
//! Until Wake DND - Activates immediately and ends after confirmed sleep followed by waking.

//! @return True if DND is in effect, false if not.
bool do_not_disturb_is_active(void);
Expand All @@ -61,6 +63,14 @@ bool do_not_disturb_is_smart_dnd_enabled(void);

void do_not_disturb_toggle_smart_dnd(void);

bool do_not_disturb_is_sleep_dnd_enabled(void);

void do_not_disturb_toggle_sleep_dnd(void);

bool do_not_disturb_is_until_wake_enabled(void);

void do_not_disturb_set_until_wake_enabled(bool enable);

void do_not_disturb_get_schedule(DoNotDisturbScheduleType type, DoNotDisturbSchedule *schedule_out);

void do_not_disturb_set_schedule(DoNotDisturbScheduleType type, DoNotDisturbSchedule *schedule);
Expand All @@ -81,4 +91,6 @@ void do_not_disturb_handle_pref_synced(void);

void do_not_disturb_handle_calendar_event(PebbleCalendarEvent *e);

void do_not_disturb_handle_activity_event(PebbleActivityEvent *e);

void do_not_disturb_manual_toggle_with_dialog(void);
31 changes: 31 additions & 0 deletions src/fw/apps/system/settings/quiet_time.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
#include "applib/ui/menu_layer.h"
#include "applib/ui/time_range_selection_window.h"
#include "kernel/pbl_malloc.h"
#include "pbl/services/activity/activity.h"
#include "pbl/services/clock.h"
#include "pbl/services/i18n/i18n.h"
#include "pbl/services/notifications/alerts_private.h"
#include "pbl/services/notifications/do_not_disturb.h"
#include "pbl/services/notifications/alerts_preferences.h"
#include "popups/health_tracking_ui.h"
#include "system/passert.h"
#include "pbl/util/size.h"
#include "pbl/util/string.h"
Expand All @@ -39,6 +41,7 @@ typedef struct {

enum QuietTimeItem {
QuietTimeItemManual,
QuietTimeItemUntilWake,
QuietTimeItemSchedule,
QuietTimeItemInterruptions,
QuietTimeItemNotifications,
Expand All @@ -55,6 +58,7 @@ enum QuietTimeItem {

enum QuietTimeScheduleItem {
QuietTimeScheduleItemCalendarAware,
QuietTimeScheduleItemSleepAware,
QuietTimeScheduleItemWeekday,
QuietTimeScheduleItemWeekend,
QuietTimeScheduleItem_Count,
Expand Down Expand Up @@ -258,6 +262,12 @@ static void prv_schedule_draw_row_cb(SettingsCallbacks *context, GContext *ctx,
: i18n_ctx_get("QuietTime", "Disabled", data),
buffer_length);
break;
case QuietTimeScheduleItemSleepAware:
title = i18n_get("Sleep Aware", data);
strncpy(subtitle, do_not_disturb_is_sleep_dnd_enabled() ?
i18n_ctx_get("QuietTime", "Enabled", data) :
i18n_ctx_get("QuietTime", "Disabled", data), buffer_length);
break;
case QuietTimeScheduleItemWeekday:
title = i18n_get("Weekdays", data);
if (do_not_disturb_is_schedule_enabled(WeekdaySchedule)) {
Expand Down Expand Up @@ -288,6 +298,14 @@ static void prv_schedule_select_click_cb(SettingsCallbacks *context, uint16_t ro
case QuietTimeScheduleItemCalendarAware:
do_not_disturb_toggle_smart_dnd();
break;
case QuietTimeScheduleItemSleepAware:
if (!do_not_disturb_is_sleep_dnd_enabled() &&
!activity_prefs_tracking_is_enabled()) {
health_tracking_ui_feature_show_disabled();
break;
}
do_not_disturb_toggle_sleep_dnd();
break;
case QuietTimeScheduleItemWeekday:
prv_scheduled_dnd_menu_push(WeekdaySchedule, data);
break;
Expand Down Expand Up @@ -428,6 +446,11 @@ static void prv_draw_row_cb(SettingsCallbacks *context, GContext *ctx, const Lay
subtitle =
do_not_disturb_is_manually_enabled() ? i18n_get("On", data) : i18n_get("Off", data);
break;
case QuietTimeItemUntilWake:
title = i18n_get("Until Wake", data);
subtitle = do_not_disturb_is_until_wake_enabled() ?
i18n_get("On", data) : i18n_get("Off", data);
break;
case QuietTimeItemSchedule:
title = i18n_get("Schedule", data);
break;
Expand Down Expand Up @@ -468,6 +491,14 @@ static void prv_select_click_cb(SettingsCallbacks *context, uint16_t row) {
case QuietTimeItemManual:
do_not_disturb_toggle_manually_enabled(ManualDNDFirstUseSourceSettingsMenu);
break;
case QuietTimeItemUntilWake:
if (!do_not_disturb_is_until_wake_enabled() &&
!activity_prefs_tracking_is_enabled()) {
health_tracking_ui_feature_show_disabled();
break;
}
do_not_disturb_set_until_wake_enabled(!do_not_disturb_is_until_wake_enabled());
break;
case QuietTimeItemSchedule:
prv_schedule_submenu_push();
break;
Expand Down
2 changes: 2 additions & 0 deletions src/fw/kernel/events.h
Original file line number Diff line number Diff line change
Expand Up @@ -723,12 +723,14 @@ _Static_assert(sizeof(PebbleAppCacheEvent) == 5, "PebbleTimelinePeekEvent size m
typedef enum PebbleActivityEventType {
PebbleActivityEvent_TrackingStarted,
PebbleActivityEvent_TrackingStopped,
PebbleActivityEvent_SleepStateChanged,

PebbleActivityEventNum
} PebbleActivityEventType;

typedef struct PBL_PACKED PebbleActivityEvent {
PebbleActivityEventType type : 8;
uint8_t sleep_state;
} PebbleActivityEvent;

typedef enum PebbleWorkoutEventType {
Expand Down
9 changes: 9 additions & 0 deletions src/fw/services/activity/activity_sessions.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,15 @@ static void prv_update_sleep_metrics(time_t now_utc, time_t max_end_utc,
"state_min: %" PRIu32 "",
sleep_data->total_minutes, sleep_data->restful_minutes,
sleep_data->cur_state, sleep_data->cur_state_elapsed_minutes);

PebbleEvent e = {
.type = PEBBLE_ACTIVITY_EVENT,
.activity_event = {
.type = PebbleActivityEvent_SleepStateChanged,
.sleep_state = sleep_data->cur_state,
},
};
event_put(&e);
}
}
unlock:
Expand Down
1 change: 1 addition & 0 deletions src/fw/services/blob_db/settings_blob_db.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ static const char *s_syncable_notif_prefs[] = {
"vibeScoreAlarms",
"dndManuallyEnabled",
"dndSmartEnabled",
"dndSleepEnabled",
"dndWeekdaySchedule",
"dndWeekdayScheduleEnabled",
"dndWeekendSchedule",
Expand Down
30 changes: 29 additions & 1 deletion src/fw/services/notifications/alerts_preferences.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ static bool s_do_not_disturb_manually_enabled = false;
#define PREF_KEY_DND_SMART_ENABLED "dndSmartEnabled"
static bool s_do_not_disturb_smart_dnd_enabled = false;

#define PREF_KEY_DND_SLEEP_ENABLED "dndSleepEnabled"
static bool s_do_not_disturb_sleep_dnd_enabled = false;

#define PREF_KEY_DND_UNTIL_WAKE_STATE "dndUntilWakeState"
static DndUntilWakeState s_do_not_disturb_until_wake_state = DndUntilWakeStateDisabled;

#define PREF_KEY_FIRST_USE_COMPLETE "firstUseComplete"
static uint32_t s_first_use_complete = 0;

Expand Down Expand Up @@ -320,6 +326,8 @@ void alerts_preferences_init(void) {
RESTORE_PREF(PREF_KEY_VIBE_SCORE_ON_DISCONNECT, s_vibe_score_on_disconnect);
RESTORE_PREF(PREF_KEY_DND_MANUALLY_ENABLED, s_do_not_disturb_manually_enabled);
RESTORE_PREF(PREF_KEY_DND_SMART_ENABLED, s_do_not_disturb_smart_dnd_enabled);
RESTORE_PREF(PREF_KEY_DND_SLEEP_ENABLED, s_do_not_disturb_sleep_dnd_enabled);
RESTORE_PREF(PREF_KEY_DND_UNTIL_WAKE_STATE, s_do_not_disturb_until_wake_state);
RESTORE_PREF(PREF_KEY_DND_INTERRUPTIONS_MASK, s_dnd_interruptions_mask);
RESTORE_PREF(PREF_KEY_DND_SHOW_NOTIFICATIONS, s_dnd_show_notifications);
RESTORE_PREF(PREF_KEY_DND_MOTION_BACKLIGHT, s_dnd_motion_backlight);
Expand Down Expand Up @@ -656,6 +664,24 @@ void alerts_preferences_dnd_set_smart_enabled(bool enable) {
SET_PREF(PREF_KEY_DND_SMART_ENABLED, s_do_not_disturb_smart_dnd_enabled);
}

bool alerts_preferences_dnd_is_sleep_enabled(void) {
return s_do_not_disturb_sleep_dnd_enabled;
}

void alerts_preferences_dnd_set_sleep_enabled(bool enable) {
s_do_not_disturb_sleep_dnd_enabled = enable;
SET_PREF(PREF_KEY_DND_SLEEP_ENABLED, s_do_not_disturb_sleep_dnd_enabled);
}

DndUntilWakeState alerts_preferences_dnd_get_until_wake_state(void) {
return s_do_not_disturb_until_wake_state;
}

void alerts_preferences_dnd_set_until_wake_state(DndUntilWakeState state) {
s_do_not_disturb_until_wake_state = state;
SET_PREF(PREF_KEY_DND_UNTIL_WAKE_STATE, s_do_not_disturb_until_wake_state);
}

void alerts_preferences_lock(void) {
pbl_mutex_lock(&s_mutex, PBL_FOREVER);
}
Expand All @@ -667,7 +693,8 @@ void alerts_preferences_unlock(void) {
//! Keys that feed do_not_disturb_is_active() or the DND schedule timer
static bool prv_is_dnd_state_key(const char *key) {
if (strcmp(key, PREF_KEY_DND_MANUALLY_ENABLED) == 0 ||
strcmp(key, PREF_KEY_DND_SMART_ENABLED) == 0) {
strcmp(key, PREF_KEY_DND_SMART_ENABLED) == 0 ||
strcmp(key, PREF_KEY_DND_SLEEP_ENABLED) == 0) {
return true;
}
for (int i = 0; i < NumDNDSchedules; i++) {
Expand Down Expand Up @@ -723,6 +750,7 @@ void alerts_preferences_handle_blob_db_event(PebbleBlobDBEvent *event) {
RELOAD_IF_MATCH(PREF_KEY_VIBE_SCORE_ALARMS, s_vibe_score_alarms);
RELOAD_IF_MATCH(PREF_KEY_DND_MANUALLY_ENABLED, s_do_not_disturb_manually_enabled);
RELOAD_IF_MATCH(PREF_KEY_DND_SMART_ENABLED, s_do_not_disturb_smart_dnd_enabled);
RELOAD_IF_MATCH(PREF_KEY_DND_SLEEP_ENABLED, s_do_not_disturb_sleep_dnd_enabled);
RELOAD_IF_MATCH(s_dnd_schedule_keys[WeekdaySchedule].schedule_pref_key,
s_dnd_schedule[WeekdaySchedule].schedule);
RELOAD_IF_MATCH(s_dnd_schedule_keys[WeekdaySchedule].enabled_pref_key,
Expand Down
Loading