mirror of
https://github.com/google/pebble.git
synced 2025-11-27 09:42:24 -05:00
106 lines
3.2 KiB
C
106 lines
3.2 KiB
C
/*
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "idle_watchdog.h"
|
|
|
|
#include "applib/event_service_client.h"
|
|
#include "comm/ble/gap_le_connection.h"
|
|
#include "services/common/battery/battery_monitor.h"
|
|
#include "services/common/regular_timer.h"
|
|
#include "services/common/system_task.h"
|
|
#include "system/reboot_reason.h"
|
|
#include "kernel/util/standby.h"
|
|
|
|
#include <bluetooth/classic_connect.h>
|
|
|
|
#define PRF_IDLE_TIMEOUT_MINUTES 10
|
|
static RegularTimerInfo s_is_idle_timer;
|
|
|
|
|
|
static void prv_handle_watchdog_timeout_cb(void *not_used) {
|
|
GAPLEConnection *le_connection = gap_le_connection_any();
|
|
|
|
if (le_connection || bt_driver_classic_is_connected()) {
|
|
// We are still connected, don't shut down
|
|
return;
|
|
}
|
|
|
|
BatteryChargeState current_state = battery_get_charge_state();
|
|
if (current_state.is_plugged) {
|
|
// We are plugged in, don't shut down
|
|
return;
|
|
}
|
|
|
|
enter_standby(RebootReasonCode_PrfIdle);
|
|
}
|
|
|
|
static void prv_handle_watchdog_timeout(void *not_used) {
|
|
system_task_add_callback(prv_handle_watchdog_timeout_cb, NULL);
|
|
}
|
|
|
|
static void prv_start_watchdog(void) {
|
|
s_is_idle_timer = (const RegularTimerInfo) {
|
|
.cb = prv_handle_watchdog_timeout,
|
|
};
|
|
|
|
regular_timer_add_multiminute_callback(&s_is_idle_timer,
|
|
PRF_IDLE_TIMEOUT_MINUTES);
|
|
}
|
|
|
|
void prv_watchdog_feed(PebbleEvent *e, void *context) {
|
|
if (regular_timer_is_scheduled(&s_is_idle_timer)) {
|
|
prv_start_watchdog();
|
|
}
|
|
}
|
|
|
|
|
|
void prf_idle_watchdog_start(void) {
|
|
// Possible scenario: connect -> 9.9 minutes elapse -> disconnect
|
|
// Feeding the watchdog on bt events ensures we don't shutdown after being
|
|
// idle for only 0.1 minutes
|
|
static EventServiceInfo bt_event_info;
|
|
bt_event_info = (EventServiceInfo) {
|
|
.type = PEBBLE_BT_CONNECTION_EVENT,
|
|
.handler = prv_watchdog_feed,
|
|
};
|
|
event_service_client_subscribe(&bt_event_info);
|
|
|
|
// Possible scenario: plug in watch to charge -> 9.9 minutes elapse -> remove watch from charger
|
|
// Feeding the watchdog on usb events ensures we don't shutdown as the watch is about to be used
|
|
static EventServiceInfo battery_event_info;
|
|
battery_event_info = (EventServiceInfo) {
|
|
.type = PEBBLE_BATTERY_CONNECTION_EVENT,
|
|
.handler = prv_watchdog_feed,
|
|
};
|
|
event_service_client_subscribe(&battery_event_info);
|
|
|
|
// The watch is clearly being used if a button was pressed
|
|
static EventServiceInfo button_event_info;
|
|
button_event_info = (EventServiceInfo) {
|
|
.type = PEBBLE_BUTTON_DOWN_EVENT,
|
|
.handler = prv_watchdog_feed,
|
|
};
|
|
event_service_client_subscribe(&button_event_info);
|
|
|
|
prv_start_watchdog();
|
|
}
|
|
|
|
void prf_idle_watchdog_stop(void) {
|
|
if (regular_timer_is_scheduled(&s_is_idle_timer)) {
|
|
regular_timer_remove_callback(&s_is_idle_timer);
|
|
}
|
|
}
|