Auto_poweroff option moved from desktop to power.

Add settings for power service (load|save).
This commit is contained in:
Dmitry422
2025-01-14 02:01:54 +07:00
parent 1a95757a75
commit c73495767c
16 changed files with 375 additions and 146 deletions

View File

@@ -19,12 +19,6 @@ static void desktop_auto_lock_arm(Desktop*);
static void desktop_auto_lock_inhibit(Desktop*); static void desktop_auto_lock_inhibit(Desktop*);
static void desktop_start_auto_lock_timer(Desktop*); static void desktop_start_auto_lock_timer(Desktop*);
static void desktop_apply_settings(Desktop*); static void desktop_apply_settings(Desktop*);
//--- auto_power_off_timer
#include <power/power_service/power.h>
static void desktop_start_auto_poweroff_timer(Desktop*);
static void desktop_auto_poweroff_arm(Desktop*);
static void desktop_auto_poweroff_inhibit(Desktop*);
//---
static void desktop_loader_callback(const void* message, void* context) { static void desktop_loader_callback(const void* message, void* context) {
furi_assert(context); furi_assert(context);
@@ -137,9 +131,7 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) {
} }
desktop_auto_lock_inhibit(desktop); desktop_auto_lock_inhibit(desktop);
//--- auto_power_off_timer
desktop_auto_poweroff_inhibit(desktop);
//--
desktop->app_running = true; desktop->app_running = true;
furi_semaphore_release(desktop->animation_semaphore); furi_semaphore_release(desktop->animation_semaphore);
@@ -147,20 +139,12 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) {
} else if(event == DesktopGlobalAfterAppFinished) { } else if(event == DesktopGlobalAfterAppFinished) {
animation_manager_load_and_continue_animation(desktop->animation_manager); animation_manager_load_and_continue_animation(desktop->animation_manager);
desktop_auto_lock_arm(desktop); desktop_auto_lock_arm(desktop);
//--- auto_power_off_timer
desktop_auto_poweroff_arm(desktop);
//---
desktop->app_running = false; desktop->app_running = false;
} else if(event == DesktopGlobalAutoLock) { } else if(event == DesktopGlobalAutoLock) {
if(!desktop->app_running && !desktop->locked) { if(!desktop->app_running && !desktop->locked) {
desktop_lock(desktop); desktop_lock(desktop);
} }
} else if(event == DesktopGlobalAutoPowerOff) {
if(!desktop->app_running) {
Power* power = furi_record_open(RECORD_POWER);
power_off(power);
}
} else if(event == DesktopGlobalSaveSettings) { } else if(event == DesktopGlobalSaveSettings) {
desktop_settings_save(&desktop->settings); desktop_settings_save(&desktop->settings);
desktop_apply_settings(desktop); desktop_apply_settings(desktop);
@@ -195,9 +179,6 @@ static void desktop_input_event_callback(const void* value, void* context) {
Desktop* desktop = context; Desktop* desktop = context;
if(event->type == InputTypePress) { if(event->type == InputTypePress) {
desktop_start_auto_lock_timer(desktop); desktop_start_auto_lock_timer(desktop);
//--- auto_power_off_timer
desktop_start_auto_poweroff_timer(desktop);
//---
} }
} }
@@ -234,41 +215,6 @@ static void desktop_auto_lock_inhibit(Desktop* desktop) {
} }
} }
//--- auto_power_off_timer
static void desktop_auto_poweroff_timer_callback(void* context) {
furi_assert(context);
Desktop* desktop = context;
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalAutoPowerOff);
}
static void desktop_start_auto_poweroff_timer(Desktop* desktop) {
furi_timer_start(
desktop->auto_poweroff_timer, furi_ms_to_ticks(desktop->settings.auto_poweroff_delay_ms));
}
static void desktop_stop_auto_poweroff_timer(Desktop* desktop) {
furi_timer_stop(desktop->auto_poweroff_timer);
}
static void desktop_auto_poweroff_arm(Desktop* desktop) {
if(desktop->settings.auto_poweroff_delay_ms) {
if(!desktop->input_events_subscription) {
desktop->input_events_subscription = furi_pubsub_subscribe(
desktop->input_events_pubsub, desktop_input_event_callback, desktop);
}
desktop_start_auto_poweroff_timer(desktop);
}
}
static void desktop_auto_poweroff_inhibit(Desktop* desktop) {
desktop_stop_auto_poweroff_timer(desktop);
if(desktop->input_events_subscription) {
furi_pubsub_unsubscribe(desktop->input_events_pubsub, desktop->input_events_subscription);
desktop->input_events_subscription = NULL;
}
}
//---
static void desktop_clock_timer_callback(void* context) { static void desktop_clock_timer_callback(void* context) {
furi_assert(context); furi_assert(context);
Desktop* desktop = context; Desktop* desktop = context;
@@ -294,9 +240,6 @@ static void desktop_apply_settings(Desktop* desktop) {
if(!desktop->app_running && !desktop->locked) { if(!desktop->app_running && !desktop->locked) {
desktop_auto_lock_arm(desktop); desktop_auto_lock_arm(desktop);
//--- auto_power_off_timer
desktop_auto_poweroff_arm(desktop);
//---
} }
desktop->in_transition = false; desktop->in_transition = false;
@@ -432,10 +375,6 @@ static Desktop* desktop_alloc(void) {
desktop->auto_lock_timer = desktop->auto_lock_timer =
furi_timer_alloc(desktop_auto_lock_timer_callback, FuriTimerTypeOnce, desktop); furi_timer_alloc(desktop_auto_lock_timer_callback, FuriTimerTypeOnce, desktop);
//--- auto_power_off_timer
desktop->auto_poweroff_timer =
furi_timer_alloc(desktop_auto_poweroff_timer_callback, FuriTimerTypeOnce, desktop);
//---
desktop->status_pubsub = furi_pubsub_alloc(); desktop->status_pubsub = furi_pubsub_alloc();

View File

@@ -75,9 +75,6 @@ struct Desktop {
FuriTimer* auto_lock_timer; FuriTimer* auto_lock_timer;
FuriTimer* update_clock_timer; FuriTimer* update_clock_timer;
//--- auto_power_off_timer
FuriTimer* auto_poweroff_timer;
//---
AnimationManager* animation_manager; AnimationManager* animation_manager;
FuriSemaphore* animation_semaphore; FuriSemaphore* animation_semaphore;

View File

@@ -6,8 +6,8 @@
#define TAG "DesktopSettings" #define TAG "DesktopSettings"
#define DESKTOP_SETTINGS_VER_14 (14) #define DESKTOP_SETTINGS_VER_15 (15)
#define DESKTOP_SETTINGS_VER (15) #define DESKTOP_SETTINGS_VER (16)
#define DESKTOP_SETTINGS_PATH INT_PATH(DESKTOP_SETTINGS_FILE_NAME) #define DESKTOP_SETTINGS_PATH INT_PATH(DESKTOP_SETTINGS_FILE_NAME)
#define DESKTOP_SETTINGS_MAGIC (0x17) #define DESKTOP_SETTINGS_MAGIC (0x17)
@@ -19,7 +19,7 @@ typedef struct {
uint8_t display_clock; uint8_t display_clock;
FavoriteApp favorite_apps[FavoriteAppNumber]; FavoriteApp favorite_apps[FavoriteAppNumber];
FavoriteApp dummy_apps[DummyAppNumber]; FavoriteApp dummy_apps[DummyAppNumber];
} DesktopSettingsV14; } DesktopSettingsV15;
// Actual size of DesktopSettings v13 // Actual size of DesktopSettings v13
//static_assert(sizeof(DesktopSettingsV13) == 1234); //static_assert(sizeof(DesktopSettingsV13) == 1234);
@@ -41,31 +41,30 @@ void desktop_settings_load(DesktopSettings* settings) {
DESKTOP_SETTINGS_MAGIC, DESKTOP_SETTINGS_MAGIC,
DESKTOP_SETTINGS_VER); DESKTOP_SETTINGS_VER);
} else if(version == DESKTOP_SETTINGS_VER_14) { } else if(version == DESKTOP_SETTINGS_VER_15) {
DesktopSettingsV14* settings_v14 = malloc(sizeof(DesktopSettingsV14)); DesktopSettingsV15* settings_v15 = malloc(sizeof(DesktopSettingsV15));
success = saved_struct_load( success = saved_struct_load(
DESKTOP_SETTINGS_PATH, DESKTOP_SETTINGS_PATH,
settings_v14, settings_v15,
sizeof(DesktopSettingsV14), sizeof(DesktopSettingsV15),
DESKTOP_SETTINGS_MAGIC, DESKTOP_SETTINGS_MAGIC,
DESKTOP_SETTINGS_VER_14); DESKTOP_SETTINGS_VER_15);
if(success) { if(success) {
settings->auto_lock_delay_ms = settings_v14->auto_lock_delay_ms; settings->auto_lock_delay_ms = settings_v15->auto_lock_delay_ms;
settings->auto_poweroff_delay_ms = 0; settings->displayBatteryPercentage = settings_v15->displayBatteryPercentage;
settings->displayBatteryPercentage = settings_v14->displayBatteryPercentage; settings->dummy_mode = settings_v15->dummy_mode;
settings->dummy_mode = settings_v14->dummy_mode; settings->display_clock = settings_v15->display_clock;
settings->display_clock = settings_v14->display_clock;
memcpy( memcpy(
settings->favorite_apps, settings->favorite_apps,
settings_v14->favorite_apps, settings_v15->favorite_apps,
sizeof(settings->favorite_apps)); sizeof(settings->favorite_apps));
memcpy( memcpy(
settings->dummy_apps, settings_v14->dummy_apps, sizeof(settings->dummy_apps)); settings->dummy_apps, settings_v15->dummy_apps, sizeof(settings->dummy_apps));
} }
free(settings_v14); free(settings_v15);
} }
} while(false); } while(false);

View File

@@ -38,9 +38,6 @@ typedef struct {
typedef struct { typedef struct {
uint32_t auto_lock_delay_ms; uint32_t auto_lock_delay_ms;
//--- auto_power_off_timer
uint32_t auto_poweroff_delay_ms;
//---
uint8_t displayBatteryPercentage; uint8_t displayBatteryPercentage;
uint8_t dummy_mode; uint8_t dummy_mode;
uint8_t display_clock; uint8_t display_clock;

View File

@@ -62,5 +62,4 @@ typedef enum {
DesktopGlobalApiUnlock, DesktopGlobalApiUnlock,
DesktopGlobalSaveSettings, DesktopGlobalSaveSettings,
DesktopGlobalReloadSettings, DesktopGlobalReloadSettings,
DesktopGlobalAutoPowerOff,
} DesktopEvent; } DesktopEvent;

View File

@@ -7,6 +7,8 @@
#include <update_util/update_operation.h> #include <update_util/update_operation.h>
#include <notification/notification_messages.h> #include <notification/notification_messages.h>
#include <loader/loader.h>
#define TAG "Power" #define TAG "Power"
#define POWER_OFF_TIMEOUT_S (90U) #define POWER_OFF_TIMEOUT_S (90U)
@@ -379,7 +381,120 @@ static void power_handle_reboot(PowerBootMode mode) {
furi_hal_power_reset(); furi_hal_power_reset();
} }
// get settings from service to settings_app by send message to power queue
void power_api_get_settings(Power* power, PowerSettings* settings) {
furi_assert(power);
furi_assert(settings);
PowerMessage msg = {
.type = PowerMessageTypeGetSettings,
.settings = settings,
.lock = api_lock_alloc_locked(),
};
furi_check(
furi_message_queue_put(power->message_queue, &msg, FuriWaitForever) == FuriStatusOk);
api_lock_wait_unlock_and_free(msg.lock);
}
// set settings from settings_app to service by send message to power queue
void power_api_set_settings(Power* power, const PowerSettings* settings) {
furi_assert(power);
furi_assert(settings);
PowerMessage msg = {
.type = PowerMessageTypeSetSettings,
.csettings = settings,
.lock = api_lock_alloc_locked(),
};
furi_check(
furi_message_queue_put(power->message_queue, &msg, FuriWaitForever) == FuriStatusOk);
api_lock_wait_unlock_and_free(msg.lock);
}
//start furi timer for autopoweroff
static void power_start_auto_poweroff_timer(Power* power) {
furi_timer_start(
power->p_auto_poweroff_timer, furi_ms_to_ticks(power->settings.p_auto_poweroff_delay_ms));
}
//stop furi timer for autopoweroff
static void power_stop_auto_poweroff_timer(Power* power) {
furi_timer_stop(power->p_auto_poweroff_timer);
}
static uint32_t power_is_running_auto_poweroff_timer(Power* power) {
return furi_timer_is_running(power->p_auto_poweroff_timer);
}
// start|restart poweroff timer
static void power_auto_poweroff_callback(const void* value, void* context) {
furi_assert(value);
furi_assert(context);
Power* power = context;
power_start_auto_poweroff_timer(power);
}
// callback for poweroff timer (what we do when timer end)
static void power_auto_poweroff_timer_callback(void* context) {
furi_assert(context);
Power* power = context;
power_off(power);
}
//start|restart timer and events subscription and callbacks for input events (we restart timer when user press keys)
static void power_auto_poweroff_arm(Power* power) {
if(power->settings.p_auto_poweroff_delay_ms) {
if(power->input_events_subscription == NULL) {
power->input_events_subscription = furi_pubsub_subscribe(
power->input_events_pubsub, power_auto_poweroff_callback, power);
}
power_start_auto_poweroff_timer(power);
}
}
// stop timer and event subscription
static void power_auto_poweroff_disarm(Power* power) {
power_stop_auto_poweroff_timer(power);
if(power->input_events_subscription) {
furi_pubsub_unsubscribe(power->input_events_pubsub, power->input_events_subscription);
power->input_events_subscription = NULL;
}
}
//check message queue from Loader - is some app started or not (if started we dont do auto poweroff)
static void power_loader_callback(const void* message, void* context) {
furi_assert(context);
Power* power = context;
const LoaderEvent* event = message;
// disarm timer if some apps started
if(event->type == LoaderEventTypeApplicationBeforeLoad) {
power->app_running = true;
power_auto_poweroff_disarm(power);
// arm timer if some apps was not loaded or was stoped
} else if(
event->type == LoaderEventTypeApplicationLoadFailed ||
event->type == LoaderEventTypeApplicationStopped) {
power->app_running = false;
power_auto_poweroff_arm(power);
}
}
// apply power settings
static void power_settings_apply(Power* power) {
//apply auto_poweroff settings
if(power->settings.p_auto_poweroff_delay_ms && !power->app_running) {
return;
power_auto_poweroff_arm(power);
} else if (power_is_running_auto_poweroff_timer(power)) {
power_auto_poweroff_disarm(power);
}
return;
}
// do something depend from power queue message
static void power_message_callback(FuriEventLoopObject* object, void* context) { static void power_message_callback(FuriEventLoopObject* object, void* context) {
furi_assert(context); furi_assert(context);
Power* power = context; Power* power = context;
@@ -405,6 +520,20 @@ static void power_message_callback(FuriEventLoopObject* object, void* context) {
case PowerMessageTypeShowBatteryLowWarning: case PowerMessageTypeShowBatteryLowWarning:
power->show_battery_low_warning = *msg.bool_param; power->show_battery_low_warning = *msg.bool_param;
break; break;
case PowerMessageTypeGetSettings:
furi_assert(msg.lock);
*msg.settings = power->settings;
break;
case PowerMessageTypeSetSettings:
furi_assert(msg.lock);
power->settings = *msg.csettings;
power_settings_apply(power);
power_settings_save(&power->settings);
break;
case PowerMessageTypeReloadSettings:
power_settings_load(&power->settings);
power_settings_apply(power);
break;
default: default:
furi_crash(); furi_crash();
} }
@@ -436,6 +565,36 @@ static void power_tick_callback(void* context) {
} }
} }
static void power_storage_callback(const void* message, void* context) {
furi_assert(context);
Power* power = context;
const StorageEvent* event = message;
if(event->type == StorageEventTypeCardMount) {
PowerMessage msg = {
.type = PowerMessageTypeReloadSettings,
};
furi_check(
furi_message_queue_put(power->message_queue, &msg, FuriWaitForever) == FuriStatusOk);
}
}
// load inital settings from file for power service
static void power_init_settings(Power* power) {
Storage* storage = furi_record_open(RECORD_STORAGE);
furi_pubsub_subscribe(storage_get_pubsub(storage), power_storage_callback, power);
if(storage_sd_status(storage) != FSE_OK) {
FURI_LOG_D(TAG, "SD Card not ready, skipping settings");
return;
}
power_settings_load(&power->settings);
power_settings_apply(power);
furi_record_close(RECORD_STORAGE);
}
static Power* power_alloc(void) { static Power* power_alloc(void) {
Power* power = malloc(sizeof(Power)); Power* power = malloc(sizeof(Power));
// Pubsub // Pubsub
@@ -449,6 +608,16 @@ static Power* power_alloc(void) {
desktop_settings_load(settings); desktop_settings_load(settings);
power->displayBatteryPercentage = settings->displayBatteryPercentage; power->displayBatteryPercentage = settings->displayBatteryPercentage;
free(settings); free(settings);
// auto_poweroff
//---define subscription to loader events message (info about started apps) and defina callback for this
Loader* loader = furi_record_open(RECORD_LOADER);
furi_pubsub_subscribe(loader_get_pubsub(loader), power_loader_callback, power);
power->input_events_pubsub = furi_record_open(RECORD_INPUT_EVENTS);
//define autopoweroff timer and they callback
power->p_auto_poweroff_timer =
furi_timer_alloc(power_auto_poweroff_timer_callback, FuriTimerTypeOnce, power);
// Gui // Gui
Gui* gui = furi_record_open(RECORD_GUI); Gui* gui = furi_record_open(RECORD_GUI);
@@ -489,6 +658,15 @@ int32_t power_srv(void* p) {
power_update_info(power); power_update_info(power);
furi_record_create(RECORD_POWER, power); furi_record_create(RECORD_POWER, power);
// Can't be done in alloc, other things in startup need power service and it would deadlock by waiting for loader
Loader* loader = furi_record_open(RECORD_LOADER);
power->app_running = loader_is_locked(loader);
furi_record_close(RECORD_LOADER);
// load inital settings for power service
power_init_settings(power);
furi_event_loop_run(power->event_loop); furi_event_loop_run(power->event_loop);
return 0; return 0;

View File

@@ -2,7 +2,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <power/power_service/power_settings.h>
#include <core/pubsub.h> #include <core/pubsub.h>
#ifdef __cplusplus #ifdef __cplusplus
@@ -102,6 +102,12 @@ void power_enable_low_battery_level_notification(Power* power, bool enable);
*/ */
void power_trigger_ui_update(Power* power); void power_trigger_ui_update(Power* power);
// get settings from service to app
void power_api_get_settings(Power* instance, PowerSettings* settings);
// set settings from app to service
void power_api_set_settings(Power* instance, const PowerSettings* settings);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -36,6 +36,11 @@ struct Power {
uint8_t displayBatteryPercentage; uint8_t displayBatteryPercentage;
uint8_t battery_level; uint8_t battery_level;
uint8_t power_off_timeout; uint8_t power_off_timeout;
PowerSettings settings;
FuriTimer* p_auto_poweroff_timer;
bool app_running;
FuriPubSub* input_events_pubsub;
FuriPubSubSubscription* input_events_subscription;
}; };
typedef enum { typedef enum {
@@ -49,6 +54,9 @@ typedef enum {
PowerMessageTypeGetInfo, PowerMessageTypeGetInfo,
PowerMessageTypeIsBatteryHealthy, PowerMessageTypeIsBatteryHealthy,
PowerMessageTypeShowBatteryLowWarning, PowerMessageTypeShowBatteryLowWarning,
PowerMessageTypeGetSettings,
PowerMessageTypeSetSettings,
PowerMessageTypeReloadSettings,
} PowerMessageType; } PowerMessageType;
typedef struct { typedef struct {
@@ -57,6 +65,8 @@ typedef struct {
PowerBootMode boot_mode; PowerBootMode boot_mode;
PowerInfo* power_info; PowerInfo* power_info;
bool* bool_param; bool* bool_param;
PowerSettings* settings;
const PowerSettings* csettings;
}; };
FuriApiLock lock; FuriApiLock lock;
} PowerMessage; } PowerMessage;

View File

@@ -0,0 +1,75 @@
#include "power_settings.h"
#include "power_settings_filename.h"
#include <saved_struct.h>
#include <storage/storage.h>
#define TAG "PowerSettings"
#define POWER_SETTINGS_VER_0 (0) // OLD version number
#define POWER_SETTINGS_VER (1) // NEW actual version nnumber
#define POWER_SETTINGS_PATH INT_PATH(POWER_SETTINGS_FILE_NAME)
#define POWER_SETTINGS_MAGIC (0x18)
typedef struct {
//inital set - empty
} PowerSettingsV0;
void power_settings_load(PowerSettings* settings) {
furi_assert(settings);
bool success = false;
do {
uint8_t version;
if(!saved_struct_get_metadata(POWER_SETTINGS_PATH, NULL, &version, NULL)) break;
if(version == POWER_SETTINGS_VER) { // if config actual version - load it directly
success = saved_struct_load(
POWER_SETTINGS_PATH,
settings,
sizeof(PowerSettings),
POWER_SETTINGS_MAGIC,
POWER_SETTINGS_VER);
} else if(version == POWER_SETTINGS_VER_0) { // if config previous version - load it and manual set new settings to inital value
PowerSettingsV0* settings_v0 = malloc(sizeof(PowerSettingsV0));
success = saved_struct_load(
POWER_SETTINGS_PATH,
settings_v0,
sizeof(PowerSettingsV0),
POWER_SETTINGS_MAGIC,
POWER_SETTINGS_VER_0);
if(success) {
settings->p_auto_poweroff_delay_ms = 0;
}
free(settings_v0);
}
} while(false);
if(!success) {
FURI_LOG_W(TAG, "Failed to load file, using defaults");
memset(settings, 0, sizeof(PowerSettings));
power_settings_save(settings);
}
}
void power_settings_save(const PowerSettings* settings) {
furi_assert(settings);
const bool success = saved_struct_save(
POWER_SETTINGS_PATH,
settings,
sizeof(PowerSettings),
POWER_SETTINGS_MAGIC,
POWER_SETTINGS_VER);
if(!success) {
FURI_LOG_E(TAG, "Failed to save file");
}
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include <stdint.h>
typedef struct {
uint32_t p_auto_poweroff_delay_ms;
} PowerSettings;
#ifdef __cplusplus
extern "C" {
#endif
void power_settings_load(PowerSettings* settings);
void power_settings_save(const PowerSettings* settings);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,3 @@
#pragma once
#define POWER_SETTINGS_FILE_NAME ".power.settings"

View File

@@ -29,15 +29,6 @@ typedef enum {
DesktopSettingsDummyOkLong, DesktopSettingsDummyOkLong,
} DesktopSettingsEntry; } DesktopSettingsEntry;
// --- auto_power_off_timer
#define AUTO_POWEROFF_DELAY_COUNT 8
const char* const auto_poweroff_delay_text[AUTO_POWEROFF_DELAY_COUNT] =
{"OFF", "5min", "10min", "15min", "30min", "45min", "60min", "90min"};
const uint32_t auto_poweroff_delay_value[AUTO_POWEROFF_DELAY_COUNT] =
{0, 300000, 600000, 900000, 1800000, 2700000, 3600000, 5400000};
// ---
#define AUTO_LOCK_DELAY_COUNT 9 #define AUTO_LOCK_DELAY_COUNT 9
const char* const auto_lock_delay_text[AUTO_LOCK_DELAY_COUNT] = { const char* const auto_lock_delay_text[AUTO_LOCK_DELAY_COUNT] = {
"OFF", "OFF",
@@ -96,16 +87,6 @@ static void desktop_settings_scene_start_clock_enable_changed(VariableItem* item
app->settings.display_clock = index; app->settings.display_clock = index;
} }
// --- auto_power_off_timer
static void desktop_settings_scene_start_auto_poweroff_delay_changed(VariableItem* item) {
DesktopSettingsApp* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, auto_poweroff_delay_text[index]);
app->settings.auto_poweroff_delay_ms = auto_poweroff_delay_value[index];
}
// ---
static void desktop_settings_scene_start_auto_lock_delay_changed(VariableItem* item) { static void desktop_settings_scene_start_auto_lock_delay_changed(VariableItem* item) {
DesktopSettingsApp* app = variable_item_get_context(item); DesktopSettingsApp* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item); uint8_t index = variable_item_get_current_value_index(item);
@@ -135,22 +116,6 @@ void desktop_settings_scene_start_on_enter(void* context) {
variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, auto_lock_delay_text[value_index]); variable_item_set_current_value_text(item, auto_lock_delay_text[value_index]);
// --- auto_power_off_timer
item = variable_item_list_add(
variable_item_list,
"Auto PowerOff",
AUTO_POWEROFF_DELAY_COUNT,
desktop_settings_scene_start_auto_poweroff_delay_changed,
app);
value_index = value_index_uint32(
app->settings.auto_poweroff_delay_ms,
auto_poweroff_delay_value,
AUTO_POWEROFF_DELAY_COUNT);
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, auto_poweroff_delay_text[value_index]);
// ---
item = variable_item_list_add( item = variable_item_list_add(
variable_item_list, variable_item_list,
"Battery View", "Battery View",

View File

@@ -46,10 +46,16 @@ PowerSettingsApp* power_settings_app_alloc(uint32_t first_scene) {
app->submenu = submenu_alloc(); app->submenu = submenu_alloc();
view_dispatcher_add_view( view_dispatcher_add_view(
app->view_dispatcher, PowerSettingsAppViewSubmenu, submenu_get_view(app->submenu)); app->view_dispatcher, PowerSettingsAppViewSubmenu, submenu_get_view(app->submenu));
app->variable_item_list = variable_item_list_alloc();
view_dispatcher_add_view(
app->view_dispatcher, PowerSettingsAppViewVariableItemList, variable_item_list_get_view(app->variable_item_list));
app->dialog = dialog_ex_alloc(); app->dialog = dialog_ex_alloc();
view_dispatcher_add_view( view_dispatcher_add_view(
app->view_dispatcher, PowerSettingsAppViewDialog, dialog_ex_get_view(app->dialog)); app->view_dispatcher, PowerSettingsAppViewDialog, dialog_ex_get_view(app->dialog));
// get settings from service to app
power_api_get_settings(app->power, &app->settings);
// Set first scene // Set first scene
scene_manager_next_scene(app->scene_manager, first_scene); scene_manager_next_scene(app->scene_manager, first_scene);
return app; return app;
@@ -57,16 +63,23 @@ PowerSettingsApp* power_settings_app_alloc(uint32_t first_scene) {
void power_settings_app_free(PowerSettingsApp* app) { void power_settings_app_free(PowerSettingsApp* app) {
furi_assert(app); furi_assert(app);
// set settings from app to service
power_api_set_settings(app->power, &app->settings);
// Views // Views
view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewBatteryInfo); view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewBatteryInfo);
battery_info_free(app->battery_info); battery_info_free(app->battery_info);
view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewSubmenu); view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewSubmenu);
submenu_free(app->submenu); submenu_free(app->submenu);
view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewVariableItemList);
variable_item_list_free(app->variable_item_list);
view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewDialog); view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewDialog);
dialog_ex_free(app->dialog); dialog_ex_free(app->dialog);
// View dispatcher // View dispatcher
view_dispatcher_free(app->view_dispatcher); view_dispatcher_free(app->view_dispatcher);
scene_manager_free(app->scene_manager); scene_manager_free(app->scene_manager);
// Records // Records
furi_record_close(RECORD_POWER); furi_record_close(RECORD_POWER);
furi_record_close(RECORD_GUI); furi_record_close(RECORD_GUI);

View File

@@ -2,6 +2,7 @@
#include <furi.h> #include <furi.h>
#include <power/power_service/power.h> #include <power/power_service/power.h>
#include <power/power_service/power_settings.h>
#include <gui/gui.h> #include <gui/gui.h>
#include <gui/view.h> #include <gui/view.h>
#include <gui/view_dispatcher.h> #include <gui/view_dispatcher.h>
@@ -10,11 +11,13 @@
#include "views/battery_info.h" #include "views/battery_info.h"
#include <gui/modules/submenu.h> #include <gui/modules/submenu.h>
#include <gui/modules/variable_item_list.h>
#include <gui/modules/dialog_ex.h> #include <gui/modules/dialog_ex.h>
#include "scenes/power_settings_scene.h" #include "scenes/power_settings_scene.h"
typedef struct { typedef struct {
PowerSettings settings;
Power* power; Power* power;
Gui* gui; Gui* gui;
SceneManager* scene_manager; SceneManager* scene_manager;
@@ -23,12 +26,14 @@ typedef struct {
Submenu* submenu; Submenu* submenu;
DialogEx* dialog; DialogEx* dialog;
PowerInfo info; PowerInfo info;
VariableItemList* variable_item_list;
} PowerSettingsApp; } PowerSettingsApp;
typedef enum { typedef enum {
PowerSettingsAppViewBatteryInfo, PowerSettingsAppViewBatteryInfo,
PowerSettingsAppViewSubmenu, PowerSettingsAppViewSubmenu,
PowerSettingsAppViewDialog, PowerSettingsAppViewDialog,
PowerSettingsAppViewVariableItemList
} PowerSettingsAppView; } PowerSettingsAppView;
typedef enum { typedef enum {

View File

@@ -1,12 +1,30 @@
#include "../power_settings_app.h" #include "../power_settings_app.h"
#include <lib/toolbox/value_index.h>
enum PowerSettingsSubmenuIndex { enum PowerSettingsSubmenuIndex {
PowerSettingsSubmenuIndexAutoPowerOff,
PowerSettingsSubmenuIndexBatteryInfo, PowerSettingsSubmenuIndexBatteryInfo,
PowerSettingsSubmenuIndexReboot, PowerSettingsSubmenuIndexReboot,
PowerSettingsSubmenuIndexOff, PowerSettingsSubmenuIndexOff,
}; };
static void power_settings_scene_start_submenu_callback(void* context, uint32_t index) { #define P_AUTO_POWEROFF_DELAY_COUNT 9
const char* const p_auto_poweroff_delay_text[P_AUTO_POWEROFF_DELAY_COUNT] =
{"OFF","5 sec" ,"5min", "10min", "15min", "30min", "45min", "60min", "90min"};
const uint32_t p_auto_poweroff_delay_value[P_AUTO_POWEROFF_DELAY_COUNT] =
{0, 5000, 300000, 600000, 900000, 1800000, 2700000, 3600000, 5400000};
// change variable_item_list visible text and app_poweroff_delay_time_settings when user change item in variable_item_list
static void power_settings_scene_start_auto_poweroff_delay_changed(VariableItem* item) {
PowerSettingsApp* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, p_auto_poweroff_delay_text[index]);
app->settings.p_auto_poweroff_delay_ms = p_auto_poweroff_delay_value[index];
}
static void power_settings_scene_start_submenu_callback(void* context, uint32_t index) { //show selected menu screen
furi_assert(context); furi_assert(context);
PowerSettingsApp* app = context; PowerSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, index); view_dispatcher_send_custom_event(app->view_dispatcher, index);
@@ -14,30 +32,34 @@ static void power_settings_scene_start_submenu_callback(void* context, uint32_t
void power_settings_scene_start_on_enter(void* context) { void power_settings_scene_start_on_enter(void* context) {
PowerSettingsApp* app = context; PowerSettingsApp* app = context;
Submenu* submenu = app->submenu; VariableItemList* variable_item_list = app->variable_item_list;
submenu_add_item( VariableItem* item;
submenu, uint8_t value_index;
"Battery Info", item = variable_item_list_add(
PowerSettingsSubmenuIndexBatteryInfo, variable_item_list,
power_settings_scene_start_submenu_callback, "Auto PowerOff Time",
P_AUTO_POWEROFF_DELAY_COUNT,
power_settings_scene_start_auto_poweroff_delay_changed, //function for change visible item list value and app settings
app); app);
submenu_add_item(
submenu,
"Reboot",
PowerSettingsSubmenuIndexReboot,
power_settings_scene_start_submenu_callback,
app);
submenu_add_item(
submenu,
"Power OFF",
PowerSettingsSubmenuIndexOff,
power_settings_scene_start_submenu_callback,
app);
submenu_set_selected_item(
submenu, scene_manager_get_scene_state(app->scene_manager, PowerSettingsAppSceneStart));
view_dispatcher_switch_to_view(app->view_dispatcher, PowerSettingsAppViewSubmenu); value_index = value_index_uint32(
app->settings.p_auto_poweroff_delay_ms,
p_auto_poweroff_delay_value,
P_AUTO_POWEROFF_DELAY_COUNT);
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, p_auto_poweroff_delay_text[value_index]);
variable_item_list_add(variable_item_list, "Battery Info", 1, NULL, NULL);
variable_item_list_add(variable_item_list, "Reboot", 1, NULL, NULL);
variable_item_list_add(variable_item_list, "Power OFF", 1, NULL, NULL);
variable_item_list_set_selected_item(
variable_item_list, scene_manager_get_scene_state(app->scene_manager, PowerSettingsAppSceneStart));
variable_item_list_set_enter_callback( //callback to show next mennu screen
variable_item_list, power_settings_scene_start_submenu_callback, app);
view_dispatcher_switch_to_view(app->view_dispatcher, PowerSettingsAppViewVariableItemList);
} }
bool power_settings_scene_start_on_event(void* context, SceneManagerEvent event) { bool power_settings_scene_start_on_event(void* context, SceneManagerEvent event) {
@@ -60,5 +82,6 @@ bool power_settings_scene_start_on_event(void* context, SceneManagerEvent event)
void power_settings_scene_start_on_exit(void* context) { void power_settings_scene_start_on_exit(void* context) {
PowerSettingsApp* app = context; PowerSettingsApp* app = context;
submenu_reset(app->submenu); variable_item_list_reset(app->variable_item_list);
power_settings_save(&app->settings); //actual need save every time when use ?
} }

View File

@@ -1,5 +1,5 @@
entry,status,name,type,params entry,status,name,type,params
Version,+,79.2,, Version,+,79.3,,
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
@@ -2993,9 +2993,9 @@ Function,+,pipe_install_as_stdio,void,PipeSide*
Function,+,pipe_receive,size_t,"PipeSide*, void*, size_t, FuriWait" Function,+,pipe_receive,size_t,"PipeSide*, void*, size_t, FuriWait"
Function,+,pipe_role,PipeRole,PipeSide* Function,+,pipe_role,PipeRole,PipeSide*
Function,+,pipe_send,size_t,"PipeSide*, const void*, size_t, FuriWait" Function,+,pipe_send,size_t,"PipeSide*, const void*, size_t, FuriWait"
Function,+,pipe_set_broken_callback,void,"PipeSide*, PipeSideBrokenCallback, FuriEventLoopEvent"
Function,+,pipe_set_callback_context,void,"PipeSide*, void*" Function,+,pipe_set_callback_context,void,"PipeSide*, void*"
Function,+,pipe_set_data_arrived_callback,void,"PipeSide*, PipeSideDataArrivedCallback, FuriEventLoopEvent" Function,+,pipe_set_data_arrived_callback,void,"PipeSide*, PipeSideDataArrivedCallback, FuriEventLoopEvent"
Function,+,pipe_set_broken_callback,void,"PipeSide*, PipeSideBrokenCallback, FuriEventLoopEvent"
Function,+,pipe_set_space_freed_callback,void,"PipeSide*, PipeSideSpaceFreedCallback, FuriEventLoopEvent" Function,+,pipe_set_space_freed_callback,void,"PipeSide*, PipeSideSpaceFreedCallback, FuriEventLoopEvent"
Function,+,pipe_spaces_available,size_t,PipeSide* Function,+,pipe_spaces_available,size_t,PipeSide*
Function,+,pipe_state,PipeState,PipeSide* Function,+,pipe_state,PipeState,PipeSide*
@@ -3023,12 +3023,16 @@ Function,-,posix_memalign,int,"void**, size_t, size_t"
Function,-,pow,double,"double, double" Function,-,pow,double,"double, double"
Function,-,pow10,double,double Function,-,pow10,double,double
Function,-,pow10f,float,float Function,-,pow10f,float,float
Function,+,power_api_get_settings,void,"Power*, PowerSettings*"
Function,+,power_api_set_settings,void,"Power*, const PowerSettings*"
Function,+,power_enable_low_battery_level_notification,void,"Power*, _Bool" Function,+,power_enable_low_battery_level_notification,void,"Power*, _Bool"
Function,+,power_get_info,void,"Power*, PowerInfo*" Function,+,power_get_info,void,"Power*, PowerInfo*"
Function,+,power_get_pubsub,FuriPubSub*,Power* Function,+,power_get_pubsub,FuriPubSub*,Power*
Function,+,power_is_battery_healthy,_Bool,Power* Function,+,power_is_battery_healthy,_Bool,Power*
Function,+,power_off,void,Power* Function,+,power_off,void,Power*
Function,+,power_reboot,void,"Power*, PowerBootMode" Function,+,power_reboot,void,"Power*, PowerBootMode"
Function,+,power_settings_load,void,PowerSettings*
Function,+,power_settings_save,void,const PowerSettings*
Function,-,power_trigger_ui_update,void,Power* Function,-,power_trigger_ui_update,void,Power*
Function,+,powf,float,"float, float" Function,+,powf,float,"float, float"
Function,-,powl,long double,"long double, long double" Function,-,powl,long double,"long double, long double"
1 entry status name type params
2 Version + 79.2 79.3
3 Header + applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h
4 Header + applications/services/bt/bt_service/bt.h
5 Header + applications/services/bt/bt_service/bt_keys_storage.h
2993 Function + pipe_receive size_t PipeSide*, void*, size_t, FuriWait
2994 Function + pipe_role PipeRole PipeSide*
2995 Function + pipe_send size_t PipeSide*, const void*, size_t, FuriWait
2996 Function + pipe_set_broken_callback void PipeSide*, PipeSideBrokenCallback, FuriEventLoopEvent
2997 Function + pipe_set_callback_context void PipeSide*, void*
2998 Function + pipe_set_data_arrived_callback void PipeSide*, PipeSideDataArrivedCallback, FuriEventLoopEvent
Function + pipe_set_broken_callback void PipeSide*, PipeSideBrokenCallback, FuriEventLoopEvent
2999 Function + pipe_set_space_freed_callback void PipeSide*, PipeSideSpaceFreedCallback, FuriEventLoopEvent
3000 Function + pipe_spaces_available size_t PipeSide*
3001 Function + pipe_state PipeState PipeSide*
3023 Function - pow double double, double
3024 Function - pow10 double double
3025 Function - pow10f float float
3026 Function + power_api_get_settings void Power*, PowerSettings*
3027 Function + power_api_set_settings void Power*, const PowerSettings*
3028 Function + power_enable_low_battery_level_notification void Power*, _Bool
3029 Function + power_get_info void Power*, PowerInfo*
3030 Function + power_get_pubsub FuriPubSub* Power*
3031 Function + power_is_battery_healthy _Bool Power*
3032 Function + power_off void Power*
3033 Function + power_reboot void Power*, PowerBootMode
3034 Function + power_settings_load void PowerSettings*
3035 Function + power_settings_save void const PowerSettings*
3036 Function - power_trigger_ui_update void Power*
3037 Function + powf float float, float
3038 Function - powl long double long double, long double