Merge remote-tracking branch 'ul/dev' into mntm-dev

This commit is contained in:
Willy-JL
2025-02-04 15:32:17 +00:00
19 changed files with 244 additions and 233 deletions

View File

@@ -1,85 +1,16 @@
### Breaking Changes: ### Breaking Changes:
- Lockscreen: Separate 'Allow RPC While Locked' settings for USB/BLE (#343 by @956MB) - UL: Desktop: Option to prevent Auto Lock when connected to USB (by @Dmitry422)
- Both default to OFF like before - Desktop settings will be reset, need to reconfigure
- If you had enabled this option before, you will need to re-enable - Keybinds will remain configured
### Added: ### Added:
- Apps: - Nothing
- Games: Pinball0 (by @rdefeo)
- GPIO: FlipperHTTP: FlipWorld (by @jblanked)
- GPIO: TEA5767 FM Radio (by @coolshrimp)
- NFC: Metroflip (by @luu176)
- USB: USB Game Controller (by @expected-ingot)
- Infrared:
- Easy Learn mode to quickly save buttons without typing (#350 by @jaylikesbunda)
- Move Easy Learn and Learn RAW toggles inside Learning/Receiving screen for quick access, RAW mode doesn't require Debug anymore (by @Willy-JL)
- Archive: Setting to show dynamic path in file browser statusbar (#322 by @956MB)
- CLI: Add `clear` and `cls` commands, add `did you mean ...?` command suggestion (#342 by @dexvleads)
- Main Menu: Add coverflow menu style (#314 by @CodyTolene)
- MNTM Settings: Add Menu Style submenu for easier selection (#359 by @jaylikesbunda)
- BadKB: Added german Mac keyboard Layout (#325 by @Cloudy261)
- UL: Sub-GHz: Jolly Motors support with add manually (by @pkooiman & @xMasterX)
- OFW: Desktop: Add winter animations (by @Astrrra)
- API:
- Added `canvas_draw_icon_animation_ex()` to draw animated icons resized (#314 by @CodyTolene)
- OFW: Added `flipper_format_write_empty_line()` (by @janwiesemann)
- OFW: Furi: Pipe support (by @portasynthinca3)
- OFW: Furi: Thread stdin support (by @portasynthinca3)
- OFW: RPC: Command to send a signal once (by @Astrrra)
- OFW: Add VCP break support (by @gsurkov)
### Updated: ### Updated:
- Apps: - OFW: Infrared: Increase max carrier limit to 1000000 (by @skotopes)
- BT/USB Remote: Add PTT support for Gather (by @SapphicCode)
- Chess: Fix illegal move bug (by @956MB)
- Color Guess: Simplify app code (by @leedave)
- Countdown Timer: Default to 60 seconds on open (by @andrejka27)
- Cross Remote: Fix Sub-GHz actions rolling code support, animations for transmit, allow interrupting chain (by @leedave), loop transmit feature (by @miccayo)
- ESP Flasher: Add c3 and c6 to s3 option (by @jaylikesbunda), update bins for Marauder to 1.2.0 (by @justcallmekoko) and FlipperHTTP to 1.6.1 (by @jblanked)
- FlipBIP: Refactor to make adding coins easier (by @xtruan)
- FlipLibrary: Wikipedia, dog facts, random quotes, weather, asset price, predictions, trivia, advice, uuid and many more, bug fixes (by @jblanked), holidays, improvements to connectivity and progress (by @jamisonderek)
- FlipSocial: Improved authentication, loading screens, many bug fixes, bio and friend counts, new feed screen with posted time, search users and contacts, home announcements and notifications, private feed option, endless feed (by @jblanked), RPC_KEYBOARD support (by @jamisonderek)
- FlipStore: Many bugfixes, support downloading ESP32 and VGM firmwares and Github repos, allow deleting apps, memory fixes, update Marauder, use Flipper catalog API (by @jblanked), more improvements (by @jamisonderek)
- FlipTrader: Improved progress display, added connectivity check on startup (by @jamisonderek)
- FlipWeather: Stability improvements (by @jblanked), improved progress display, added connectivity check on startup (by @jamisonderek)
- FlipWiFi: Improve error handling, update scan loading and parsing, many bug/crash fixes, max 100 network scan, add some fast commands (by @jblanked), add connectivity check on startup (by @jamisonderek)
- KeyCopier: Support for formats AR4, M1, AM7, Y2, Y11, S22, NA25, CO88, LW4, LW5, NA12, RU45, H75, B102, Y159, KA14, YM63, SFIC, RV (by @HonestLocksmith)
- NFC Maker: Allow setting custom UID, code cleanup (by @Willy-JL), show extra symbols for WiFi SSID/Password and Emails (by @956MB)
- Nightstand: Show battery percentage and show AM/PM in timer mode (by @956MB)
- Oscilloscope: Add simple spectrum analyser and basic software scaling support (by @anfractuosity)
- Picopass: Handle write key retry when a different card is presented, save SR as legacy from saved menu (by @bettse)
- Pokemon Trade Tool: Update to gblink v0.63 which includes saving/loading of pin configurations for the EXT link interface, bug fixes (by @kbembedded)
- Snake 2.0: Progress saving, endless mode, game timer, fruit positioning bugfixes (by @Willzvul)
- uPython: Enabled extra functions for the `random` module, optimized speaker note constants to save space (by @ofabel)
- WebCrawler: New BROWSE option to read HTML pages, many bugfixes (by @jblanked), improved progress display, added connectivity check on startup (by @jamisonderek)
- WiFi Marauder: AirTag Spoof, flipper blespam, sniff airtag and flipper, list airtag (by @0xchocolate)
- UL: NFC Magic: Added possibility to write 7b MFC to Gen1 tags (by @mishamyte)
- UL: Unitemp: Fixed handling of hPa units (by @shininghero)
- UL: Fixed apps for firmware USB CDC callback changes (by @xMasterX)
- Infrared: Update audio, bluray and tv universal remotes (#348 #358 by @jaylikesbunda)
- NFC:
- OFW: Replace mf_classic_dict.nfc with Proxmark3 version (by @onovy)
- OFW: More station IDs for Clipper plugin (by @ted-logan)
- OFW: Infrared: Add IR command for NAD DR2 D7050 D3020 (by @nikos9742)
### Fixed: ### Fixed:
- Desktop: Fixed Wardriving animation design (by @Davim09) - Nothing
- Main Menu: Fix MNTM style battery percent off by 1 (#339 by @956MB)
- OFW: Fix lost BadBLE keystrokes (by @Astrrra)
- OFW: GPIO: Fix USB UART Bridge Crash by increasing system stack size (by @Astrrra)
- OFW: Loader: Fix BusFault in handling of OOM (by @Willy-JL)
- NFC:
- XERO: Fix issue with MFC key recovery state machine performing key reuse early (by @noproto)
- OFW: Plantain parser Last payment amount fix (by @mxcdoam)
- OFW: Fix skylander ID reading (by @bettse)
- OFW: Fix MIFARE Plus detection (by @GMMan)
- OFW: Fix ISO15693 stuck in wrong mode (by @RebornedBrain)
- OFW: Fix MFUL PWD_AUTH command creation when 0x00 in password (by @GMMan)
- OFW: Fix typo for `mf_classic_key_cahce_get_next_key()` function (by @luu176)
- OFW: U2F: Fix message digest memory leak (by @GMMan)
- OFW: JS: SDK workaround incorrect serial port handling by OS (by @portasynthinca3)
- OFW: FBT: Fix invalid path errors on Windows with UTF8 paths (by @Alex4386)
### Removed: ### Removed:
- NFC: Previous fix for ISO15693 stuck in wrong mode (#225) - Nothing
- Removes APIs `nfc_iso15693_detect_mode()`, `nfc_iso15693_force_1outof4()`, `nfc_iso15693_force_1outof256()`

View File

@@ -137,6 +137,10 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) {
} else if(event == DesktopGlobalAutoLock) { } else if(event == DesktopGlobalAutoLock) {
if(!desktop->app_running && !desktop->locked) { if(!desktop->app_running && !desktop->locked) {
// Disable AutoLock if usb_inhibit_autolock option enabled and device have active USB session.
if((desktop->settings.usb_inhibit_auto_lock) && (furi_hal_usb_is_locked())) {
return true;
}
desktop_lock(desktop, desktop->settings.auto_lock_with_pin); desktop_lock(desktop, desktop->settings.auto_lock_with_pin);
} }

View File

@@ -6,7 +6,7 @@
#define TAG "DesktopSettings" #define TAG "DesktopSettings"
#define DESKTOP_SETTINGS_VER (11) #define DESKTOP_SETTINGS_VER (12)
#define DESKTOP_SETTINGS_MAGIC (0x13) // Different from OFW 0x17 #define DESKTOP_SETTINGS_MAGIC (0x13) // Different from OFW 0x17
void desktop_settings_load(DesktopSettings* settings) { void desktop_settings_load(DesktopSettings* settings) {

View File

@@ -5,6 +5,7 @@
typedef struct { typedef struct {
uint32_t auto_lock_delay_ms; uint32_t auto_lock_delay_ms;
uint8_t auto_lock_with_pin; uint8_t auto_lock_with_pin;
uint8_t usb_inhibit_auto_lock;
uint8_t display_clock; uint8_t display_clock;
} DesktopSettings; } DesktopSettings;

View File

@@ -2,12 +2,13 @@
#include <furi.h> #include <furi.h>
#include <furi_hal.h> #include <furi_hal.h>
#include <loader/loader.h>
#include <momentum/momentum.h> #include <momentum/momentum.h>
#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)
@@ -252,106 +253,6 @@ static ViewPort* power_battery_view_port_alloc(Power* power) {
return battery_view_port; return battery_view_port;
} }
static void power_start_auto_shutdown_timer(Power* power) {
furi_timer_start(
power->auto_shutdown_timer, furi_ms_to_ticks(power->settings.shutdown_idle_delay_ms));
}
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_auto_shutdown_callback(const void* value, void* context) {
furi_assert(value);
furi_assert(context);
UNUSED(value);
Power* power = context;
power_start_auto_shutdown_timer(power);
}
static void power_auto_shutdown_arm(Power* power) {
if(power->settings.shutdown_idle_delay_ms) {
if(power->input_events_subscription == NULL) {
power->input_events_subscription = furi_pubsub_subscribe(
power->input_events_pubsub, power_auto_shutdown_callback, power);
}
if(power->ascii_events_subscription == NULL) {
power->ascii_events_subscription = furi_pubsub_subscribe(
power->ascii_events_pubsub, power_auto_shutdown_callback, power);
}
power_start_auto_shutdown_timer(power);
}
}
static void power_auto_shutdown_inhibit(Power* power) {
power_stop_auto_shutdown_timer(power);
if(power->input_events_subscription) {
furi_pubsub_unsubscribe(power->input_events_pubsub, power->input_events_subscription);
power->input_events_subscription = NULL;
}
if(power->ascii_events_subscription) {
furi_pubsub_unsubscribe(power->ascii_events_pubsub, power->ascii_events_subscription);
power->ascii_events_subscription = NULL;
}
}
static void power_loader_callback(const void* message, void* context) {
furi_assert(context);
Power* power = context;
const LoaderEvent* event = message;
if(event->type == LoaderEventTypeApplicationBeforeLoad) {
power->app_running = true;
power_auto_shutdown_inhibit(power);
} else if(
event->type == LoaderEventTypeApplicationLoadFailed ||
event->type == LoaderEventTypeApplicationStopped) {
power->app_running = false;
power_auto_shutdown_arm(power);
}
}
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);
}
}
static void power_auto_shutdown_timer_callback(void* context) {
furi_assert(context);
Power* power = context;
// Suppress shutdown on idle while charging to avoid the battery from not charging fully. Then restart timer back to original timeout.
if(power->state != PowerStateNotCharging) {
FURI_LOG_D(TAG, "Plugged in, reset idle timer");
power_auto_shutdown_arm(power);
} else {
power_auto_shutdown_inhibit(power);
power_off(power);
}
}
static void power_apply_settings(Power* power) {
if(power->settings.shutdown_idle_delay_ms && !power->app_running) {
power_auto_shutdown_arm(power);
} else if(power_is_running_auto_shutdown_timer(power)) {
power_auto_shutdown_inhibit(power);
}
}
static bool power_update_info(Power* power) { static bool power_update_info(Power* power) {
const PowerInfo info = { const PowerInfo info = {
.is_charging = furi_hal_power_is_charging(), .is_charging = furi_hal_power_is_charging(),
@@ -499,6 +400,101 @@ static void power_handle_reboot(PowerBootMode mode) {
furi_hal_power_reset(); furi_hal_power_reset();
} }
//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;
//Dont poweroff device if charger connected
if(power->state != PowerStateNotCharging) {
FURI_LOG_D(TAG, "We dont auto_power_off until battery is charging");
power_start_auto_poweroff_timer(power);
} else {
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.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);
}
if(power->ascii_events_subscription == NULL) {
power->ascii_events_subscription = furi_pubsub_subscribe(
power->ascii_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;
}
if(power->ascii_events_subscription) {
furi_pubsub_unsubscribe(power->ascii_events_pubsub, power->ascii_events_subscription);
power->ascii_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) {
power_auto_poweroff_arm(power);
} else if(power_is_running_auto_poweroff_timer(power)) {
power_auto_poweroff_disarm(power);
}
}
// 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;
@@ -531,12 +527,12 @@ static void power_message_callback(FuriEventLoopObject* object, void* context) {
case PowerMessageTypeSetSettings: case PowerMessageTypeSetSettings:
furi_assert(msg.lock); furi_assert(msg.lock);
power->settings = *msg.csettings; power->settings = *msg.csettings;
power_apply_settings(power); power_settings_apply(power);
power_settings_save(&power->settings); power_settings_save(&power->settings);
break; break;
case PowerMessageTypeReloadSettings: case PowerMessageTypeReloadSettings:
power_settings_load(&power->settings); power_settings_load(&power->settings);
power_apply_settings(power); power_settings_apply(power);
break; break;
default: default:
furi_crash(); furi_crash();
@@ -573,6 +569,22 @@ 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) { static void power_init_settings(Power* power) {
Storage* storage = furi_record_open(RECORD_STORAGE); Storage* storage = furi_record_open(RECORD_STORAGE);
furi_pubsub_subscribe(storage_get_pubsub(storage), power_storage_callback, power); furi_pubsub_subscribe(storage_get_pubsub(storage), power_storage_callback, power);
@@ -583,7 +595,7 @@ static void power_init_settings(Power* power) {
} }
power_settings_load(&power->settings); power_settings_load(&power->settings);
power_apply_settings(power); power_settings_apply(power);
furi_record_close(RECORD_STORAGE); furi_record_close(RECORD_STORAGE);
} }
@@ -597,13 +609,15 @@ static Power* power_alloc(void) {
// Gui // Gui
Gui* gui = furi_record_open(RECORD_GUI); Gui* gui = furi_record_open(RECORD_GUI);
// Auto shutdown on idle // auto_poweroff
//---define subscription to loader events message (info about started apps) and defina callback for this
Loader* loader = furi_record_open(RECORD_LOADER); Loader* loader = furi_record_open(RECORD_LOADER);
furi_pubsub_subscribe(loader_get_pubsub(loader), power_loader_callback, power); furi_pubsub_subscribe(loader_get_pubsub(loader), power_loader_callback, power);
power->input_events_pubsub = furi_record_open(RECORD_INPUT_EVENTS); power->input_events_pubsub = furi_record_open(RECORD_INPUT_EVENTS);
power->ascii_events_pubsub = furi_record_open(RECORD_ASCII_EVENTS); power->ascii_events_pubsub = furi_record_open(RECORD_ASCII_EVENTS);
power->auto_shutdown_timer = //define autopoweroff timer and they callback
furi_timer_alloc(power_auto_shutdown_timer_callback, FuriTimerTypeOnce, power); power->auto_poweroff_timer =
furi_timer_alloc(power_auto_poweroff_timer_callback, FuriTimerTypeOnce, power);
power->view_holder = view_holder_alloc(); power->view_holder = view_holder_alloc();
power->view_power_off = power_off_alloc(); power->view_power_off = power_off_alloc();
@@ -639,6 +653,10 @@ int32_t power_srv(void* p) {
} }
Power* power = power_alloc(); Power* power = power_alloc();
// load inital settings for power service
power_init_settings(power);
power_update_info(power); power_update_info(power);
furi_record_create(RECORD_POWER, power); furi_record_create(RECORD_POWER, power);
@@ -647,7 +665,6 @@ int32_t power_srv(void* p) {
Loader* loader = furi_record_open(RECORD_LOADER); Loader* loader = furi_record_open(RECORD_LOADER);
power->app_running = loader_is_locked(loader); power->app_running = loader_is_locked(loader);
furi_record_close(RECORD_LOADER); furi_record_close(RECORD_LOADER);
power_init_settings(power);
furi_event_loop_run(power->event_loop); furi_event_loop_run(power->event_loop);

View File

@@ -75,7 +75,8 @@ void power_enable_low_battery_level_notification(Power* power, bool enable) {
* Private API for the Settings app * Private API for the Settings app
*/ */
void power_get_settings(Power* power, PowerSettings* settings) { // 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(power);
furi_assert(settings); furi_assert(settings);
@@ -90,7 +91,8 @@ void power_get_settings(Power* power, PowerSettings* settings) {
api_lock_wait_unlock_and_free(msg.lock); api_lock_wait_unlock_and_free(msg.lock);
} }
void power_set_settings(Power* power, const PowerSettings* settings) { // 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(power);
furi_assert(settings); furi_assert(settings);

View File

@@ -11,7 +11,7 @@
#include "views/power_off.h" #include "views/power_off.h"
#include "views/power_unplug_usb.h" #include "views/power_unplug_usb.h"
#include <power/power_settings.h> #include <power/power_service/power_settings.h>
typedef enum { typedef enum {
PowerStateNotCharging, PowerStateNotCharging,
@@ -38,14 +38,14 @@ struct Power {
uint8_t battery_level; uint8_t battery_level;
uint8_t power_off_timeout; uint8_t power_off_timeout;
PowerSettings settings;
FuriTimer* auto_poweroff_timer;
bool app_running;
bool is_charge_capped;
FuriPubSub* input_events_pubsub; FuriPubSub* input_events_pubsub;
FuriPubSub* ascii_events_pubsub; FuriPubSub* ascii_events_pubsub;
FuriPubSubSubscription* input_events_subscription; FuriPubSubSubscription* input_events_subscription;
FuriPubSubSubscription* ascii_events_subscription; FuriPubSubSubscription* ascii_events_subscription;
FuriTimer* auto_shutdown_timer;
PowerSettings settings;
bool is_charge_capped;
bool app_running;
}; };
typedef enum { typedef enum {

View File

@@ -3,7 +3,7 @@
#include <stdint.h> #include <stdint.h>
typedef struct { typedef struct {
uint32_t shutdown_idle_delay_ms; uint32_t auto_poweroff_delay_ms;
} PowerSettings; } PowerSettings;
void power_settings_load(PowerSettings* settings); void power_settings_load(PowerSettings* settings);

View File

@@ -1,8 +1,10 @@
#pragma once #pragma once
#include "power.h" #include "power.h"
#include "../power_settings.h" #include "power_settings.h"
void power_get_settings(Power* power, PowerSettings* settings); // get settings from service to app
void power_api_get_settings(Power* instance, PowerSettings* settings);
void power_set_settings(Power* power, const PowerSettings* settings); // set settings from app to service
void power_api_set_settings(Power* instance, const PowerSettings* settings);

View File

@@ -10,11 +10,13 @@ typedef enum {
DesktopSettingsResetKeybinds, DesktopSettingsResetKeybinds,
DesktopSettingsAutoLockDelay, DesktopSettingsAutoLockDelay,
DesktopSettingsAutoLockPin, DesktopSettingsAutoLockPin,
DesktopSettingsAutoLockInhibit,
DesktopSettingsClockDisplay, DesktopSettingsClockDisplay,
DesktopSettingsHappyMode, DesktopSettingsHappyMode,
} DesktopSettingsEntry; } DesktopSettingsEntry;
#define AUTO_LOCK_DELAY_COUNT 9 #define AUTO_LOCK_DELAY_COUNT 9
static const char* const auto_lock_delay_text[AUTO_LOCK_DELAY_COUNT] = { static const char* const auto_lock_delay_text[AUTO_LOCK_DELAY_COUNT] = {
"OFF", "OFF",
"10s", "10s",
@@ -26,9 +28,19 @@ static const char* const auto_lock_delay_text[AUTO_LOCK_DELAY_COUNT] = {
"5min", "5min",
"10min", "10min",
}; };
static const uint32_t auto_lock_delay_value[AUTO_LOCK_DELAY_COUNT] = static const uint32_t auto_lock_delay_value[AUTO_LOCK_DELAY_COUNT] =
{0, 10000, 15000, 30000, 60000, 90000, 120000, 300000, 600000}; {0, 10000, 15000, 30000, 60000, 90000, 120000, 300000, 600000};
#define USB_INHIBIT_AUTO_LOCK_DELAY_COUNT 2
const char* const usb_inhibit_auto_lock_delay_text[USB_INHIBIT_AUTO_LOCK_DELAY_COUNT] = {
"OFF",
"ON",
};
const uint32_t usb_inhibit_auto_lock_delay_value[USB_INHIBIT_AUTO_LOCK_DELAY_COUNT] = {0, 1};
#define CLOCK_ENABLE_COUNT 2 #define CLOCK_ENABLE_COUNT 2
const char* const clock_enable_text[CLOCK_ENABLE_COUNT] = { const char* const clock_enable_text[CLOCK_ENABLE_COUNT] = {
"OFF", "OFF",
@@ -66,6 +78,14 @@ static void desktop_settings_scene_start_auto_lock_pin_changed(VariableItem* ite
app->settings.auto_lock_with_pin = value; app->settings.auto_lock_with_pin = value;
} }
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, 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) { void desktop_settings_scene_start_on_enter(void* context) {
DesktopSettingsApp* app = context; DesktopSettingsApp* app = context;
VariableItemList* variable_item_list = app->variable_item_list; VariableItemList* variable_item_list = app->variable_item_list;
@@ -101,6 +121,21 @@ void desktop_settings_scene_start_on_enter(void* context) {
variable_item_set_current_value_index(item, app->settings.auto_lock_with_pin); variable_item_set_current_value_index(item, app->settings.auto_lock_with_pin);
variable_item_set_current_value_text(item, app->settings.auto_lock_with_pin ? "ON" : "OFF"); variable_item_set_current_value_text(item, app->settings.auto_lock_with_pin ? "ON" : "OFF");
// USB connection Inhibit autolock OFF|ON|with opened RPC session
item = variable_item_list_add(
variable_item_list,
"Auto Lock disarm by active USB session",
USB_INHIBIT_AUTO_LOCK_DELAY_COUNT,
desktop_settings_scene_start_usb_inhibit_auto_lock_delay_changed,
app);
value_index = value_index_uint32(
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, usb_inhibit_auto_lock_delay_text[value_index]);
item = variable_item_list_add( item = variable_item_list_add(
variable_item_list, variable_item_list,
"Show Clock", "Show Clock",

View File

@@ -3,5 +3,5 @@
// Instead of copying the file, can (ab)use the preprocessor to insert the source code here // Instead of copying the file, can (ab)use the preprocessor to insert the source code here
// Then, we still use the Header from original code as if nothing happened // Then, we still use the Header from original code as if nothing happened
// power_get_settings(), power_set_settings() // power_api_get_settings(), power_api_set_settings()
#include <applications/services/power/power_service/power_api.c> #include <applications/services/power/power_service/power_api.c>

View File

@@ -50,18 +50,19 @@ PowerSettingsApp* power_settings_app_alloc(uint32_t first_scene, ViewDispatcherT
PowerSettingsAppViewBatteryInfo, PowerSettingsAppViewBatteryInfo,
battery_info_get_view(app->battery_info)); battery_info_get_view(app->battery_info));
app->submenu = submenu_alloc(); app->submenu = submenu_alloc();
app->variable_item_list = variable_item_list_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->dialog = dialog_ex_alloc(); app->variable_item_list = variable_item_list_alloc();
view_dispatcher_add_view(
app->view_dispatcher, PowerSettingsAppViewDialog, dialog_ex_get_view(app->dialog));
view_dispatcher_add_view( view_dispatcher_add_view(
app->view_dispatcher, app->view_dispatcher,
PowerSettingsAppViewVariableItemList, PowerSettingsAppViewVariableItemList,
variable_item_list_get_view(app->variable_item_list)); 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));
power_get_settings(app->power, &app->settings); // 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);
@@ -70,7 +71,9 @@ PowerSettingsApp* power_settings_app_alloc(uint32_t first_scene, ViewDispatcherT
void power_settings_app_free(PowerSettingsApp* app) { void power_settings_app_free(PowerSettingsApp* app) {
furi_assert(app); furi_assert(app);
power_set_settings(app->power, &app->settings);
// 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);
@@ -78,12 +81,12 @@ void power_settings_app_free(PowerSettingsApp* app) {
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, PowerSettingsAppViewDialog);
dialog_ex_free(app->dialog);
view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewVariableItemList); view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewVariableItemList);
variable_item_list_free(app->variable_item_list); 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
view_dispatcher_free(app->view_dispatcher); view_dispatcher_free(app->view_dispatcher);
scene_manager_free(app->scene_manager); scene_manager_free(app->scene_manager);

View File

@@ -11,23 +11,22 @@
#include "views/battery_info.h" #include "views/battery_info.h"
#include <gui/modules/submenu.h> #include <gui/modules/submenu.h>
#include <gui/modules/dialog_ex.h>
#include <gui/modules/variable_item_list.h> #include <gui/modules/variable_item_list.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; PowerSettings settings;
Power* power; Power* power;
Gui* gui; Gui* gui;
SceneManager* scene_manager; SceneManager* scene_manager;
ViewDispatcher* view_dispatcher; ViewDispatcher* view_dispatcher;
BatteryInfo* battery_info; BatteryInfo* battery_info;
Submenu* submenu; Submenu* submenu;
VariableItemList* variable_item_list;
DialogEx* dialog; DialogEx* dialog;
PowerInfo info; PowerInfo info;
VariableItemList* variable_item_list;
bool about_battery; bool about_battery;
} PowerSettingsApp; } PowerSettingsApp;

View File

@@ -6,30 +6,47 @@ enum PowerSettingsSubmenuIndex {
PowerSettingsSubmenuIndexBatteryInfo, PowerSettingsSubmenuIndexBatteryInfo,
PowerSettingsSubmenuIndexReboot, PowerSettingsSubmenuIndexReboot,
PowerSettingsSubmenuIndexOff, PowerSettingsSubmenuIndexOff,
PowerSettingsSubmenuShutdownIdle PowerSettingsSubmenuIndexAutoPowerOff,
}; };
#define SHUTDOWN_IDLE_DELAY_COUNT 9 #define AUTO_POWEROFF_DELAY_COUNT 13
const char* const shutdown_idle_delay_text[SHUTDOWN_IDLE_DELAY_COUNT] = { const char* const auto_poweroff_delay_text[AUTO_POWEROFF_DELAY_COUNT] = {
"OFF", "OFF",
"15m", "5min",
"30m", "10min",
"1h", "15min",
"30min",
"45min",
"60min",
"90min",
"2h", "2h",
"6h", "6h",
"12h", "12h",
"24h", "24h",
"48h", "48h"};
};
const uint32_t shutdown_idle_delay_value[SHUTDOWN_IDLE_DELAY_COUNT] =
{0, 900000, 1800000, 3600000, 7200000, 21600000, 43200000, 86400000, 172800000};
static void power_settings_scene_start_auto_lock_delay_changed(VariableItem* item) { const uint32_t auto_poweroff_delay_value[AUTO_POWEROFF_DELAY_COUNT] = {
0,
300000,
600000,
900000,
1800000,
2700000,
3600000,
5400000,
7200000,
21600000,
43200000,
86400000,
172800000};
// 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); PowerSettingsApp* 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);
variable_item_set_current_value_text(item, shutdown_idle_delay_text[index]); variable_item_set_current_value_text(item, auto_poweroff_delay_text[index]);
app->settings.shutdown_idle_delay_ms = shutdown_idle_delay_value[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) { static void power_settings_scene_start_submenu_callback(void* context, uint32_t index) {
@@ -53,16 +70,17 @@ void power_settings_scene_start_on_enter(void* context) {
item = variable_item_list_add( item = variable_item_list_add(
variable_item_list, variable_item_list,
"Shutdown on Idle", "Auto PowerOff",
SHUTDOWN_IDLE_DELAY_COUNT, AUTO_POWEROFF_DELAY_COUNT,
power_settings_scene_start_auto_lock_delay_changed, power_settings_scene_start_auto_poweroff_delay_changed, //function for change visible item list value and app settings
app); app);
value_index = value_index_uint32( value_index = value_index_uint32(
app->settings.shutdown_idle_delay_ms, app->settings.auto_poweroff_delay_ms,
shutdown_idle_delay_value, auto_poweroff_delay_value,
SHUTDOWN_IDLE_DELAY_COUNT); AUTO_POWEROFF_DELAY_COUNT);
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, shutdown_idle_delay_text[value_index]); variable_item_set_current_value_text(item, auto_poweroff_delay_text[value_index]);
variable_item_list_set_selected_item( variable_item_list_set_selected_item(
variable_item_list, variable_item_list,
@@ -85,7 +103,6 @@ bool power_settings_scene_start_on_event(void* context, SceneManagerEvent event)
scene_manager_next_scene(app->scene_manager, PowerSettingsAppSceneReboot); scene_manager_next_scene(app->scene_manager, PowerSettingsAppSceneReboot);
} else if(event.event == PowerSettingsSubmenuIndexOff) { } else if(event.event == PowerSettingsSubmenuIndexOff) {
scene_manager_next_scene(app->scene_manager, PowerSettingsAppScenePowerOff); scene_manager_next_scene(app->scene_manager, PowerSettingsAppScenePowerOff);
} else if(event.event == PowerSettingsSubmenuShutdownIdle) {
} }
scene_manager_set_scene_state(app->scene_manager, PowerSettingsAppSceneStart, event.event); scene_manager_set_scene_state(app->scene_manager, PowerSettingsAppSceneStart, event.event);
consumed = true; consumed = true;

View File

@@ -48,7 +48,7 @@ static void flipper_print_version(const char* target, const Version* version) {
#include <expansion/expansion_settings_filename.h> #include <expansion/expansion_settings_filename.h>
#include <loader/loader_menu.h> #include <loader/loader_menu.h>
#include <notification/notification_settings_filename.h> #include <notification/notification_settings_filename.h>
#include <power/power_settings_filename.h> #include <power/power_service/power_settings_filename.h>
#include <drivers/rgb_backlight_filename.h> #include <drivers/rgb_backlight_filename.h>
#include <applications/main/infrared/infrared_settings.h> #include <applications/main/infrared/infrared_settings.h>
#include <applications/main/u2f/u2f_data.h> #include <applications/main/u2f/u2f_data.h>

View File

@@ -3017,9 +3017,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*
1 entry status name type params
3017 Function + pipe_receive size_t PipeSide*, void*, size_t, FuriWait
3018 Function + pipe_role PipeRole PipeSide*
3019 Function + pipe_send size_t PipeSide*, const void*, size_t, FuriWait
3020 Function + pipe_set_broken_callback void PipeSide*, PipeSideBrokenCallback, FuriEventLoopEvent
3021 Function + pipe_set_callback_context void PipeSide*, void*
3022 Function + pipe_set_data_arrived_callback void PipeSide*, PipeSideDataArrivedCallback, FuriEventLoopEvent
Function + pipe_set_broken_callback void PipeSide*, PipeSideBrokenCallback, FuriEventLoopEvent
3023 Function + pipe_set_space_freed_callback void PipeSide*, PipeSideSpaceFreedCallback, FuriEventLoopEvent
3024 Function + pipe_spaces_available size_t PipeSide*
3025 Function + pipe_state PipeState PipeSide*

View File

@@ -13,7 +13,7 @@
extern "C" { extern "C" {
#endif #endif
#define INFRARED_MAX_FREQUENCY 56000 #define INFRARED_MAX_FREQUENCY 1000000
#define INFRARED_MIN_FREQUENCY 10000 #define INFRARED_MIN_FREQUENCY 10000
typedef enum { typedef enum {