diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index 59c5290f4f..43356cf25c 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -13,18 +13,19 @@ #include "scenes/desktop_scene.h" #include "scenes/desktop_scene_locked.h" +#include "furi_hal_power.h" + #define TAG "Desktop" +// dublicate constants from desktop_setting_scene_start.c +#define USB_INHIBIT_AUTOLOCK_OFF 0 +#define USB_INHIBIT_AUTOLOCK_ON 1 +#define USB_INHIBIT_AUTOLOCK_RPC 2 + static void desktop_auto_lock_arm(Desktop*); static void desktop_auto_lock_inhibit(Desktop*); static void desktop_start_auto_lock_timer(Desktop*); static void desktop_apply_settings(Desktop*); -//--- auto_power_off_timer -#include -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) { furi_assert(context); @@ -137,9 +138,7 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) { } desktop_auto_lock_inhibit(desktop); - //--- auto_power_off_timer - desktop_auto_poweroff_inhibit(desktop); - //-- + desktop->app_running = true; furi_semaphore_release(desktop->animation_semaphore); @@ -147,20 +146,20 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) { } else if(event == DesktopGlobalAfterAppFinished) { animation_manager_load_and_continue_animation(desktop->animation_manager); desktop_auto_lock_arm(desktop); - //--- auto_power_off_timer - desktop_auto_poweroff_arm(desktop); - //--- desktop->app_running = false; } else if(event == DesktopGlobalAutoLock) { if(!desktop->app_running && !desktop->locked) { + // if usb_inhibit_autolock enabled and device charging or device charged but still connected to USB then break desktop locking. + if ((desktop->settings.usb_inhibit_auto_lock == USB_INHIBIT_AUTOLOCK_ON) && ((furi_hal_power_is_charging()) || (furi_hal_power_is_charging_done()))){ + return(0); + } + // if usb_inhibit_autolock set to RPC and we have F0 connected to phone or PC app then break desktop locking. + if (desktop->settings.usb_inhibit_auto_lock == USB_INHIBIT_AUTOLOCK_RPC){ + return(0); + } 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) { desktop_settings_save(&desktop->settings); desktop_apply_settings(desktop); @@ -195,9 +194,6 @@ static void desktop_input_event_callback(const void* value, void* context) { Desktop* desktop = context; if(event->type == InputTypePress) { desktop_start_auto_lock_timer(desktop); - //--- auto_power_off_timer - desktop_start_auto_poweroff_timer(desktop); - //--- } } @@ -234,41 +230,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) { furi_assert(context); Desktop* desktop = context; @@ -294,9 +255,6 @@ static void desktop_apply_settings(Desktop* desktop) { if(!desktop->app_running && !desktop->locked) { desktop_auto_lock_arm(desktop); - //--- auto_power_off_timer - desktop_auto_poweroff_arm(desktop); - //--- } desktop->in_transition = false; @@ -432,10 +390,6 @@ static Desktop* desktop_alloc(void) { desktop->auto_lock_timer = 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(); diff --git a/applications/services/desktop/desktop_i.h b/applications/services/desktop/desktop_i.h index abf5cd579b..1dc7c7d219 100644 --- a/applications/services/desktop/desktop_i.h +++ b/applications/services/desktop/desktop_i.h @@ -75,9 +75,6 @@ struct Desktop { FuriTimer* auto_lock_timer; FuriTimer* update_clock_timer; - //--- auto_power_off_timer - FuriTimer* auto_poweroff_timer; - //--- AnimationManager* animation_manager; FuriSemaphore* animation_semaphore; diff --git a/applications/services/desktop/desktop_settings.c b/applications/services/desktop/desktop_settings.c index 7a99dd3653..bf9215dd26 100644 --- a/applications/services/desktop/desktop_settings.c +++ b/applications/services/desktop/desktop_settings.c @@ -6,20 +6,21 @@ #define TAG "DesktopSettings" -#define DESKTOP_SETTINGS_VER_14 (14) -#define DESKTOP_SETTINGS_VER (15) +#define DESKTOP_SETTINGS_VER_15 (15) +#define DESKTOP_SETTINGS_VER (16) #define DESKTOP_SETTINGS_PATH INT_PATH(DESKTOP_SETTINGS_FILE_NAME) #define DESKTOP_SETTINGS_MAGIC (0x17) typedef struct { uint32_t auto_lock_delay_ms; + uint32_t auto_poweroff_delay_ms; uint8_t displayBatteryPercentage; uint8_t dummy_mode; uint8_t display_clock; FavoriteApp favorite_apps[FavoriteAppNumber]; FavoriteApp dummy_apps[DummyAppNumber]; -} DesktopSettingsV14; +} DesktopSettingsV15; // Actual size of DesktopSettings v13 //static_assert(sizeof(DesktopSettingsV13) == 1234); @@ -41,31 +42,31 @@ void desktop_settings_load(DesktopSettings* settings) { DESKTOP_SETTINGS_MAGIC, DESKTOP_SETTINGS_VER); - } else if(version == DESKTOP_SETTINGS_VER_14) { - DesktopSettingsV14* settings_v14 = malloc(sizeof(DesktopSettingsV14)); + } else if(version == DESKTOP_SETTINGS_VER_15) { + DesktopSettingsV15* settings_v15 = malloc(sizeof(DesktopSettingsV15)); success = saved_struct_load( DESKTOP_SETTINGS_PATH, - settings_v14, - sizeof(DesktopSettingsV14), + settings_v15, + sizeof(DesktopSettingsV15), DESKTOP_SETTINGS_MAGIC, - DESKTOP_SETTINGS_VER_14); + DESKTOP_SETTINGS_VER_15); if(success) { - settings->auto_lock_delay_ms = settings_v14->auto_lock_delay_ms; - settings->auto_poweroff_delay_ms = 0; - settings->displayBatteryPercentage = settings_v14->displayBatteryPercentage; - settings->dummy_mode = settings_v14->dummy_mode; - settings->display_clock = settings_v14->display_clock; + settings->auto_lock_delay_ms = settings_v15->auto_lock_delay_ms; + settings->usb_inhibit_auto_lock = 0; + settings->displayBatteryPercentage = settings_v15->displayBatteryPercentage; + settings->dummy_mode = settings_v15->dummy_mode; + settings->display_clock = settings_v15->display_clock; memcpy( settings->favorite_apps, - settings_v14->favorite_apps, + settings_v15->favorite_apps, sizeof(settings->favorite_apps)); 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); diff --git a/applications/services/desktop/desktop_settings.h b/applications/services/desktop/desktop_settings.h index e2e91d2dd3..784b1eeba5 100644 --- a/applications/services/desktop/desktop_settings.h +++ b/applications/services/desktop/desktop_settings.h @@ -38,9 +38,7 @@ typedef struct { typedef struct { uint32_t auto_lock_delay_ms; - //--- auto_power_off_timer - uint32_t auto_poweroff_delay_ms; - //--- + uint8_t usb_inhibit_auto_lock; uint8_t displayBatteryPercentage; uint8_t dummy_mode; uint8_t display_clock; diff --git a/applications/services/desktop/views/desktop_events.h b/applications/services/desktop/views/desktop_events.h index 57cc0fdaa0..ba91a30ccd 100644 --- a/applications/services/desktop/views/desktop_events.h +++ b/applications/services/desktop/views/desktop_events.h @@ -62,5 +62,4 @@ typedef enum { DesktopGlobalApiUnlock, DesktopGlobalSaveSettings, DesktopGlobalReloadSettings, - DesktopGlobalAutoPowerOff, } DesktopEvent; diff --git a/applications/services/power/power_service/power.c b/applications/services/power/power_service/power.c index 8d387612a8..1814dbd4a5 100644 --- a/applications/services/power/power_service/power.c +++ b/applications/services/power/power_service/power.c @@ -7,6 +7,8 @@ #include #include +#include + #define TAG "Power" #define POWER_OFF_TIMEOUT_S (90U) @@ -379,7 +381,127 @@ static void power_handle_reboot(PowerBootMode mode) { 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->auto_poweroff_timer, furi_ms_to_ticks(power->settings.auto_poweroff_delay_ms)); +} + +//stop furi timer for autopoweroff +static void power_stop_auto_poweroff_timer(Power* power) { + furi_timer_stop(power->auto_poweroff_timer); +} + +static uint32_t power_is_running_auto_poweroff_timer(Power* power) { + return furi_timer_is_running(power->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; + //check charging state and dont poweroff if battery not fully charged + power_check_charging_state(power); + if (power->state == PowerStateCharged) { + power_off(power); + } + else { + FURI_LOG_D(TAG, "We dont auto_power_off until battery is charging"); + } +} + +//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.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.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) { furi_assert(context); Power* power = context; @@ -405,6 +527,20 @@ static void power_message_callback(FuriEventLoopObject* object, void* context) { case PowerMessageTypeShowBatteryLowWarning: power->show_battery_low_warning = *msg.bool_param; 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: furi_crash(); } @@ -436,6 +572,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) { Power* power = malloc(sizeof(Power)); // Pubsub @@ -449,6 +615,16 @@ static Power* power_alloc(void) { desktop_settings_load(settings); power->displayBatteryPercentage = settings->displayBatteryPercentage; 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->auto_poweroff_timer = + furi_timer_alloc(power_auto_poweroff_timer_callback, FuriTimerTypeOnce, power); + // Gui Gui* gui = furi_record_open(RECORD_GUI); @@ -489,6 +665,15 @@ int32_t power_srv(void* p) { power_update_info(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); return 0; diff --git a/applications/services/power/power_service/power.h b/applications/services/power/power_service/power.h index 34d58353a2..59947fa52e 100644 --- a/applications/services/power/power_service/power.h +++ b/applications/services/power/power_service/power.h @@ -2,7 +2,7 @@ #include #include - +#include #include #ifdef __cplusplus @@ -102,6 +102,12 @@ void power_enable_low_battery_level_notification(Power* power, bool enable); */ 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 } #endif diff --git a/applications/services/power/power_service/power_i.h b/applications/services/power/power_service/power_i.h index d75071f8f6..40b4a1ef4e 100644 --- a/applications/services/power/power_service/power_i.h +++ b/applications/services/power/power_service/power_i.h @@ -36,6 +36,11 @@ struct Power { uint8_t displayBatteryPercentage; uint8_t battery_level; uint8_t power_off_timeout; + PowerSettings settings; + FuriTimer* auto_poweroff_timer; + bool app_running; + FuriPubSub* input_events_pubsub; + FuriPubSubSubscription* input_events_subscription; }; typedef enum { @@ -49,6 +54,9 @@ typedef enum { PowerMessageTypeGetInfo, PowerMessageTypeIsBatteryHealthy, PowerMessageTypeShowBatteryLowWarning, + PowerMessageTypeGetSettings, + PowerMessageTypeSetSettings, + PowerMessageTypeReloadSettings, } PowerMessageType; typedef struct { @@ -57,6 +65,8 @@ typedef struct { PowerBootMode boot_mode; PowerInfo* power_info; bool* bool_param; + PowerSettings* settings; + const PowerSettings* csettings; }; FuriApiLock lock; } PowerMessage; diff --git a/applications/services/power/power_service/power_settings.c b/applications/services/power/power_service/power_settings.c new file mode 100644 index 0000000000..9682a65e0c --- /dev/null +++ b/applications/services/power/power_service/power_settings.c @@ -0,0 +1,75 @@ +#include "power_settings.h" +#include "power_settings_filename.h" + +#include +#include + +#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->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"); + } +} diff --git a/applications/services/power/power_service/power_settings.h b/applications/services/power/power_service/power_settings.h new file mode 100644 index 0000000000..0385317523 --- /dev/null +++ b/applications/services/power/power_service/power_settings.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +typedef struct { + uint32_t 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 \ No newline at end of file diff --git a/applications/services/power/power_service/power_settings_filename.h b/applications/services/power/power_service/power_settings_filename.h new file mode 100644 index 0000000000..e8c6fbfced --- /dev/null +++ b/applications/services/power/power_service/power_settings_filename.h @@ -0,0 +1,3 @@ +#pragma once + +#define POWER_SETTINGS_FILE_NAME ".power.settings" diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c index f674380afe..dee9d40be5 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c @@ -29,15 +29,6 @@ typedef enum { DesktopSettingsDummyOkLong, } 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 const char* const auto_lock_delay_text[AUTO_LOCK_DELAY_COUNT] = { "OFF", @@ -54,6 +45,23 @@ const char* const auto_lock_delay_text[AUTO_LOCK_DELAY_COUNT] = { const uint32_t auto_lock_delay_value[AUTO_LOCK_DELAY_COUNT] = {0, 10000, 15000, 30000, 60000, 90000, 120000, 300000, 600000}; +#define USB_INHIBIT_AUTO_LOCK_DELAY_COUNT 3 +#define USB_INHIBIT_AUTOLOCK_OFF 0 +#define USB_INHIBIT_AUTOLOCK_ON 1 +#define USB_INHIBIT_AUTOLOCK_RPC 2 + +const char* const usb_inhibit_auto_lock_delay_text[USB_INHIBIT_AUTO_LOCK_DELAY_COUNT] = { + "OFF", + "ON", + "RPC", +}; + +const uint32_t usb_inhibit_auto_lock_delay_value[USB_INHIBIT_AUTO_LOCK_DELAY_COUNT] = { + USB_INHIBIT_AUTOLOCK_OFF, + USB_INHIBIT_AUTOLOCK_ON, + USB_INHIBIT_AUTOLOCK_RPC, +}; + #define CLOCK_ENABLE_COUNT 2 const char* const clock_enable_text[CLOCK_ENABLE_COUNT] = { "OFF", @@ -96,22 +104,21 @@ static void desktop_settings_scene_start_clock_enable_changed(VariableItem* item app->settings.display_clock = index; } -// --- auto_power_off_timer -static void desktop_settings_scene_start_auto_poweroff_delay_changed(VariableItem* item) { + +static void desktop_settings_scene_start_auto_lock_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]; + variable_item_set_current_value_text(item, auto_lock_delay_text[index]); + app->settings.auto_lock_delay_ms = auto_lock_delay_value[index]; } -// --- -static void desktop_settings_scene_start_auto_lock_delay_changed(VariableItem* item) { +static void desktop_settings_scene_start_usb_inhibit_auto_lock_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_lock_delay_text[index]); - app->settings.auto_lock_delay_ms = auto_lock_delay_value[index]; + variable_item_set_current_value_text(item, usb_inhibit_auto_lock_delay_text[index]); + app->settings.usb_inhibit_auto_lock = usb_inhibit_auto_lock_delay_value[index]; } void desktop_settings_scene_start_on_enter(void* context) { @@ -135,22 +142,19 @@ void desktop_settings_scene_start_on_enter(void* context) { variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, auto_lock_delay_text[value_index]); - // --- auto_power_off_timer + // USB connection Inhibit autolock OFF|ON|with opened RPC session item = variable_item_list_add( variable_item_list, - "Auto PowerOff", - AUTO_POWEROFF_DELAY_COUNT, - desktop_settings_scene_start_auto_poweroff_delay_changed, + "USB disarm Auto Lock", + USB_INHIBIT_AUTO_LOCK_DELAY_COUNT, + desktop_settings_scene_start_usb_inhibit_auto_lock_delay_changed, app); value_index = value_index_uint32( - app->settings.auto_poweroff_delay_ms, - auto_poweroff_delay_value, - AUTO_POWEROFF_DELAY_COUNT); + app->settings.usb_inhibit_auto_lock, usb_inhibit_auto_lock_delay_value, USB_INHIBIT_AUTO_LOCK_DELAY_COUNT); variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, auto_poweroff_delay_text[value_index]); - // --- - + variable_item_set_current_value_text(item, usb_inhibit_auto_lock_delay_text[value_index]); + item = variable_item_list_add( variable_item_list, "Battery View", diff --git a/applications/settings/power_settings_app/power_settings_app.c b/applications/settings/power_settings_app/power_settings_app.c index 57df1344f3..8fa824252b 100644 --- a/applications/settings/power_settings_app/power_settings_app.c +++ b/applications/settings/power_settings_app/power_settings_app.c @@ -46,10 +46,16 @@ PowerSettingsApp* power_settings_app_alloc(uint32_t first_scene) { app->submenu = submenu_alloc(); view_dispatcher_add_view( 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(); view_dispatcher_add_view( 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 scene_manager_next_scene(app->scene_manager, first_scene); return app; @@ -57,16 +63,23 @@ PowerSettingsApp* power_settings_app_alloc(uint32_t first_scene) { void power_settings_app_free(PowerSettingsApp* app) { furi_assert(app); + + // set settings from app to service + power_api_set_settings(app->power, &app->settings); // Views view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewBatteryInfo); battery_info_free(app->battery_info); view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewSubmenu); 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); dialog_ex_free(app->dialog); + // 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); diff --git a/applications/settings/power_settings_app/power_settings_app.h b/applications/settings/power_settings_app/power_settings_app.h index bbbbacd612..f28e6a5485 100644 --- a/applications/settings/power_settings_app/power_settings_app.h +++ b/applications/settings/power_settings_app/power_settings_app.h @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -10,11 +11,13 @@ #include "views/battery_info.h" #include +#include #include #include "scenes/power_settings_scene.h" typedef struct { + PowerSettings settings; Power* power; Gui* gui; SceneManager* scene_manager; @@ -23,12 +26,14 @@ typedef struct { Submenu* submenu; DialogEx* dialog; PowerInfo info; + VariableItemList* variable_item_list; } PowerSettingsApp; typedef enum { PowerSettingsAppViewBatteryInfo, PowerSettingsAppViewSubmenu, PowerSettingsAppViewDialog, + PowerSettingsAppViewVariableItemList } PowerSettingsAppView; typedef enum { diff --git a/applications/settings/power_settings_app/scenes/power_settings_scene_start.c b/applications/settings/power_settings_app/scenes/power_settings_scene_start.c index 63f123d890..6f9975114b 100644 --- a/applications/settings/power_settings_app/scenes/power_settings_scene_start.c +++ b/applications/settings/power_settings_app/scenes/power_settings_scene_start.c @@ -1,12 +1,30 @@ #include "../power_settings_app.h" +#include enum PowerSettingsSubmenuIndex { + PowerSettingsSubmenuIndexAutoPowerOff, PowerSettingsSubmenuIndexBatteryInfo, PowerSettingsSubmenuIndexReboot, PowerSettingsSubmenuIndexOff, }; -static void power_settings_scene_start_submenu_callback(void* context, uint32_t index) { +#define AUTO_POWEROFF_DELAY_COUNT 9 +const char* const auto_poweroff_delay_text[AUTO_POWEROFF_DELAY_COUNT] = + {"OFF","5 sec","5min", "10min", "15min", "30min", "45min", "60min", "90min"}; + +const uint32_t auto_poweroff_delay_value[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, auto_poweroff_delay_text[index]); + app->settings.auto_poweroff_delay_ms = 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); PowerSettingsApp* app = context; 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) { PowerSettingsApp* app = context; - Submenu* submenu = app->submenu; + VariableItemList* variable_item_list = app->variable_item_list; - submenu_add_item( - submenu, - "Battery Info", - PowerSettingsSubmenuIndexBatteryInfo, - power_settings_scene_start_submenu_callback, + VariableItem* item; + uint8_t value_index; + item = variable_item_list_add( + variable_item_list, + "Auto PowerOff Time", + AUTO_POWEROFF_DELAY_COUNT, + power_settings_scene_start_auto_poweroff_delay_changed, //function for change visible item list value and app settings 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.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]); + + 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) { @@ -60,5 +82,6 @@ bool power_settings_scene_start_on_event(void* context, SceneManagerEvent event) void power_settings_scene_start_on_exit(void* 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 ? } diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 80effa9afe..b649f1f99d 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,79.2,, +Version,+,79.3,, 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_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_role,PipeRole,PipeSide* 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_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_spaces_available,size_t,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,-,pow10,double,double 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_get_info,void,"Power*, PowerInfo*" Function,+,power_get_pubsub,FuriPubSub*,Power* Function,+,power_is_battery_healthy,_Bool,Power* Function,+,power_off,void,Power* 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,+,powf,float,"float, float" Function,-,powl,long double,"long double, long double"