mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-24 22:07:14 +03:00
[FL-2612, FL-2618, FL-2619, FL-2622] CLI, threads, notifications, archive fixes (#1354)
* CLI, notifications, archive fixes * Led blink fix * Fix thread flags notification index * Archive: fix infinite tab switch on empty SD card Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
parent
ece142a667
commit
e17dae2d00
@ -15,8 +15,9 @@ static void
|
||||
|
||||
int32_t load_offset = 0;
|
||||
browser->is_root = is_root;
|
||||
ArchiveTabEnum tab = archive_get_tab(browser);
|
||||
|
||||
if((item_cnt == 0) && (archive_is_home(browser))) {
|
||||
if((item_cnt == 0) && (archive_is_home(browser)) && (tab != ArchiveTabBrowser)) {
|
||||
archive_switch_tab(browser, browser->last_tab_switch_dir);
|
||||
} else if(!string_start_with_str_p(browser->path, "/app:")) {
|
||||
with_view_model(
|
||||
@ -389,6 +390,22 @@ void archive_favorites_move_mode(ArchiveBrowserView* browser, bool active) {
|
||||
});
|
||||
}
|
||||
|
||||
static bool archive_is_dir_exists(string_t path) {
|
||||
if(string_equal_str_p(path, "/any")) {
|
||||
return true;
|
||||
}
|
||||
bool state = false;
|
||||
FileInfo file_info;
|
||||
Storage* storage = furi_record_open("storage");
|
||||
if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) {
|
||||
if(file_info.flags & FSF_DIRECTORY) {
|
||||
state = true;
|
||||
}
|
||||
}
|
||||
furi_record_close("storage");
|
||||
return state;
|
||||
}
|
||||
|
||||
void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) {
|
||||
furi_assert(browser);
|
||||
ArchiveTabEnum tab = archive_get_tab(browser);
|
||||
@ -418,11 +435,15 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ArchiveTabEnum tab = archive_get_tab(browser);
|
||||
bool skip_assets = (strcmp(archive_get_tab_ext(tab), "*") == 0) ? false : true;
|
||||
file_browser_worker_set_config(
|
||||
browser->worker, browser->path, archive_get_tab_ext(tab), skip_assets);
|
||||
tab_empty = false; // Empty check will be performed later
|
||||
tab = archive_get_tab(browser);
|
||||
if(archive_is_dir_exists(browser->path)) {
|
||||
bool skip_assets = (strcmp(archive_get_tab_ext(tab), "*") == 0) ? false : true;
|
||||
file_browser_worker_set_config(
|
||||
browser->worker, browser->path, archive_get_tab_ext(tab), skip_assets);
|
||||
tab_empty = false; // Empty check will be performed later
|
||||
} else {
|
||||
tab_empty = true;
|
||||
}
|
||||
}
|
||||
|
||||
if((tab_empty) && (tab != ArchiveTabBrowser)) {
|
||||
|
@ -229,18 +229,22 @@ static void cli_handle_enter(Cli* cli) {
|
||||
|
||||
// Search for command
|
||||
furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK);
|
||||
CliCommand* cli_command = CliCommandTree_get(cli->commands, command);
|
||||
if(cli_command) {
|
||||
CliCommand* cli_command_ptr = CliCommandTree_get(cli->commands, command);
|
||||
|
||||
if(cli_command_ptr) {
|
||||
CliCommand cli_command;
|
||||
memcpy(&cli_command, cli_command_ptr, sizeof(CliCommand));
|
||||
furi_check(osMutexRelease(cli->mutex) == osOK);
|
||||
cli_nl(cli);
|
||||
cli_execute_command(cli, cli_command, args);
|
||||
cli_execute_command(cli, &cli_command, args);
|
||||
} else {
|
||||
furi_check(osMutexRelease(cli->mutex) == osOK);
|
||||
cli_nl(cli);
|
||||
printf(
|
||||
"`%s` command not found, use `help` or `?` to list all available commands",
|
||||
string_get_cstr(command));
|
||||
cli_putc(cli, CliSymbolAsciiBell);
|
||||
}
|
||||
furi_check(osMutexRelease(cli->mutex) == osOK);
|
||||
|
||||
cli_reset(cli);
|
||||
cli_prompt(cli);
|
||||
|
@ -199,6 +199,7 @@ static int32_t vcp_worker(void* context) {
|
||||
furi_hal_cdc_set_callbacks(VCP_IF_NUM, NULL, NULL);
|
||||
// Restore previous USB mode (if it was set during init)
|
||||
if((vcp->usb_if_prev != &usb_cdc_single) && (vcp->usb_if_prev != &usb_cdc_dual)) {
|
||||
furi_hal_usb_unlock();
|
||||
furi_hal_usb_set_config(vcp->usb_if_prev, NULL);
|
||||
}
|
||||
xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0);
|
||||
|
@ -158,7 +158,7 @@ static bool desktop_view_locked_input(InputEvent* event, void* context) {
|
||||
const bool pin_locked = model->pin_locked;
|
||||
view_commit_model(locked_view->view, is_changed);
|
||||
|
||||
if(view_state == DesktopViewLockedStateUnlocked || event->type != InputTypeShort) {
|
||||
if(view_state == DesktopViewLockedStateUnlocked) {
|
||||
return view_state != DesktopViewLockedStateUnlocked;
|
||||
} else if(view_state == DesktopViewLockedStateLocked && pin_locked) {
|
||||
locked_view->callback(DesktopLockedEventShowPinInput, locked_view->context);
|
||||
@ -173,10 +173,12 @@ static bool desktop_view_locked_input(InputEvent* event, void* context) {
|
||||
desktop_view_locked_update_hint_icon_timeout(locked_view);
|
||||
|
||||
if(event->key == InputKeyBack) {
|
||||
locked_view->lock_lastpress = press_time;
|
||||
locked_view->lock_count++;
|
||||
if(locked_view->lock_count == UNLOCK_CNT) {
|
||||
locked_view->callback(DesktopLockedEventUnlocked, locked_view->context);
|
||||
if(event->type == InputTypeShort) {
|
||||
locked_view->lock_lastpress = press_time;
|
||||
locked_view->lock_count++;
|
||||
if(locked_view->lock_count == UNLOCK_CNT) {
|
||||
locked_view->callback(DesktopLockedEventUnlocked, locked_view->context);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
locked_view->lock_count = 0;
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <dolphin/dolphin.h>
|
||||
#include <toolbox/path.h>
|
||||
|
||||
#define EMULATE_TIMEOUT_TICKS 10
|
||||
|
||||
static void ibutton_scene_emulate_callback(void* context, bool emulated) {
|
||||
iButton* ibutton = context;
|
||||
if(emulated) {
|
||||
@ -95,11 +97,23 @@ bool ibutton_scene_emulate_on_event(void* context, SceneManagerEvent event) {
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeTick) {
|
||||
uint32_t cnt = scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneEmulate);
|
||||
if(cnt > 0) {
|
||||
cnt--;
|
||||
if(cnt == 0) {
|
||||
ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateBlink);
|
||||
}
|
||||
scene_manager_set_scene_state(ibutton->scene_manager, iButtonSceneEmulate, cnt);
|
||||
}
|
||||
consumed = true;
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
consumed = true;
|
||||
if(event.event == iButtonCustomEventWorkerEmulated) {
|
||||
ibutton_notification_message(ibutton, iButtonNotificationMessageYellowBlink);
|
||||
if(scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneEmulate) == 0) {
|
||||
ibutton_notification_message(ibutton, iButtonNotificationMessageYellowBlink);
|
||||
}
|
||||
scene_manager_set_scene_state(
|
||||
ibutton->scene_manager, iButtonSceneEmulate, EMULATE_TIMEOUT_TICKS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,9 @@ void notification_reset_notification_led_layer(NotificationLedLayer* layer) {
|
||||
}
|
||||
|
||||
void notification_reset_notification_layer(NotificationApp* app, uint8_t reset_mask) {
|
||||
if(reset_mask & reset_blink_mask) {
|
||||
furi_hal_light_blink_stop();
|
||||
}
|
||||
if(reset_mask & reset_red_mask) {
|
||||
notification_reset_notification_led_layer(&app->led[0]);
|
||||
}
|
||||
@ -102,9 +105,6 @@ void notification_reset_notification_layer(NotificationApp* app, uint8_t reset_m
|
||||
if(reset_mask & reset_blue_mask) {
|
||||
notification_reset_notification_led_layer(&app->led[2]);
|
||||
}
|
||||
if(reset_mask & reset_blink_mask) {
|
||||
furi_hal_light_blink_stop();
|
||||
}
|
||||
if(reset_mask & reset_vibro_mask) {
|
||||
notification_vibro_off();
|
||||
}
|
||||
@ -243,6 +243,9 @@ void notification_process_notification_message(
|
||||
notification_message->data.led_blink.on_time,
|
||||
notification_message->data.led_blink.period);
|
||||
reset_mask |= reset_blink_mask;
|
||||
reset_mask |= reset_red_mask;
|
||||
reset_mask |= reset_green_mask;
|
||||
reset_mask |= reset_blue_mask;
|
||||
break;
|
||||
case NotificationMessageTypeLedBlinkColor:
|
||||
led_active = true;
|
||||
@ -251,6 +254,9 @@ void notification_process_notification_message(
|
||||
case NotificationMessageTypeLedBlinkStop:
|
||||
furi_hal_light_blink_stop();
|
||||
reset_mask &= ~reset_blink_mask;
|
||||
reset_mask |= reset_red_mask;
|
||||
reset_mask |= reset_green_mask;
|
||||
reset_mask |= reset_blue_mask;
|
||||
break;
|
||||
case NotificationMessageTypeVibro:
|
||||
if(notification_message->data.vibro.on) {
|
||||
@ -326,7 +332,7 @@ void notification_process_notification_message(
|
||||
reset_mask |= reset_green_mask;
|
||||
reset_mask |= reset_blue_mask;
|
||||
|
||||
if(need_minimal_delay) {
|
||||
if((need_minimal_delay) && (reset_notifications)) {
|
||||
notification_apply_notification_leds(app, led_off_values);
|
||||
furi_hal_delay_ms(minimal_delay);
|
||||
}
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <task.h>
|
||||
#include <m-string.h>
|
||||
|
||||
#define THREAD_NOTIFY_INDEX 1 // Index 0 is used for stream buffers
|
||||
|
||||
struct FuriThread {
|
||||
FuriThreadState state;
|
||||
int32_t ret;
|
||||
@ -221,13 +223,14 @@ uint32_t furi_thread_flags_set(FuriThreadId thread_id, uint32_t flags) {
|
||||
if(FURI_IS_IRQ_MODE()) {
|
||||
yield = pdFALSE;
|
||||
|
||||
(void)xTaskNotifyFromISR(hTask, flags, eSetBits, &yield);
|
||||
(void)xTaskNotifyAndQueryFromISR(hTask, 0, eNoAction, &rflags, NULL);
|
||||
(void)xTaskNotifyIndexedFromISR(hTask, THREAD_NOTIFY_INDEX, flags, eSetBits, &yield);
|
||||
(void)xTaskNotifyAndQueryIndexedFromISR(
|
||||
hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &rflags, NULL);
|
||||
|
||||
portYIELD_FROM_ISR(yield);
|
||||
} else {
|
||||
(void)xTaskNotify(hTask, flags, eSetBits);
|
||||
(void)xTaskNotifyAndQuery(hTask, 0, eNoAction, &rflags);
|
||||
(void)xTaskNotifyIndexed(hTask, THREAD_NOTIFY_INDEX, flags, eSetBits);
|
||||
(void)xTaskNotifyAndQueryIndexed(hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &rflags);
|
||||
}
|
||||
}
|
||||
/* Return flags after setting */
|
||||
@ -245,11 +248,13 @@ uint32_t furi_thread_flags_clear(uint32_t flags) {
|
||||
} else {
|
||||
hTask = xTaskGetCurrentTaskHandle();
|
||||
|
||||
if(xTaskNotifyAndQuery(hTask, 0, eNoAction, &cflags) == pdPASS) {
|
||||
if(xTaskNotifyAndQueryIndexed(hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &cflags) ==
|
||||
pdPASS) {
|
||||
rflags = cflags;
|
||||
cflags &= ~flags;
|
||||
|
||||
if(xTaskNotify(hTask, cflags, eSetValueWithOverwrite) != pdPASS) {
|
||||
if(xTaskNotifyIndexed(hTask, THREAD_NOTIFY_INDEX, cflags, eSetValueWithOverwrite) !=
|
||||
pdPASS) {
|
||||
rflags = (uint32_t)osError;
|
||||
}
|
||||
} else {
|
||||
@ -270,7 +275,8 @@ uint32_t furi_thread_flags_get(void) {
|
||||
} else {
|
||||
hTask = xTaskGetCurrentTaskHandle();
|
||||
|
||||
if(xTaskNotifyAndQuery(hTask, 0, eNoAction, &rflags) != pdPASS) {
|
||||
if(xTaskNotifyAndQueryIndexed(hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &rflags) !=
|
||||
pdPASS) {
|
||||
rflags = (uint32_t)osError;
|
||||
}
|
||||
}
|
||||
@ -300,7 +306,7 @@ uint32_t furi_thread_flags_wait(uint32_t flags, uint32_t options, uint32_t timeo
|
||||
|
||||
t0 = xTaskGetTickCount();
|
||||
do {
|
||||
rval = xTaskNotifyWait(0, clear, &nval, tout);
|
||||
rval = xTaskNotifyWaitIndexed(THREAD_NOTIFY_INDEX, 0, clear, &nval, tout);
|
||||
|
||||
if(rval == pdPASS) {
|
||||
rflags &= flags;
|
||||
|
Loading…
Reference in New Issue
Block a user