diff --git a/applications/services/power/power_service/power.c b/applications/services/power/power_service/power.c index 5063e81c5..0935814cb 100644 --- a/applications/services/power/power_service/power.c +++ b/applications/services/power/power_service/power.c @@ -92,6 +92,10 @@ static void power_stop_auto_shutdown_timer(Power* power) { furi_timer_stop(power->auto_shutdown_timer); } +static uint32_t power_is_running_auto_shutdown_timer(Power* power) { + return furi_timer_is_running(power->auto_shutdown_timer); +} + static void power_input_event_callback(const void* value, void* context) { furi_assert(value); furi_assert(context); @@ -104,8 +108,10 @@ static void power_input_event_callback(const void* value, void* context) { static void power_auto_shutdown_arm(Power* power) { if(power->shutdown_idle_delay_ms) { - power->input_events_subscription = - furi_pubsub_subscribe(power->input_events_pubsub, power_input_event_callback, power); + if(power->input_events_subscription == NULL) { + power->input_events_subscription = furi_pubsub_subscribe( + power->input_events_pubsub, power_input_event_callback, power); + } power_start_auto_shutdown_timer(power); } } @@ -125,6 +131,18 @@ static void power_auto_shutdown_timer_callback(void* context) { power_off(power); } +static void power_shutdown_time_changed_callback(const void* event, void* context) { + furi_assert(event); + furi_assert(context); + Power* power = context; + power->shutdown_idle_delay_ms = *(uint32_t*)event; + if(power->shutdown_idle_delay_ms) { + power_auto_shutdown_arm(power); + } else if(power_is_running_auto_shutdown_timer(power)) { + power_auto_shutdown_inhibit(power); + } +} + Power* power_alloc() { Power* power = malloc(sizeof(Power)); @@ -133,6 +151,10 @@ Power* power_alloc() { power->gui = furi_record_open(RECORD_GUI); // Pubsub power->event_pubsub = furi_pubsub_alloc(); + power->settings_events = furi_pubsub_alloc(); + furi_pubsub_subscribe(power->settings_events, power_shutdown_time_changed_callback, power); + power->input_events_pubsub = furi_record_open(RECORD_INPUT_EVENTS); + power->input_events_subscription = NULL; power->input_events_pubsub = furi_record_open(RECORD_INPUT_EVENTS); power->input_events_subscription = NULL; @@ -183,6 +205,7 @@ void power_free(Power* power) { // FuriPubSub furi_pubsub_free(power->event_pubsub); + furi_pubsub_free(power->settings_events); furi_pubsub_free(power->input_events_pubsub); if(power->input_events_subscription) { @@ -190,6 +213,9 @@ void power_free(Power* power) { power->input_events_subscription = NULL; } + //Auto shutdown timer + furi_timer_free(power->auto_shutdown_timer); + // Records furi_record_close(RECORD_NOTIFICATION); furi_record_close(RECORD_GUI); diff --git a/applications/services/power/power_service/power.h b/applications/services/power/power_service/power.h index bdf5fa529..3144a46e4 100644 --- a/applications/services/power/power_service/power.h +++ b/applications/services/power/power_service/power.h @@ -80,6 +80,14 @@ void power_get_info(Power* power, PowerInfo* info); */ FuriPubSub* power_get_pubsub(Power* power); +/** Get power settings events pubsub handler + * + * @param power Power instance + * + * @return FuriPubSub instance + */ +FuriPubSub* power_get_settings_events_pubsub(Power* power); + /** Check battery health * * @return true if battery is healthy diff --git a/applications/services/power/power_service/power_api.c b/applications/services/power/power_service/power_api.c index 8185b7cd5..ef25ca019 100644 --- a/applications/services/power/power_service/power_api.c +++ b/applications/services/power/power_service/power_api.c @@ -38,6 +38,11 @@ FuriPubSub* power_get_pubsub(Power* power) { return power->event_pubsub; } +FuriPubSub* power_get_settings_events_pubsub(Power* power) { + furi_assert(power); + return power->settings_events; +} + bool power_is_battery_healthy(Power* power) { furi_assert(power); bool is_healthy = false; diff --git a/applications/services/power/power_service/power_i.h b/applications/services/power/power_service/power_i.h index 2b5682213..bbaab8fa1 100644 --- a/applications/services/power/power_service/power_i.h +++ b/applications/services/power/power_service/power_i.h @@ -8,7 +8,7 @@ #include #include "views/power_off.h" -#include "applications/settings/power_settings_app/power_settings.h" +#include #include "views/power_unplug_usb.h" #include @@ -30,6 +30,7 @@ struct Power { Gui* gui; NotificationApp* notification; FuriPubSub* event_pubsub; + FuriPubSub* settings_events; FuriPubSub* input_events_pubsub; FuriPubSubSubscription* input_events_subscription; PowerEvent event; diff --git a/applications/services/power/power_settings.h b/applications/services/power/power_settings.h new file mode 100644 index 000000000..0f2afa295 --- /dev/null +++ b/applications/services/power/power_settings.h @@ -0,0 +1,16 @@ +#include +#include +#include "power_settings_filename.h" + +#define POWER_SETTINGS_VER (1) + +#define POWER_SETTINGS_PATH INT_PATH(POWER_SETTINGS_FILE_NAME) +#define POWER_SETTINGS_MAGIC (0x21) + +#define SAVE_POWER_SETTINGS(x) \ + saved_struct_save( \ + POWER_SETTINGS_PATH, (x), sizeof(uint32_t), POWER_SETTINGS_MAGIC, POWER_SETTINGS_VER) + +#define LOAD_POWER_SETTINGS(x) \ + saved_struct_load( \ + POWER_SETTINGS_PATH, (x), sizeof(uint32_t), POWER_SETTINGS_MAGIC, POWER_SETTINGS_VER) diff --git a/applications/services/power/power_settings_filename.h b/applications/services/power/power_settings_filename.h new file mode 100644 index 000000000..6a3be534c --- /dev/null +++ b/applications/services/power/power_settings_filename.h @@ -0,0 +1,3 @@ +#pragma once + +#define POWER_SETTINGS_FILE_NAME ".power.settings" \ No newline at end of file diff --git a/applications/settings/power_settings_app/power_settings_app.c b/applications/settings/power_settings_app/power_settings_app.c index ec010ee71..016439c0d 100644 --- a/applications/settings/power_settings_app/power_settings_app.c +++ b/applications/settings/power_settings_app/power_settings_app.c @@ -25,6 +25,9 @@ PowerSettingsApp* power_settings_app_alloc(uint32_t first_scene) { app->gui = furi_record_open(RECORD_GUI); app->power = furi_record_open(RECORD_POWER); + //PubSub + app->settings_events = power_get_settings_events_pubsub(app->power); + // View dispatcher app->view_dispatcher = view_dispatcher_alloc(); app->scene_manager = scene_manager_alloc(&power_settings_scene_handlers, app); @@ -66,18 +69,24 @@ void power_settings_app_free(PowerSettingsApp* app) { // Views view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewBatteryInfo); battery_info_free(app->batery_info); + view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewSubmenu); submenu_free(app->submenu); - variable_item_list_free(app->variable_item_list); + view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewDialog); dialog_ex_free(app->dialog); + view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewVariableItemList); + variable_item_list_free(app->variable_item_list); + // View dispatcher view_dispatcher_free(app->view_dispatcher); scene_manager_free(app->scene_manager); + // Records furi_record_close(RECORD_POWER); furi_record_close(RECORD_GUI); + free(app); } diff --git a/applications/settings/power_settings_app/power_settings_app.h b/applications/settings/power_settings_app/power_settings_app.h index 383163ac3..c128215d0 100644 --- a/applications/settings/power_settings_app/power_settings_app.h +++ b/applications/settings/power_settings_app/power_settings_app.h @@ -12,7 +12,7 @@ #include #include -#include "power_settings.h" +#include #include "scenes/power_settings_scene.h" typedef struct { @@ -26,6 +26,7 @@ typedef struct { PowerInfo info; VariableItemList* variable_item_list; uint32_t shutdown_idle_delay_ms; + FuriPubSub* settings_events; } PowerSettingsApp; typedef enum { diff --git a/applications/settings/power_settings_app/scenes/power_settings_scene_shutdown_idle.c b/applications/settings/power_settings_app/scenes/power_settings_scene_shutdown_idle.c index 574050e5c..30304bec6 100644 --- a/applications/settings/power_settings_app/scenes/power_settings_scene_shutdown_idle.c +++ b/applications/settings/power_settings_app/scenes/power_settings_scene_shutdown_idle.c @@ -10,8 +10,6 @@ const char* const shutdown_idle_delay_text[SHUTDOWN_IDLE_DELAY_COUNT] = const uint32_t shutdown_idle_delay_value[SHUTDOWN_IDLE_DELAY_COUNT] = {0, 900000, 1800000, 3600000, 21600000, 43200000, 86400000, 172800000}; -uint32_t origShutdownIdleDelay_value = 0; - static void power_settings_scene_shutodwn_idle_callback(void* context, uint32_t index) { PowerSettingsApp* app = context; view_dispatcher_send_custom_event(app->view_dispatcher, index); @@ -31,7 +29,6 @@ void power_settings_scene_shutdown_idle_on_enter(void* context) { VariableItemList* variable_item_list = app->variable_item_list; VariableItem* item; uint8_t value_index; - origShutdownIdleDelay_value = app->shutdown_idle_delay_ms; item = variable_item_list_add( variable_item_list, @@ -66,9 +63,6 @@ bool power_settings_scene_shutdown_idle_on_event(void* context, SceneManagerEven void power_settings_scene_shutdown_idle_on_exit(void* context) { PowerSettingsApp* app = context; SAVE_POWER_SETTINGS(&app->shutdown_idle_delay_ms); + furi_pubsub_publish(app->settings_events, &app->shutdown_idle_delay_ms); variable_item_list_reset(app->variable_item_list); - - if(app->shutdown_idle_delay_ms != origShutdownIdleDelay_value) { - furi_hal_power_reset(); - } } diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 233308071..b63392d02 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1842,6 +1842,7 @@ Function,-,pow10f,float,float Function,-,power_enable_low_battery_level_notification,void,"Power*, _Bool" Function,+,power_get_info,void,"Power*, PowerInfo*" Function,+,power_get_pubsub,FuriPubSub*,Power* +Function,+,power_get_settings_events_pubsub,FuriPubSub*,Power* Function,+,power_is_battery_healthy,_Bool,Power* Function,+,power_off,void,Power* Function,+,power_reboot,void,PowerBootMode