From bc6c958abffe9741a8bbed3b8d90647e2208dc72 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Thu, 10 Oct 2024 00:24:46 +0800 Subject: [PATCH 01/24] init --- .../main/infrared/infrared_brute_force.c | 66 +++++-- .../main/infrared/infrared_brute_force.h | 20 +++ .../common/infrared_scene_universal_common.c | 12 +- .../infrared/scenes/infrared_scene_config.h | 1 + .../scenes/infrared_scene_universal.c | 12 ++ .../scenes/infrared_scene_universal_led.c | 1 - .../infrared_scene_universal_more_devices.c | 169 ++++++++++++++++++ .../infrared/views/infrared_progress_view.c | 4 +- 8 files changed, 268 insertions(+), 17 deletions(-) create mode 100644 applications/main/infrared/scenes/infrared_scene_universal_more_devices.c diff --git a/applications/main/infrared/infrared_brute_force.c b/applications/main/infrared/infrared_brute_force.c index 8c7422d5ef..af11947e04 100644 --- a/applications/main/infrared/infrared_brute_force.c +++ b/applications/main/infrared/infrared_brute_force.c @@ -6,6 +6,8 @@ #include "infrared_signal.h" +#include + typedef struct { uint32_t index; uint32_t count; @@ -60,32 +62,34 @@ InfraredErrorCode infrared_brute_force_calculate_messages(InfraredBruteForce* br FuriString* signal_name = furi_string_alloc(); InfraredSignal* signal = infrared_signal_alloc(); - do { - if(!flipper_format_buffered_file_open_existing(ff, brute_force->db_filename)) { - error = InfraredErrorCodeFileOperationFailed; - break; - } - - bool signals_valid = false; + if(!flipper_format_buffered_file_open_existing(ff, brute_force->db_filename)) { + error = InfraredErrorCodeFileOperationFailed; + } else { + uint32_t total_signals = 0; while(infrared_signal_read_name(ff, signal_name) == InfraredErrorCodeNone) { error = infrared_signal_read_body(signal, ff); - signals_valid = (!INFRARED_ERROR_PRESENT(error)) && infrared_signal_is_valid(signal); - if(!signals_valid) break; + if(INFRARED_ERROR_PRESENT(error) || !infrared_signal_is_valid(signal)) { + break; + } InfraredBruteForceRecord* record = InfraredBruteForceRecordDict_get(brute_force->records, signal_name); if(record) { //-V547 ++(record->count); + + } else { + infrared_brute_force_add_record( + brute_force, total_signals, furi_string_get_cstr(signal_name)); } + total_signals++; } - if(!signals_valid) break; - } while(false); + } infrared_signal_free(signal); furi_string_free(signal_name); - flipper_format_free(ff); furi_record_close(RECORD_STORAGE); + return error; } @@ -94,10 +98,12 @@ bool infrared_brute_force_start( uint32_t index, uint32_t* record_count) { furi_assert(!brute_force->is_started); + bool success = false; *record_count = 0; InfraredBruteForceRecordDict_it_t it; + for(InfraredBruteForceRecordDict_it(it, brute_force->records); !InfraredBruteForceRecordDict_end_p(it); InfraredBruteForceRecordDict_next(it)) { @@ -114,12 +120,17 @@ bool infrared_brute_force_start( if(*record_count) { Storage* storage = furi_record_open(RECORD_STORAGE); brute_force->ff = flipper_format_buffered_file_alloc(storage); + brute_force->current_signal = infrared_signal_alloc(); + brute_force->is_started = true; + success = flipper_format_buffered_file_open_existing(brute_force->ff, brute_force->db_filename); + if(!success) infrared_brute_force_stop(brute_force); } + return success; } @@ -151,7 +162,6 @@ bool infrared_brute_force_send_next(InfraredBruteForce* brute_force) { } return success; } - void infrared_brute_force_add_record( InfraredBruteForce* brute_force, uint32_t index, @@ -160,6 +170,7 @@ void infrared_brute_force_add_record( FuriString* key; key = furi_string_alloc_set(name); InfraredBruteForceRecordDict_set_at(brute_force->records, key, value); + furi_string_free(key); } @@ -167,3 +178,32 @@ void infrared_brute_force_reset(InfraredBruteForce* brute_force) { furi_assert(!brute_force->is_started); InfraredBruteForceRecordDict_reset(brute_force->records); } + +size_t infrared_brute_force_get_db_size(const InfraredBruteForce* brute_force) { + size_t size = InfraredBruteForceRecordDict_size(brute_force->records); + return size; +} + +const char* + infrared_brute_force_get_button_name(const InfraredBruteForce* brute_force, size_t index) { + if(index >= infrared_brute_force_get_db_size(brute_force)) { + return NULL; + } + + InfraredBruteForceRecordDict_it_t it; + size_t current_index = 0; + + for(InfraredBruteForceRecordDict_it(it, brute_force->records); + !InfraredBruteForceRecordDict_end_p(it); + InfraredBruteForceRecordDict_next(it)) { + if(current_index == index) { + const char* button_name = + furi_string_get_cstr(InfraredBruteForceRecordDict_cref(it)->key); + + return button_name; + } + current_index++; + } + + return NULL; //just as fallback +} diff --git a/applications/main/infrared/infrared_brute_force.h b/applications/main/infrared/infrared_brute_force.h index 8796422576..13889be61d 100644 --- a/applications/main/infrared/infrared_brute_force.h +++ b/applications/main/infrared/infrared_brute_force.h @@ -10,6 +10,7 @@ #include #include +#include #include "infrared_error_code.h" /** @@ -109,3 +110,22 @@ void infrared_brute_force_add_record( * @param[in,out] brute_force pointer to the instance to be reset. */ void infrared_brute_force_reset(InfraredBruteForce* brute_force); + +/** + * @brief Get the total number of unique button names in the database, for example, + * if a button name is "Power" and it appears 3 times in the db, then the + * db_size is 1, instead of 3. + * + * @param[in] brute_force pointer to the InfraredBruteForce instance. + * @return size_t number of unique button names. + */ +size_t infrared_brute_force_get_db_size(const InfraredBruteForce* brute_force); + +/** + * @brief Get the button name at the specified index. + * + * @param[in] brute_force pointer to the InfraredBruteForce instance. + * @param[in] index index of the button name to retrieve. + * @return const char* button name, or NULL if index is out of range. + */ +const char* infrared_brute_force_get_button_name(const InfraredBruteForce* brute_force, size_t index); diff --git a/applications/main/infrared/scenes/common/infrared_scene_universal_common.c b/applications/main/infrared/scenes/common/infrared_scene_universal_common.c index a52f141c47..b8de627038 100644 --- a/applications/main/infrared/scenes/common/infrared_scene_universal_common.c +++ b/applications/main/infrared/scenes/common/infrared_scene_universal_common.c @@ -51,6 +51,16 @@ void infrared_scene_universal_common_on_enter(void* context) { infrared_blocking_task_start(infrared, infrared_scene_universal_common_task_callback); } +void infrared_scene_universal_common_on_enter_more_devices(void* context) { + InfraredApp* infrared = context; + view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical); + view_stack_add_view(infrared->view_stack, button_menu_get_view(infrared->button_menu)); + + // Load universal remote data in background + infrared_blocking_task_start(infrared, infrared_scene_universal_common_task_callback); + view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack); +} + bool infrared_scene_universal_common_on_event(void* context, SceneManagerEvent event) { InfraredApp* infrared = context; SceneManager* scene_manager = infrared->scene_manager; @@ -114,4 +124,4 @@ void infrared_scene_universal_common_on_exit(void* context) { view_stack_remove_view(infrared->view_stack, button_panel_get_view(button_panel)); infrared_brute_force_reset(infrared->brute_force); button_panel_reset(button_panel); -} +} \ No newline at end of file diff --git a/applications/main/infrared/scenes/infrared_scene_config.h b/applications/main/infrared/scenes/infrared_scene_config.h index c0938f9c73..d7012ee607 100644 --- a/applications/main/infrared/scenes/infrared_scene_config.h +++ b/applications/main/infrared/scenes/infrared_scene_config.h @@ -23,6 +23,7 @@ ADD_SCENE(infrared, universal_audio, UniversalAudio) ADD_SCENE(infrared, universal_led, UniversalLED) ADD_SCENE(infrared, universal_ac, UniversalAC) ADD_SCENE(infrared, universal_fan, UniversalFan) +ADD_SCENE(infrared, universal_more_devices, UniversalMoreDevices) ADD_SCENE(infrared, gpio_settings, GpioSettings) ADD_SCENE(infrared, debug, Debug) ADD_SCENE(infrared, error_databases, ErrorDatabases) diff --git a/applications/main/infrared/scenes/infrared_scene_universal.c b/applications/main/infrared/scenes/infrared_scene_universal.c index 1e00232aa7..9c33feed29 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal.c +++ b/applications/main/infrared/scenes/infrared_scene_universal.c @@ -9,6 +9,7 @@ typedef enum { SubmenuIndexUniversalMonitor, SubmenuIndexUniversalDigitalSign, SubmenuIndexUniversalLED, + SubmenuIndexUniversalMoreDevices, } SubmenuIndex; static void infrared_scene_universal_submenu_callback(void* context, uint32_t index) { @@ -76,6 +77,13 @@ void infrared_scene_universal_on_enter(void* context) { infrared_scene_universal_submenu_callback, context); + submenu_add_item( + submenu, + "More Devices", + SubmenuIndexUniversalMoreDevices, + infrared_scene_universal_submenu_callback, + context); + submenu_set_selected_item( submenu, scene_manager_get_scene_state(infrared->scene_manager, InfraredSceneUniversal)); @@ -112,6 +120,10 @@ bool infrared_scene_universal_on_event(void* context, SceneManagerEvent event) { } else if(event.event == SubmenuIndexUniversalLED) { scene_manager_next_scene(scene_manager, InfraredSceneUniversalLED); consumed = true; + } else if(event.event == SubmenuIndexUniversalMoreDevices) { + furi_string_set(infrared->file_path, INFRARED_APP_FOLDER); + scene_manager_next_scene(scene_manager, InfraredSceneUniversalMoreDevices); + consumed = true; } scene_manager_set_scene_state(scene_manager, InfraredSceneUniversal, event.event); } diff --git a/applications/main/infrared/scenes/infrared_scene_universal_led.c b/applications/main/infrared/scenes/infrared_scene_universal_led.c index 1055f71e97..c0bd64b2c1 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_led.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_led.c @@ -8,7 +8,6 @@ void infrared_scene_universal_led_on_enter(void* context) { InfraredBruteForce* brute_force = infrared->brute_force; infrared_brute_force_set_db_filename(brute_force, EXT_PATH("infrared/assets/led.ir")); - button_panel_reserve(button_panel, 2, 2); uint32_t i = 0; button_panel_add_item( diff --git a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c new file mode 100644 index 0000000000..15a1fd81c0 --- /dev/null +++ b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c @@ -0,0 +1,169 @@ +#include "../infrared_app_i.h" +#include +#include +#include + + +static void + infrared_scene_universal_more_devices_callback(void* context, int32_t index, InputType type) { + UNUSED(type); + InfraredApp* infrared = context; + uint32_t event = infrared_custom_event_pack(InfraredCustomEventTypeButtonSelected, index); + view_dispatcher_send_custom_event(infrared->view_dispatcher, event); +} + +static void infrared_scene_universal_more_devices_progress_back_callback(void* context) { + InfraredApp* infrared = context; + uint32_t event = infrared_custom_event_pack(InfraredCustomEventTypeBackPressed, -1); + view_dispatcher_send_custom_event(infrared->view_dispatcher, event); +} + +static void + infrared_scene_universal_more_devices_show_popup(InfraredApp* infrared, uint32_t record_count) { + ViewStack* view_stack = infrared->view_stack; + InfraredProgressView* progress = infrared->progress; + infrared_progress_view_set_progress_total(progress, record_count); + infrared_progress_view_set_back_callback( + progress, infrared_scene_universal_more_devices_progress_back_callback, infrared); + view_stack_add_view(view_stack, infrared_progress_view_get_view(progress)); + infrared_play_notification_message(infrared, InfraredNotificationMessageBlinkStartSend); +} + +static void infrared_scene_universal_more_devices_hide_popup(InfraredApp* infrared) { + ViewStack* view_stack = infrared->view_stack; + InfraredProgressView* progress = infrared->progress; + view_stack_remove_view(view_stack, infrared_progress_view_get_view(progress)); + infrared_play_notification_message(infrared, InfraredNotificationMessageBlinkStop); +} + +static int32_t infrared_scene_universal_more_devices_task_callback(void* context) { + InfraredApp* infrared = context; + const InfraredErrorCode error = infrared_brute_force_calculate_messages(infrared->brute_force); + view_dispatcher_send_custom_event( + infrared->view_dispatcher, + infrared_custom_event_pack(InfraredCustomEventTypeTaskFinished, 0)); + + return error; +} + +void infrared_scene_universal_more_devices_on_enter(void* context) { + InfraredApp* infrared = context; + ButtonMenu* button_menu = infrared->button_menu; + InfraredBruteForce* brute_force = infrared->brute_force; + + DialogsFileBrowserOptions browser_options; + dialog_file_browser_set_basic_options(&browser_options, INFRARED_APP_EXTENSION, &I_ir_10px); + browser_options.base_path = INFRARED_APP_FOLDER; + + bool file_selected = dialog_file_browser_show( + infrared->dialogs, infrared->file_path, infrared->file_path, &browser_options); + + if(file_selected) { + infrared_brute_force_set_db_filename( + brute_force, furi_string_get_cstr(infrared->file_path)); + + // load db previously cuz need to use the db to add btns in runtime + InfraredErrorCode error = infrared_brute_force_calculate_messages(brute_force); + + if(INFRARED_ERROR_PRESENT(error)) { + infrared_show_error_message(infrared, "Failed to load database"); + scene_manager_previous_scene(infrared->scene_manager); + return; + } + + // add btns + for(size_t i = 0; i < infrared_brute_force_get_db_size(brute_force); ++i) { + const char* button_name = infrared_brute_force_get_button_name(brute_force, i); + button_menu_add_item( + button_menu, + button_name, + i, + infrared_scene_universal_more_devices_callback, + ButtonMenuItemTypeCommon, + infrared); + } + + ///header name handler + const char* file_name = strrchr(furi_string_get_cstr(infrared->file_path), '/'); + if(file_name) { + file_name++; // skip dir seperator + } else { + file_name = furi_string_get_cstr(infrared->file_path); // fallback + } + button_menu_set_header(button_menu, file_name); + + view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical); + view_stack_add_view(infrared->view_stack, button_menu_get_view(infrared->button_menu)); + + // Load universal remote data in background + infrared_blocking_task_start(infrared, infrared_scene_universal_more_devices_task_callback); + view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack); + } else { + scene_manager_previous_scene(infrared->scene_manager); + } +} + +bool infrared_scene_universal_more_devices_on_event(void* context, SceneManagerEvent event) { + InfraredApp* infrared = context; + SceneManager* scene_manager = infrared->scene_manager; + InfraredBruteForce* brute_force = infrared->brute_force; + bool consumed = false; + + if(infrared_brute_force_is_started(brute_force)) { + if(event.type == SceneManagerEventTypeTick) { + bool success = infrared_brute_force_send_next(brute_force); + if(success) { + success = infrared_progress_view_increase_progress(infrared->progress); + } + if(!success) { + infrared_brute_force_stop(brute_force); + infrared_scene_universal_more_devices_hide_popup(infrared); + } + consumed = true; + } else if(event.type == SceneManagerEventTypeCustom) { + if(infrared_custom_event_get_type(event.event) == InfraredCustomEventTypeBackPressed) { + infrared_brute_force_stop(brute_force); + infrared_scene_universal_more_devices_hide_popup(infrared); + } + consumed = true; + } + } else { + if(event.type == SceneManagerEventTypeBack) { + scene_manager_previous_scene(scene_manager); + consumed = true; + } else if(event.type == SceneManagerEventTypeCustom) { + uint16_t event_type; + int16_t event_value; + infrared_custom_event_unpack(event.event, &event_type, &event_value); + + if(event_type == InfraredCustomEventTypeButtonSelected) { + uint32_t record_count; + if(infrared_brute_force_start(brute_force, event_value, &record_count)) { + dolphin_deed(DolphinDeedIrSend); + infrared_scene_universal_more_devices_show_popup(infrared, record_count); + } else { + scene_manager_next_scene(scene_manager, InfraredSceneErrorDatabases); + } + } else if(event_type == InfraredCustomEventTypeTaskFinished) { + const InfraredErrorCode task_error = infrared_blocking_task_finalize(infrared); + + if(INFRARED_ERROR_PRESENT(task_error)) { + scene_manager_next_scene(infrared->scene_manager, InfraredSceneErrorDatabases); + } else { + view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack); + } + } + consumed = true; + } + } + + return consumed; +} + +void infrared_scene_universal_more_devices_on_exit(void* context) { + InfraredApp* infrared = context; + ButtonMenu* button_menu = infrared->button_menu; + view_stack_remove_view(infrared->view_stack, button_menu_get_view(button_menu)); + button_menu_reset(button_menu); + infrared_brute_force_reset(infrared->brute_force); +} diff --git a/applications/main/infrared/views/infrared_progress_view.c b/applications/main/infrared/views/infrared_progress_view.c index 1f491e4abf..a2bb64c287 100644 --- a/applications/main/infrared/views/infrared_progress_view.c +++ b/applications/main/infrared/views/infrared_progress_view.c @@ -81,9 +81,9 @@ bool infrared_progress_view_input_callback(InputEvent* event, void* context) { if(instance->back_callback) { instance->back_callback(instance->context); } + return true; } - - return true; + return false; } InfraredProgressView* infrared_progress_view_alloc(void) { From f8723aa6fa33ca6d1a82422c38b01301c9c9acf7 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Thu, 10 Oct 2024 16:51:44 +0800 Subject: [PATCH 02/24] comments --- .../scenes/infrared_scene_universal_more_devices.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c index 15a1fd81c0..a0f81d6a93 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c @@ -47,6 +47,15 @@ static int32_t infrared_scene_universal_more_devices_task_callback(void* context } void infrared_scene_universal_more_devices_on_enter(void* context) { + // in this func, note that it's actually loaded the db twice, here's what i did and why it's harmless: + // 1. load db previously cuz need to use the db to add btns in runtime + // 2. load db again with blocking task + // reason: + // 1. there's a funny policy in infrared_brute_force_calculate_messages func, that it'll check if name in it, if yes, it will increase the num and add, if yes, it will make a new field. + // it's probablt a work around to satisfying other places, but since momentum is not a distro, i really don't want to edit that func to make it's hard to merge upstream changes. + // why it's harmless: + // 1. do it twice can make it cover the first custom item. + // 2. only the count (which controls the for loop to go through the next item by name field) x2, not index, so signal index not impacted. InfraredApp* infrared = context; ButtonMenu* button_menu = infrared->button_menu; InfraredBruteForce* brute_force = infrared->brute_force; From e6b6edc9ef943f5551e0d5b94bd5a18f7ead4126 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Thu, 10 Oct 2024 17:29:29 +0800 Subject: [PATCH 03/24] remove trash --- .../scenes/common/infrared_scene_universal_common.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/applications/main/infrared/scenes/common/infrared_scene_universal_common.c b/applications/main/infrared/scenes/common/infrared_scene_universal_common.c index b8de627038..e71892cfad 100644 --- a/applications/main/infrared/scenes/common/infrared_scene_universal_common.c +++ b/applications/main/infrared/scenes/common/infrared_scene_universal_common.c @@ -51,16 +51,6 @@ void infrared_scene_universal_common_on_enter(void* context) { infrared_blocking_task_start(infrared, infrared_scene_universal_common_task_callback); } -void infrared_scene_universal_common_on_enter_more_devices(void* context) { - InfraredApp* infrared = context; - view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical); - view_stack_add_view(infrared->view_stack, button_menu_get_view(infrared->button_menu)); - - // Load universal remote data in background - infrared_blocking_task_start(infrared, infrared_scene_universal_common_task_callback); - view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack); -} - bool infrared_scene_universal_common_on_event(void* context, SceneManagerEvent event) { InfraredApp* infrared = context; SceneManager* scene_manager = infrared->scene_manager; From cb8984668a02443dafb48d71b78a8f75f2f9d173 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Thu, 10 Oct 2024 17:32:14 +0800 Subject: [PATCH 04/24] remove code that mistakenly added from merging conflicts --- .../main/infrared/scenes/infrared_scene_universal.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/applications/main/infrared/scenes/infrared_scene_universal.c b/applications/main/infrared/scenes/infrared_scene_universal.c index 024dc3db0d..de8c6bd2eb 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal.c +++ b/applications/main/infrared/scenes/infrared_scene_universal.c @@ -86,13 +86,6 @@ void infrared_scene_universal_on_enter(void* context) { infrared_scene_universal_submenu_callback, context); - submenu_add_item( - submenu, - "LEDs", - SubmenuIndexUniversalLED, - infrared_scene_universal_submenu_callback, - context); - submenu_add_item( submenu, "More Devices", @@ -139,9 +132,6 @@ bool infrared_scene_universal_on_event(void* context, SceneManagerEvent event) { } else if(event.event == SubmenuIndexUniversalDigitalSign) { scene_manager_next_scene(scene_manager, InfraredSceneUniversalDigitalSign); consumed = true; - } else if(event.event == SubmenuIndexUniversalLED) { - scene_manager_next_scene(scene_manager, InfraredSceneUniversalLEDs); - consumed = true; } else if(event.event == SubmenuIndexUniversalMoreDevices) { furi_string_set(infrared->file_path, INFRARED_APP_FOLDER); scene_manager_next_scene(scene_manager, InfraredSceneUniversalMoreDevices); From 89fb274676fd69ff240f5d00dc44fa2c75209e60 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Thu, 10 Oct 2024 17:33:40 +0800 Subject: [PATCH 05/24] remove code that mistakenly added from merging conflicts --- applications/main/infrared/scenes/infrared_scene_universal.c | 1 - 1 file changed, 1 deletion(-) diff --git a/applications/main/infrared/scenes/infrared_scene_universal.c b/applications/main/infrared/scenes/infrared_scene_universal.c index de8c6bd2eb..39dcd2376b 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal.c +++ b/applications/main/infrared/scenes/infrared_scene_universal.c @@ -10,7 +10,6 @@ typedef enum { SubmenuIndexUniversalBluray, SubmenuIndexUniversalMonitor, SubmenuIndexUniversalDigitalSign, - SubmenuIndexUniversalLED, SubmenuIndexUniversalMoreDevices, } SubmenuIndex; From 8d2289dce820529a201749211208317be15ca7b3 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Thu, 10 Oct 2024 17:43:51 +0800 Subject: [PATCH 06/24] format --- applications/main/infrared/infrared_brute_force.h | 3 ++- .../scenes/common/infrared_scene_universal_common.c | 2 +- .../main/infrared/scenes/infrared_scene_universal.c | 2 +- .../infrared/scenes/infrared_scene_universal_more_devices.c | 6 +++--- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/applications/main/infrared/infrared_brute_force.h b/applications/main/infrared/infrared_brute_force.h index 13889be61d..553e000c13 100644 --- a/applications/main/infrared/infrared_brute_force.h +++ b/applications/main/infrared/infrared_brute_force.h @@ -128,4 +128,5 @@ size_t infrared_brute_force_get_db_size(const InfraredBruteForce* brute_force); * @param[in] index index of the button name to retrieve. * @return const char* button name, or NULL if index is out of range. */ -const char* infrared_brute_force_get_button_name(const InfraredBruteForce* brute_force, size_t index); +const char* + infrared_brute_force_get_button_name(const InfraredBruteForce* brute_force, size_t index); diff --git a/applications/main/infrared/scenes/common/infrared_scene_universal_common.c b/applications/main/infrared/scenes/common/infrared_scene_universal_common.c index e71892cfad..a52f141c47 100644 --- a/applications/main/infrared/scenes/common/infrared_scene_universal_common.c +++ b/applications/main/infrared/scenes/common/infrared_scene_universal_common.c @@ -114,4 +114,4 @@ void infrared_scene_universal_common_on_exit(void* context) { view_stack_remove_view(infrared->view_stack, button_panel_get_view(button_panel)); infrared_brute_force_reset(infrared->brute_force); button_panel_reset(button_panel); -} \ No newline at end of file +} diff --git a/applications/main/infrared/scenes/infrared_scene_universal.c b/applications/main/infrared/scenes/infrared_scene_universal.c index 39dcd2376b..9c228a59ef 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal.c +++ b/applications/main/infrared/scenes/infrared_scene_universal.c @@ -85,7 +85,7 @@ void infrared_scene_universal_on_enter(void* context) { infrared_scene_universal_submenu_callback, context); - submenu_add_item( + submenu_add_item( submenu, "More Devices", SubmenuIndexUniversalMoreDevices, diff --git a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c index a0f81d6a93..d50099c98d 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c @@ -3,7 +3,6 @@ #include #include - static void infrared_scene_universal_more_devices_callback(void* context, int32_t index, InputType type) { UNUSED(type); @@ -53,7 +52,7 @@ void infrared_scene_universal_more_devices_on_enter(void* context) { // reason: // 1. there's a funny policy in infrared_brute_force_calculate_messages func, that it'll check if name in it, if yes, it will increase the num and add, if yes, it will make a new field. // it's probablt a work around to satisfying other places, but since momentum is not a distro, i really don't want to edit that func to make it's hard to merge upstream changes. - // why it's harmless: + // why it's harmless: // 1. do it twice can make it cover the first custom item. // 2. only the count (which controls the for loop to go through the next item by name field) x2, not index, so signal index not impacted. InfraredApp* infrared = context; @@ -105,7 +104,8 @@ void infrared_scene_universal_more_devices_on_enter(void* context) { view_stack_add_view(infrared->view_stack, button_menu_get_view(infrared->button_menu)); // Load universal remote data in background - infrared_blocking_task_start(infrared, infrared_scene_universal_more_devices_task_callback); + infrared_blocking_task_start( + infrared, infrared_scene_universal_more_devices_task_callback); view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack); } else { scene_manager_previous_scene(infrared->scene_manager); From 3602c6992fa1cf718edb957a5646874e972b6ac1 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Thu, 10 Oct 2024 17:47:11 +0800 Subject: [PATCH 07/24] remove header that added during debugging --- applications/main/infrared/infrared_brute_force.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/applications/main/infrared/infrared_brute_force.c b/applications/main/infrared/infrared_brute_force.c index af11947e04..925bbd7001 100644 --- a/applications/main/infrared/infrared_brute_force.c +++ b/applications/main/infrared/infrared_brute_force.c @@ -6,8 +6,6 @@ #include "infrared_signal.h" -#include - typedef struct { uint32_t index; uint32_t count; From 9e45d35c00cadf0fcf4f4265a3099b4e901e3e47 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Fri, 11 Oct 2024 20:31:02 +0800 Subject: [PATCH 08/24] ecit name --- applications/main/infrared/scenes/infrared_scene_universal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/main/infrared/scenes/infrared_scene_universal.c b/applications/main/infrared/scenes/infrared_scene_universal.c index 9c228a59ef..3f8078bb77 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal.c +++ b/applications/main/infrared/scenes/infrared_scene_universal.c @@ -87,7 +87,7 @@ void infrared_scene_universal_on_enter(void* context) { submenu_add_item( submenu, - "More Devices", + "Load Custom DB", SubmenuIndexUniversalMoreDevices, infrared_scene_universal_submenu_callback, context); From 15fdf9c5ebc7ffc1b84aeeb47d9584f50686af46 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 11 Oct 2024 18:35:16 +0100 Subject: [PATCH 09/24] Revert some whitespace changes to avoid future conflicts --- applications/main/infrared/infrared_brute_force.c | 11 ++--------- .../main/infrared/scenes/infrared_scene_config.h | 1 - .../main/infrared/views/infrared_progress_view.c | 1 + 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/applications/main/infrared/infrared_brute_force.c b/applications/main/infrared/infrared_brute_force.c index 925bbd7001..e73d895107 100644 --- a/applications/main/infrared/infrared_brute_force.c +++ b/applications/main/infrared/infrared_brute_force.c @@ -85,9 +85,9 @@ InfraredErrorCode infrared_brute_force_calculate_messages(InfraredBruteForce* br infrared_signal_free(signal); furi_string_free(signal_name); + flipper_format_free(ff); furi_record_close(RECORD_STORAGE); - return error; } @@ -96,12 +96,10 @@ bool infrared_brute_force_start( uint32_t index, uint32_t* record_count) { furi_assert(!brute_force->is_started); - bool success = false; *record_count = 0; InfraredBruteForceRecordDict_it_t it; - for(InfraredBruteForceRecordDict_it(it, brute_force->records); !InfraredBruteForceRecordDict_end_p(it); InfraredBruteForceRecordDict_next(it)) { @@ -118,17 +116,12 @@ bool infrared_brute_force_start( if(*record_count) { Storage* storage = furi_record_open(RECORD_STORAGE); brute_force->ff = flipper_format_buffered_file_alloc(storage); - brute_force->current_signal = infrared_signal_alloc(); - brute_force->is_started = true; - success = flipper_format_buffered_file_open_existing(brute_force->ff, brute_force->db_filename); - if(!success) infrared_brute_force_stop(brute_force); } - return success; } @@ -160,6 +153,7 @@ bool infrared_brute_force_send_next(InfraredBruteForce* brute_force) { } return success; } + void infrared_brute_force_add_record( InfraredBruteForce* brute_force, uint32_t index, @@ -168,7 +162,6 @@ void infrared_brute_force_add_record( FuriString* key; key = furi_string_alloc_set(name); InfraredBruteForceRecordDict_set_at(brute_force->records, key, value); - furi_string_free(key); } diff --git a/applications/main/infrared/scenes/infrared_scene_config.h b/applications/main/infrared/scenes/infrared_scene_config.h index 91f123453b..81928f95c5 100644 --- a/applications/main/infrared/scenes/infrared_scene_config.h +++ b/applications/main/infrared/scenes/infrared_scene_config.h @@ -25,7 +25,6 @@ ADD_SCENE(infrared, universal_bluray, UniversalBluray) ADD_SCENE(infrared, universal_monitor, UniversalMonitor) ADD_SCENE(infrared, universal_digital_sign, UniversalDigitalSign) ADD_SCENE(infrared, universal_more_devices, UniversalMoreDevices) - ADD_SCENE(infrared, gpio_settings, GpioSettings) ADD_SCENE(infrared, debug, Debug) ADD_SCENE(infrared, error_databases, ErrorDatabases) diff --git a/applications/main/infrared/views/infrared_progress_view.c b/applications/main/infrared/views/infrared_progress_view.c index a2bb64c287..b8bf518c83 100644 --- a/applications/main/infrared/views/infrared_progress_view.c +++ b/applications/main/infrared/views/infrared_progress_view.c @@ -83,6 +83,7 @@ bool infrared_progress_view_input_callback(InputEvent* event, void* context) { } return true; } + return false; } From 67a6f56abe3fbee6e12cc7e8466408eb57b650af Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 11 Oct 2024 18:35:59 +0100 Subject: [PATCH 10/24] get_button_count() --- applications/main/infrared/infrared_brute_force.c | 4 ++-- applications/main/infrared/infrared_brute_force.h | 2 +- .../infrared/scenes/infrared_scene_universal_more_devices.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/applications/main/infrared/infrared_brute_force.c b/applications/main/infrared/infrared_brute_force.c index e73d895107..e920b08326 100644 --- a/applications/main/infrared/infrared_brute_force.c +++ b/applications/main/infrared/infrared_brute_force.c @@ -170,14 +170,14 @@ void infrared_brute_force_reset(InfraredBruteForce* brute_force) { InfraredBruteForceRecordDict_reset(brute_force->records); } -size_t infrared_brute_force_get_db_size(const InfraredBruteForce* brute_force) { +size_t infrared_brute_force_get_button_count(const InfraredBruteForce* brute_force) { size_t size = InfraredBruteForceRecordDict_size(brute_force->records); return size; } const char* infrared_brute_force_get_button_name(const InfraredBruteForce* brute_force, size_t index) { - if(index >= infrared_brute_force_get_db_size(brute_force)) { + if(index >= infrared_brute_force_get_button_count(brute_force)) { return NULL; } diff --git a/applications/main/infrared/infrared_brute_force.h b/applications/main/infrared/infrared_brute_force.h index 553e000c13..1accfc4e18 100644 --- a/applications/main/infrared/infrared_brute_force.h +++ b/applications/main/infrared/infrared_brute_force.h @@ -119,7 +119,7 @@ void infrared_brute_force_reset(InfraredBruteForce* brute_force); * @param[in] brute_force pointer to the InfraredBruteForce instance. * @return size_t number of unique button names. */ -size_t infrared_brute_force_get_db_size(const InfraredBruteForce* brute_force); +size_t infrared_brute_force_get_button_count(const InfraredBruteForce* brute_force); /** * @brief Get the button name at the specified index. diff --git a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c index d50099c98d..d307220f07 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c @@ -80,7 +80,7 @@ void infrared_scene_universal_more_devices_on_enter(void* context) { } // add btns - for(size_t i = 0; i < infrared_brute_force_get_db_size(brute_force); ++i) { + for(size_t i = 0; i < infrared_brute_force_get_button_count(brute_force); ++i) { const char* button_name = infrared_brute_force_get_button_name(brute_force, i); button_menu_add_item( button_menu, From 527630ee2a0056d99661e4c15aa97ec50797d8b2 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 11 Oct 2024 18:45:04 +0100 Subject: [PATCH 11/24] Use same index values --- .../main/infrared/infrared_brute_force.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/applications/main/infrared/infrared_brute_force.c b/applications/main/infrared/infrared_brute_force.c index e920b08326..3c82720463 100644 --- a/applications/main/infrared/infrared_brute_force.c +++ b/applications/main/infrared/infrared_brute_force.c @@ -63,7 +63,7 @@ InfraredErrorCode infrared_brute_force_calculate_messages(InfraredBruteForce* br if(!flipper_format_buffered_file_open_existing(ff, brute_force->db_filename)) { error = InfraredErrorCodeFileOperationFailed; } else { - uint32_t total_signals = 0; + uint32_t button_index = 0; while(infrared_signal_read_name(ff, signal_name) == InfraredErrorCodeNone) { error = infrared_signal_read_body(signal, ff); if(INFRARED_ERROR_PRESENT(error) || !infrared_signal_is_valid(signal)) { @@ -77,9 +77,9 @@ InfraredErrorCode infrared_brute_force_calculate_messages(InfraredBruteForce* br } else { infrared_brute_force_add_record( - brute_force, total_signals, furi_string_get_cstr(signal_name)); + brute_force, button_index, furi_string_get_cstr(signal_name)); } - total_signals++; + button_index++; } } @@ -182,18 +182,17 @@ const char* } InfraredBruteForceRecordDict_it_t it; - size_t current_index = 0; - for(InfraredBruteForceRecordDict_it(it, brute_force->records); !InfraredBruteForceRecordDict_end_p(it); InfraredBruteForceRecordDict_next(it)) { - if(current_index == index) { - const char* button_name = - furi_string_get_cstr(InfraredBruteForceRecordDict_cref(it)->key); - + // Dict elements are unordered, they may be shuffled while adding elements, so the + // index used in add_record() may differ when iterating here, so we have to check + // the stored index not "position" index + const InfraredBruteForceRecordDict_itref_t* pair = InfraredBruteForceRecordDict_cref(it); + if(pair->value.index == index) { + const char* button_name = furi_string_get_cstr(pair->key); return button_name; } - current_index++; } return NULL; //just as fallback From 92debefa9a59baa2e5dd909c0ff19cb98f3e35db Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 11 Oct 2024 18:59:10 +0100 Subject: [PATCH 12/24] Use common functions where possible --- .../infrared_scene_universal_more_devices.c | 85 ++----------------- 1 file changed, 6 insertions(+), 79 deletions(-) diff --git a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c index d307220f07..bb5d464675 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c @@ -1,4 +1,7 @@ #include "../infrared_app_i.h" + +#include "common/infrared_scene_universal_common.h" + #include #include #include @@ -11,30 +14,6 @@ static void view_dispatcher_send_custom_event(infrared->view_dispatcher, event); } -static void infrared_scene_universal_more_devices_progress_back_callback(void* context) { - InfraredApp* infrared = context; - uint32_t event = infrared_custom_event_pack(InfraredCustomEventTypeBackPressed, -1); - view_dispatcher_send_custom_event(infrared->view_dispatcher, event); -} - -static void - infrared_scene_universal_more_devices_show_popup(InfraredApp* infrared, uint32_t record_count) { - ViewStack* view_stack = infrared->view_stack; - InfraredProgressView* progress = infrared->progress; - infrared_progress_view_set_progress_total(progress, record_count); - infrared_progress_view_set_back_callback( - progress, infrared_scene_universal_more_devices_progress_back_callback, infrared); - view_stack_add_view(view_stack, infrared_progress_view_get_view(progress)); - infrared_play_notification_message(infrared, InfraredNotificationMessageBlinkStartSend); -} - -static void infrared_scene_universal_more_devices_hide_popup(InfraredApp* infrared) { - ViewStack* view_stack = infrared->view_stack; - InfraredProgressView* progress = infrared->progress; - view_stack_remove_view(view_stack, infrared_progress_view_get_view(progress)); - infrared_play_notification_message(infrared, InfraredNotificationMessageBlinkStop); -} - static int32_t infrared_scene_universal_more_devices_task_callback(void* context) { InfraredApp* infrared = context; const InfraredErrorCode error = infrared_brute_force_calculate_messages(infrared->brute_force); @@ -113,66 +92,14 @@ void infrared_scene_universal_more_devices_on_enter(void* context) { } bool infrared_scene_universal_more_devices_on_event(void* context, SceneManagerEvent event) { - InfraredApp* infrared = context; - SceneManager* scene_manager = infrared->scene_manager; - InfraredBruteForce* brute_force = infrared->brute_force; - bool consumed = false; - - if(infrared_brute_force_is_started(brute_force)) { - if(event.type == SceneManagerEventTypeTick) { - bool success = infrared_brute_force_send_next(brute_force); - if(success) { - success = infrared_progress_view_increase_progress(infrared->progress); - } - if(!success) { - infrared_brute_force_stop(brute_force); - infrared_scene_universal_more_devices_hide_popup(infrared); - } - consumed = true; - } else if(event.type == SceneManagerEventTypeCustom) { - if(infrared_custom_event_get_type(event.event) == InfraredCustomEventTypeBackPressed) { - infrared_brute_force_stop(brute_force); - infrared_scene_universal_more_devices_hide_popup(infrared); - } - consumed = true; - } - } else { - if(event.type == SceneManagerEventTypeBack) { - scene_manager_previous_scene(scene_manager); - consumed = true; - } else if(event.type == SceneManagerEventTypeCustom) { - uint16_t event_type; - int16_t event_value; - infrared_custom_event_unpack(event.event, &event_type, &event_value); - - if(event_type == InfraredCustomEventTypeButtonSelected) { - uint32_t record_count; - if(infrared_brute_force_start(brute_force, event_value, &record_count)) { - dolphin_deed(DolphinDeedIrSend); - infrared_scene_universal_more_devices_show_popup(infrared, record_count); - } else { - scene_manager_next_scene(scene_manager, InfraredSceneErrorDatabases); - } - } else if(event_type == InfraredCustomEventTypeTaskFinished) { - const InfraredErrorCode task_error = infrared_blocking_task_finalize(infrared); - - if(INFRARED_ERROR_PRESENT(task_error)) { - scene_manager_next_scene(infrared->scene_manager, InfraredSceneErrorDatabases); - } else { - view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack); - } - } - consumed = true; - } - } - - return consumed; + return infrared_scene_universal_common_on_event(context, event); } void infrared_scene_universal_more_devices_on_exit(void* context) { + // Common function won't work since we use ButtonMenu not ButtonPanel InfraredApp* infrared = context; ButtonMenu* button_menu = infrared->button_menu; view_stack_remove_view(infrared->view_stack, button_menu_get_view(button_menu)); - button_menu_reset(button_menu); infrared_brute_force_reset(infrared->brute_force); + button_menu_reset(button_menu); } From 9c8f85484a6e5785368aef805851c7ddb3359cab Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 11 Oct 2024 18:59:49 +0100 Subject: [PATCH 13/24] Unroll long if into guard check --- .../infrared_scene_universal_more_devices.c | 92 +++++++++---------- 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c index bb5d464675..da11928893 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c @@ -6,8 +6,10 @@ #include #include -static void - infrared_scene_universal_more_devices_callback(void* context, int32_t index, InputType type) { +static void infrared_scene_universal_more_devices_item_callback( + void* context, + int32_t index, + InputType type) { UNUSED(type); InfraredApp* infrared = context; uint32_t event = infrared_custom_event_pack(InfraredCustomEventTypeButtonSelected, index); @@ -41,54 +43,50 @@ void infrared_scene_universal_more_devices_on_enter(void* context) { DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options(&browser_options, INFRARED_APP_EXTENSION, &I_ir_10px); browser_options.base_path = INFRARED_APP_FOLDER; + if(!dialog_file_browser_show( + infrared->dialogs, infrared->file_path, infrared->file_path, &browser_options)) { + scene_manager_previous_scene(infrared->scene_manager); + return; + } - bool file_selected = dialog_file_browser_show( - infrared->dialogs, infrared->file_path, infrared->file_path, &browser_options); - - if(file_selected) { - infrared_brute_force_set_db_filename( - brute_force, furi_string_get_cstr(infrared->file_path)); - - // load db previously cuz need to use the db to add btns in runtime - InfraredErrorCode error = infrared_brute_force_calculate_messages(brute_force); - - if(INFRARED_ERROR_PRESENT(error)) { - infrared_show_error_message(infrared, "Failed to load database"); - scene_manager_previous_scene(infrared->scene_manager); - return; - } - - // add btns - for(size_t i = 0; i < infrared_brute_force_get_button_count(brute_force); ++i) { - const char* button_name = infrared_brute_force_get_button_name(brute_force, i); - button_menu_add_item( - button_menu, - button_name, - i, - infrared_scene_universal_more_devices_callback, - ButtonMenuItemTypeCommon, - infrared); - } - - ///header name handler - const char* file_name = strrchr(furi_string_get_cstr(infrared->file_path), '/'); - if(file_name) { - file_name++; // skip dir seperator - } else { - file_name = furi_string_get_cstr(infrared->file_path); // fallback - } - button_menu_set_header(button_menu, file_name); - - view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical); - view_stack_add_view(infrared->view_stack, button_menu_get_view(infrared->button_menu)); - - // Load universal remote data in background - infrared_blocking_task_start( - infrared, infrared_scene_universal_more_devices_task_callback); - view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack); - } else { + infrared_brute_force_set_db_filename(brute_force, furi_string_get_cstr(infrared->file_path)); + + // load db previously cuz need to use the db to add btns in runtime + InfraredErrorCode error = infrared_brute_force_calculate_messages(brute_force); + + if(INFRARED_ERROR_PRESENT(error)) { + infrared_show_error_message(infrared, "Failed to load database"); scene_manager_previous_scene(infrared->scene_manager); + return; + } + + // add btns + for(size_t i = 0; i < infrared_brute_force_get_button_count(brute_force); ++i) { + const char* button_name = infrared_brute_force_get_button_name(brute_force, i); + button_menu_add_item( + button_menu, + button_name, + i, + infrared_scene_universal_more_devices_item_callback, + ButtonMenuItemTypeCommon, + infrared); + } + + ///header name handler + const char* file_name = strrchr(furi_string_get_cstr(infrared->file_path), '/'); + if(file_name) { + file_name++; // skip dir seperator + } else { + file_name = furi_string_get_cstr(infrared->file_path); // fallback } + button_menu_set_header(button_menu, file_name); + + view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical); + view_stack_add_view(infrared->view_stack, button_menu_get_view(infrared->button_menu)); + + // Load universal remote data in background + infrared_blocking_task_start(infrared, infrared_scene_universal_more_devices_task_callback); + view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack); } bool infrared_scene_universal_more_devices_on_event(void* context, SceneManagerEvent event) { From 44a26a68f9b818c1437cacf65bf85ea2ce1ee1d3 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 11 Oct 2024 19:15:21 +0100 Subject: [PATCH 14/24] Fix furi check failed due to inflated button index --- applications/main/infrared/infrared_brute_force.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/applications/main/infrared/infrared_brute_force.c b/applications/main/infrared/infrared_brute_force.c index 3c82720463..572b4dccb3 100644 --- a/applications/main/infrared/infrared_brute_force.c +++ b/applications/main/infrared/infrared_brute_force.c @@ -74,12 +74,10 @@ InfraredErrorCode infrared_brute_force_calculate_messages(InfraredBruteForce* br InfraredBruteForceRecordDict_get(brute_force->records, signal_name); if(record) { //-V547 ++(record->count); - } else { infrared_brute_force_add_record( - brute_force, button_index, furi_string_get_cstr(signal_name)); + brute_force, button_index++, furi_string_get_cstr(signal_name)); } - button_index++; } } From c146d991f2fcecc49512fe6d52c464b4d33a9646 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 11 Oct 2024 19:15:34 +0100 Subject: [PATCH 15/24] Show "assets" folders --- .../main/infrared/scenes/infrared_scene_universal_more_devices.c | 1 + 1 file changed, 1 insertion(+) diff --git a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c index da11928893..fdef900254 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c @@ -43,6 +43,7 @@ void infrared_scene_universal_more_devices_on_enter(void* context) { DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options(&browser_options, INFRARED_APP_EXTENSION, &I_ir_10px); browser_options.base_path = INFRARED_APP_FOLDER; + browser_options.skip_assets = false; if(!dialog_file_browser_show( infrared->dialogs, infrared->file_path, infrared->file_path, &browser_options)) { scene_manager_previous_scene(infrared->scene_manager); From 0b11d7cd242d0baea6eef72a3515c71ab7620eaf Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 11 Oct 2024 19:43:40 +0100 Subject: [PATCH 16/24] Load DB file only once and show loading animation --- .../infrared_scene_universal_more_devices.c | 55 ++++++++----------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c index fdef900254..98193ad3fb 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c @@ -18,7 +18,24 @@ static void infrared_scene_universal_more_devices_item_callback( static int32_t infrared_scene_universal_more_devices_task_callback(void* context) { InfraredApp* infrared = context; + ButtonMenu* button_menu = infrared->button_menu; + InfraredBruteForce* brute_force = infrared->brute_force; const InfraredErrorCode error = infrared_brute_force_calculate_messages(infrared->brute_force); + + if(!INFRARED_ERROR_PRESENT(error)) { + // add btns + for(size_t i = 0; i < infrared_brute_force_get_button_count(brute_force); ++i) { + const char* button_name = infrared_brute_force_get_button_name(brute_force, i); + button_menu_add_item( + button_menu, + button_name, + i, + infrared_scene_universal_more_devices_item_callback, + ButtonMenuItemTypeCommon, + infrared); + } + } + view_dispatcher_send_custom_event( infrared->view_dispatcher, infrared_custom_event_pack(InfraredCustomEventTypeTaskFinished, 0)); @@ -27,15 +44,6 @@ static int32_t infrared_scene_universal_more_devices_task_callback(void* context } void infrared_scene_universal_more_devices_on_enter(void* context) { - // in this func, note that it's actually loaded the db twice, here's what i did and why it's harmless: - // 1. load db previously cuz need to use the db to add btns in runtime - // 2. load db again with blocking task - // reason: - // 1. there's a funny policy in infrared_brute_force_calculate_messages func, that it'll check if name in it, if yes, it will increase the num and add, if yes, it will make a new field. - // it's probablt a work around to satisfying other places, but since momentum is not a distro, i really don't want to edit that func to make it's hard to merge upstream changes. - // why it's harmless: - // 1. do it twice can make it cover the first custom item. - // 2. only the count (which controls the for loop to go through the next item by name field) x2, not index, so signal index not impacted. InfraredApp* infrared = context; ButtonMenu* button_menu = infrared->button_menu; InfraredBruteForce* brute_force = infrared->brute_force; @@ -52,28 +60,9 @@ void infrared_scene_universal_more_devices_on_enter(void* context) { infrared_brute_force_set_db_filename(brute_force, furi_string_get_cstr(infrared->file_path)); - // load db previously cuz need to use the db to add btns in runtime - InfraredErrorCode error = infrared_brute_force_calculate_messages(brute_force); - - if(INFRARED_ERROR_PRESENT(error)) { - infrared_show_error_message(infrared, "Failed to load database"); - scene_manager_previous_scene(infrared->scene_manager); - return; - } - - // add btns - for(size_t i = 0; i < infrared_brute_force_get_button_count(brute_force); ++i) { - const char* button_name = infrared_brute_force_get_button_name(brute_force, i); - button_menu_add_item( - button_menu, - button_name, - i, - infrared_scene_universal_more_devices_item_callback, - ButtonMenuItemTypeCommon, - infrared); - } - - ///header name handler + // File name in header + // Using c-string functions on FuriString is a bad idea but file_path is not modified + // for the lifetime of this scene so it should be fine const char* file_name = strrchr(furi_string_get_cstr(infrared->file_path), '/'); if(file_name) { file_name++; // skip dir seperator @@ -82,12 +71,12 @@ void infrared_scene_universal_more_devices_on_enter(void* context) { } button_menu_set_header(button_menu, file_name); + // Can't use infrared_scene_universal_common_on_enter() since we use ButtonMenu not ButtonPanel view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical); view_stack_add_view(infrared->view_stack, button_menu_get_view(infrared->button_menu)); // Load universal remote data in background infrared_blocking_task_start(infrared, infrared_scene_universal_more_devices_task_callback); - view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack); } bool infrared_scene_universal_more_devices_on_event(void* context, SceneManagerEvent event) { @@ -95,7 +84,7 @@ bool infrared_scene_universal_more_devices_on_event(void* context, SceneManagerE } void infrared_scene_universal_more_devices_on_exit(void* context) { - // Common function won't work since we use ButtonMenu not ButtonPanel + // Can't use infrared_scene_universal_common_on_exit() since we use ButtonMenu not ButtonPanel InfraredApp* infrared = context; ButtonMenu* button_menu = infrared->button_menu; view_stack_remove_view(infrared->view_stack, button_menu_get_view(button_menu)); From 31a7c07119bcac09590819c7c92c9979c68dd767 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 11 Oct 2024 19:49:42 +0100 Subject: [PATCH 17/24] Add bool for auto_detect_buttons --- applications/main/infrared/infrared_brute_force.c | 14 +++++++++----- applications/main/infrared/infrared_brute_force.h | 5 ++++- applications/main/infrared/infrared_cli.c | 2 +- .../common/infrared_scene_universal_common.c | 3 ++- .../scenes/infrared_scene_universal_more_devices.c | 3 ++- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/applications/main/infrared/infrared_brute_force.c b/applications/main/infrared/infrared_brute_force.c index 572b4dccb3..b1ef5d21ef 100644 --- a/applications/main/infrared/infrared_brute_force.c +++ b/applications/main/infrared/infrared_brute_force.c @@ -50,7 +50,9 @@ void infrared_brute_force_set_db_filename(InfraredBruteForce* brute_force, const brute_force->db_filename = db_filename; } -InfraredErrorCode infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force) { +InfraredErrorCode infrared_brute_force_calculate_messages( + InfraredBruteForce* brute_force, + bool auto_detect_buttons) { furi_assert(!brute_force->is_started); furi_assert(brute_force->db_filename); InfraredErrorCode error = InfraredErrorCodeNone; @@ -63,7 +65,7 @@ InfraredErrorCode infrared_brute_force_calculate_messages(InfraredBruteForce* br if(!flipper_format_buffered_file_open_existing(ff, brute_force->db_filename)) { error = InfraredErrorCodeFileOperationFailed; } else { - uint32_t button_index = 0; + uint32_t auto_detect_button_index = 0; while(infrared_signal_read_name(ff, signal_name) == InfraredErrorCodeNone) { error = infrared_signal_read_body(signal, ff); if(INFRARED_ERROR_PRESENT(error) || !infrared_signal_is_valid(signal)) { @@ -72,11 +74,13 @@ InfraredErrorCode infrared_brute_force_calculate_messages(InfraredBruteForce* br InfraredBruteForceRecord* record = InfraredBruteForceRecordDict_get(brute_force->records, signal_name); + if(!record && auto_detect_buttons) { + infrared_brute_force_add_record( + brute_force, auto_detect_button_index++, furi_string_get_cstr(signal_name)); + record = InfraredBruteForceRecordDict_get(brute_force->records, signal_name); + } if(record) { //-V547 ++(record->count); - } else { - infrared_brute_force_add_record( - brute_force, button_index++, furi_string_get_cstr(signal_name)); } } } diff --git a/applications/main/infrared/infrared_brute_force.h b/applications/main/infrared/infrared_brute_force.h index 1accfc4e18..c1985ee3ff 100644 --- a/applications/main/infrared/infrared_brute_force.h +++ b/applications/main/infrared/infrared_brute_force.h @@ -47,9 +47,12 @@ void infrared_brute_force_set_db_filename(InfraredBruteForce* brute_force, const * a infrared_brute_force_set_db_filename() call. * * @param[in,out] brute_force pointer to the instance to be updated. + * @param[in] auto_detect_buttons bool whether to automatically register newly discovered buttons. * @returns InfraredErrorCodeNone on success, otherwise error code. */ -InfraredErrorCode infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force); +InfraredErrorCode infrared_brute_force_calculate_messages( + InfraredBruteForce* brute_force, + bool auto_detect_buttons); /** * @brief Start transmitting signals from a category stored in an InfraredBruteForce's instance dictionary. diff --git a/applications/main/infrared/infrared_cli.c b/applications/main/infrared/infrared_cli.c index cdd5b9a118..d4668d699c 100644 --- a/applications/main/infrared/infrared_cli.c +++ b/applications/main/infrared/infrared_cli.c @@ -470,7 +470,7 @@ static void printf("Missing signal name.\r\n"); break; } - if(infrared_brute_force_calculate_messages(brute_force) != InfraredErrorCodeNone) { + if(infrared_brute_force_calculate_messages(brute_force, false) != InfraredErrorCodeNone) { printf("Invalid remote name.\r\n"); break; } diff --git a/applications/main/infrared/scenes/common/infrared_scene_universal_common.c b/applications/main/infrared/scenes/common/infrared_scene_universal_common.c index a52f141c47..dbccabb9b9 100644 --- a/applications/main/infrared/scenes/common/infrared_scene_universal_common.c +++ b/applications/main/infrared/scenes/common/infrared_scene_universal_common.c @@ -34,7 +34,8 @@ static void infrared_scene_universal_common_hide_popup(InfraredApp* infrared) { static int32_t infrared_scene_universal_common_task_callback(void* context) { InfraredApp* infrared = context; - const InfraredErrorCode error = infrared_brute_force_calculate_messages(infrared->brute_force); + const InfraredErrorCode error = + infrared_brute_force_calculate_messages(infrared->brute_force, false); view_dispatcher_send_custom_event( infrared->view_dispatcher, infrared_custom_event_pack(InfraredCustomEventTypeTaskFinished, 0)); diff --git a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c index 98193ad3fb..be80a1d3c2 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c @@ -20,7 +20,8 @@ static int32_t infrared_scene_universal_more_devices_task_callback(void* context InfraredApp* infrared = context; ButtonMenu* button_menu = infrared->button_menu; InfraredBruteForce* brute_force = infrared->brute_force; - const InfraredErrorCode error = infrared_brute_force_calculate_messages(infrared->brute_force); + const InfraredErrorCode error = + infrared_brute_force_calculate_messages(infrared->brute_force, true); if(!INFRARED_ERROR_PRESENT(error)) { // add btns From 4238b5d3695070dd11269ca469dfe54f4a78858c Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 11 Oct 2024 20:09:16 +0100 Subject: [PATCH 18/24] Show error when tryingto load remote file as universal library --- .../main/infrared/infrared_brute_force.c | 49 ++++++++++++++++--- .../infrared_scene_universal_more_devices.c | 29 +++++++++++ 2 files changed, 71 insertions(+), 7 deletions(-) diff --git a/applications/main/infrared/infrared_brute_force.c b/applications/main/infrared/infrared_brute_force.c index b1ef5d21ef..e4525f868d 100644 --- a/applications/main/infrared/infrared_brute_force.c +++ b/applications/main/infrared/infrared_brute_force.c @@ -6,6 +6,12 @@ #include "infrared_signal.h" +#define TAG "InfraredBruteforce" + +#define INFRARED_FILE_HEADER "IR signals file" +#define INFRARED_LIBRARY_HEADER "IR library file" +#define INFRARED_LIBRARY_VERSION (1) + typedef struct { uint32_t index; uint32_t count; @@ -62,15 +68,43 @@ InfraredErrorCode infrared_brute_force_calculate_messages( FuriString* signal_name = furi_string_alloc(); InfraredSignal* signal = infrared_signal_alloc(); - if(!flipper_format_buffered_file_open_existing(ff, brute_force->db_filename)) { - error = InfraredErrorCodeFileOperationFailed; - } else { + do { + if(!flipper_format_buffered_file_open_existing(ff, brute_force->db_filename)) { + error = InfraredErrorCodeFileOperationFailed; + break; + } + + uint32_t version; + // Temporarily use signal_name to get header info + if(!flipper_format_read_header(ff, signal_name, &version)) { + error = InfraredErrorCodeFileOperationFailed; + break; + } + + if(furi_string_equal(signal_name, INFRARED_FILE_HEADER)) { + FURI_LOG_E(TAG, "Remote file can't be loaded in this context"); + error = InfraredErrorCodeWrongFileType; + break; + } + + if(!furi_string_equal(signal_name, INFRARED_LIBRARY_HEADER)) { + error = InfraredErrorCodeWrongFileType; + FURI_LOG_E(TAG, "Filetype unknown"); + break; + } + + if(version != INFRARED_LIBRARY_VERSION) { + error = InfraredErrorCodeWrongFileVersion; + FURI_LOG_E(TAG, "Wrong file version"); + break; + } + + bool signals_valid = false; uint32_t auto_detect_button_index = 0; while(infrared_signal_read_name(ff, signal_name) == InfraredErrorCodeNone) { error = infrared_signal_read_body(signal, ff); - if(INFRARED_ERROR_PRESENT(error) || !infrared_signal_is_valid(signal)) { - break; - } + signals_valid = (!INFRARED_ERROR_PRESENT(error)) && infrared_signal_is_valid(signal); + if(!signals_valid) break; InfraredBruteForceRecord* record = InfraredBruteForceRecordDict_get(brute_force->records, signal_name); @@ -83,7 +117,8 @@ InfraredErrorCode infrared_brute_force_calculate_messages( ++(record->count); } } - } + if(!signals_valid) break; + } while(false); infrared_signal_free(signal); furi_string_free(signal_name); diff --git a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c index be80a1d3c2..8072db7b04 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c @@ -81,6 +81,35 @@ void infrared_scene_universal_more_devices_on_enter(void* context) { } bool infrared_scene_universal_more_devices_on_event(void* context, SceneManagerEvent event) { + InfraredApp* infrared = context; + SceneManager* scene_manager = infrared->scene_manager; + InfraredBruteForce* brute_force = infrared->brute_force; + + // Only override InfraredCustomEventTypeTaskFinished on error condition + if(!infrared_brute_force_is_started(brute_force) && + event.type == SceneManagerEventTypeCustom) { + uint16_t event_type; + int16_t event_value; + infrared_custom_event_unpack(event.event, &event_type, &event_value); + if(event_type == InfraredCustomEventTypeTaskFinished) { + const InfraredErrorCode task_error = infrared_blocking_task_finalize(infrared); + + if(INFRARED_ERROR_PRESENT(task_error)) { + bool wrong_file_type = + INFRARED_ERROR_CHECK(task_error, InfraredErrorCodeWrongFileType); + const char* format = wrong_file_type ? + "Remote file\n\"%s\" can't be openned as a library" : + "Failed to load\n\"%s\""; + + infrared_show_error_message( + infrared, format, furi_string_get_cstr(infrared->file_path)); + scene_manager_previous_scene(scene_manager); + return true; + } + } + } + + // Use common function for all other functionality return infrared_scene_universal_common_on_event(context, event); } From 48010234838e9a7fdeb610f3b5a78c03f20895ca Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 11 Oct 2024 20:11:55 +0100 Subject: [PATCH 19/24] Remove unnecessary includes --- .../infrared/scenes/infrared_scene_universal_more_devices.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c index 8072db7b04..8057b9ba69 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c @@ -2,10 +2,6 @@ #include "common/infrared_scene_universal_common.h" -#include -#include -#include - static void infrared_scene_universal_more_devices_item_callback( void* context, int32_t index, From 6c4877db971d408d9b4a4a0910ef784b8dd155a0 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 11 Oct 2024 20:31:33 +0100 Subject: [PATCH 20/24] Fix inputs --- .../scenes/infrared_scene_universal_more_devices.c | 9 +++++---- .../main/infrared/views/infrared_progress_view.c | 3 +-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c index 8057b9ba69..d1c8a339d4 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c @@ -6,10 +6,11 @@ static void infrared_scene_universal_more_devices_item_callback( void* context, int32_t index, InputType type) { - UNUSED(type); - InfraredApp* infrared = context; - uint32_t event = infrared_custom_event_pack(InfraredCustomEventTypeButtonSelected, index); - view_dispatcher_send_custom_event(infrared->view_dispatcher, event); + if(type == InputTypeRelease) { + InfraredApp* infrared = context; + uint32_t event = infrared_custom_event_pack(InfraredCustomEventTypeButtonSelected, index); + view_dispatcher_send_custom_event(infrared->view_dispatcher, event); + } } static int32_t infrared_scene_universal_more_devices_task_callback(void* context) { diff --git a/applications/main/infrared/views/infrared_progress_view.c b/applications/main/infrared/views/infrared_progress_view.c index b8bf518c83..1f491e4abf 100644 --- a/applications/main/infrared/views/infrared_progress_view.c +++ b/applications/main/infrared/views/infrared_progress_view.c @@ -81,10 +81,9 @@ bool infrared_progress_view_input_callback(InputEvent* event, void* context) { if(instance->back_callback) { instance->back_callback(instance->context); } - return true; } - return false; + return true; } InfraredProgressView* infrared_progress_view_alloc(void) { From 7c62e0788b65a138327e6aec2dcb1063e2b3829a Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 11 Oct 2024 20:36:32 +0100 Subject: [PATCH 21/24] more_devices -> from_file --- .../infrared/scenes/infrared_scene_config.h | 2 +- .../infrared/scenes/infrared_scene_universal.c | 10 +++++----- ....c => infrared_scene_universal_from_file.c} | 18 ++++++++---------- 3 files changed, 14 insertions(+), 16 deletions(-) rename applications/main/infrared/scenes/{infrared_scene_universal_more_devices.c => infrared_scene_universal_from_file.c} (89%) diff --git a/applications/main/infrared/scenes/infrared_scene_config.h b/applications/main/infrared/scenes/infrared_scene_config.h index 81928f95c5..074fc8ca2d 100644 --- a/applications/main/infrared/scenes/infrared_scene_config.h +++ b/applications/main/infrared/scenes/infrared_scene_config.h @@ -24,7 +24,7 @@ ADD_SCENE(infrared, universal_fan, UniversalFan) ADD_SCENE(infrared, universal_bluray, UniversalBluray) ADD_SCENE(infrared, universal_monitor, UniversalMonitor) ADD_SCENE(infrared, universal_digital_sign, UniversalDigitalSign) -ADD_SCENE(infrared, universal_more_devices, UniversalMoreDevices) +ADD_SCENE(infrared, universal_from_file, UniversalFromFile) ADD_SCENE(infrared, gpio_settings, GpioSettings) ADD_SCENE(infrared, debug, Debug) ADD_SCENE(infrared, error_databases, ErrorDatabases) diff --git a/applications/main/infrared/scenes/infrared_scene_universal.c b/applications/main/infrared/scenes/infrared_scene_universal.c index 3f8078bb77..1cfc6a4658 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal.c +++ b/applications/main/infrared/scenes/infrared_scene_universal.c @@ -10,7 +10,7 @@ typedef enum { SubmenuIndexUniversalBluray, SubmenuIndexUniversalMonitor, SubmenuIndexUniversalDigitalSign, - SubmenuIndexUniversalMoreDevices, + SubmenuIndexUniversalFromFile, } SubmenuIndex; static void infrared_scene_universal_submenu_callback(void* context, uint32_t index) { @@ -87,8 +87,8 @@ void infrared_scene_universal_on_enter(void* context) { submenu_add_item( submenu, - "Load Custom DB", - SubmenuIndexUniversalMoreDevices, + "Load from Library File", + SubmenuIndexUniversalFromFile, infrared_scene_universal_submenu_callback, context); @@ -131,9 +131,9 @@ bool infrared_scene_universal_on_event(void* context, SceneManagerEvent event) { } else if(event.event == SubmenuIndexUniversalDigitalSign) { scene_manager_next_scene(scene_manager, InfraredSceneUniversalDigitalSign); consumed = true; - } else if(event.event == SubmenuIndexUniversalMoreDevices) { + } else if(event.event == SubmenuIndexUniversalFromFile) { furi_string_set(infrared->file_path, INFRARED_APP_FOLDER); - scene_manager_next_scene(scene_manager, InfraredSceneUniversalMoreDevices); + scene_manager_next_scene(scene_manager, InfraredSceneUniversalFromFile); consumed = true; } scene_manager_set_scene_state(scene_manager, InfraredSceneUniversal, event.event); diff --git a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c b/applications/main/infrared/scenes/infrared_scene_universal_from_file.c similarity index 89% rename from applications/main/infrared/scenes/infrared_scene_universal_more_devices.c rename to applications/main/infrared/scenes/infrared_scene_universal_from_file.c index d1c8a339d4..d6a7190414 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_more_devices.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_from_file.c @@ -2,10 +2,8 @@ #include "common/infrared_scene_universal_common.h" -static void infrared_scene_universal_more_devices_item_callback( - void* context, - int32_t index, - InputType type) { +static void + infrared_scene_universal_from_file_item_callback(void* context, int32_t index, InputType type) { if(type == InputTypeRelease) { InfraredApp* infrared = context; uint32_t event = infrared_custom_event_pack(InfraredCustomEventTypeButtonSelected, index); @@ -13,7 +11,7 @@ static void infrared_scene_universal_more_devices_item_callback( } } -static int32_t infrared_scene_universal_more_devices_task_callback(void* context) { +static int32_t infrared_scene_universal_from_file_task_callback(void* context) { InfraredApp* infrared = context; ButtonMenu* button_menu = infrared->button_menu; InfraredBruteForce* brute_force = infrared->brute_force; @@ -28,7 +26,7 @@ static int32_t infrared_scene_universal_more_devices_task_callback(void* context button_menu, button_name, i, - infrared_scene_universal_more_devices_item_callback, + infrared_scene_universal_from_file_item_callback, ButtonMenuItemTypeCommon, infrared); } @@ -41,7 +39,7 @@ static int32_t infrared_scene_universal_more_devices_task_callback(void* context return error; } -void infrared_scene_universal_more_devices_on_enter(void* context) { +void infrared_scene_universal_from_file_on_enter(void* context) { InfraredApp* infrared = context; ButtonMenu* button_menu = infrared->button_menu; InfraredBruteForce* brute_force = infrared->brute_force; @@ -74,10 +72,10 @@ void infrared_scene_universal_more_devices_on_enter(void* context) { view_stack_add_view(infrared->view_stack, button_menu_get_view(infrared->button_menu)); // Load universal remote data in background - infrared_blocking_task_start(infrared, infrared_scene_universal_more_devices_task_callback); + infrared_blocking_task_start(infrared, infrared_scene_universal_from_file_task_callback); } -bool infrared_scene_universal_more_devices_on_event(void* context, SceneManagerEvent event) { +bool infrared_scene_universal_from_file_on_event(void* context, SceneManagerEvent event) { InfraredApp* infrared = context; SceneManager* scene_manager = infrared->scene_manager; InfraredBruteForce* brute_force = infrared->brute_force; @@ -110,7 +108,7 @@ bool infrared_scene_universal_more_devices_on_event(void* context, SceneManagerE return infrared_scene_universal_common_on_event(context, event); } -void infrared_scene_universal_more_devices_on_exit(void* context) { +void infrared_scene_universal_from_file_on_exit(void* context) { // Can't use infrared_scene_universal_common_on_exit() since we use ButtonMenu not ButtonPanel InfraredApp* infrared = context; ButtonMenu* button_menu = infrared->button_menu; From 2f89422edbfa3b3211ef9b5fecfc2c1f54cb14bf Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 11 Oct 2024 20:38:18 +0100 Subject: [PATCH 22/24] Consistency --- applications/main/infrared/scenes/infrared_scene_universal.c | 1 - .../main/infrared/scenes/infrared_scene_universal_from_file.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/main/infrared/scenes/infrared_scene_universal.c b/applications/main/infrared/scenes/infrared_scene_universal.c index 1cfc6a4658..3616fe06ad 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal.c +++ b/applications/main/infrared/scenes/infrared_scene_universal.c @@ -132,7 +132,6 @@ bool infrared_scene_universal_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(scene_manager, InfraredSceneUniversalDigitalSign); consumed = true; } else if(event.event == SubmenuIndexUniversalFromFile) { - furi_string_set(infrared->file_path, INFRARED_APP_FOLDER); scene_manager_next_scene(scene_manager, InfraredSceneUniversalFromFile); consumed = true; } diff --git a/applications/main/infrared/scenes/infrared_scene_universal_from_file.c b/applications/main/infrared/scenes/infrared_scene_universal_from_file.c index d6a7190414..ec1cdb4d6f 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_from_file.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_from_file.c @@ -46,6 +46,7 @@ void infrared_scene_universal_from_file_on_enter(void* context) { DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options(&browser_options, INFRARED_APP_EXTENSION, &I_ir_10px); + furi_string_set(infrared->file_path, INFRARED_APP_FOLDER); browser_options.base_path = INFRARED_APP_FOLDER; browser_options.skip_assets = false; if(!dialog_file_browser_show( From 0b2247c5361a70cbe5b7573b36d862cdd0cb2da4 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 11 Oct 2024 20:45:04 +0100 Subject: [PATCH 23/24] Remember last selected library file --- applications/main/infrared/scenes/infrared_scene_start.c | 4 ++++ .../main/infrared/scenes/infrared_scene_universal_from_file.c | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/applications/main/infrared/scenes/infrared_scene_start.c b/applications/main/infrared/scenes/infrared_scene_start.c index 3a9512a619..11944df19e 100644 --- a/applications/main/infrared/scenes/infrared_scene_start.c +++ b/applications/main/infrared/scenes/infrared_scene_start.c @@ -85,6 +85,10 @@ bool infrared_scene_start_on_event(void* context, SceneManagerEvent event) { const uint32_t submenu_index = event.event; scene_manager_set_scene_state(scene_manager, InfraredSceneStart, submenu_index); if(submenu_index == SubmenuIndexUniversalRemotes) { + // Set file_path only once here so repeated usages of + // "Load from Library File" have file browser focused on + // last selected file, feels more intuitive + furi_string_set(infrared->file_path, INFRARED_APP_FOLDER); scene_manager_next_scene(scene_manager, InfraredSceneUniversal); } else if( submenu_index == SubmenuIndexLearnNewRemote || diff --git a/applications/main/infrared/scenes/infrared_scene_universal_from_file.c b/applications/main/infrared/scenes/infrared_scene_universal_from_file.c index ec1cdb4d6f..d6a7190414 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_from_file.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_from_file.c @@ -46,7 +46,6 @@ void infrared_scene_universal_from_file_on_enter(void* context) { DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options(&browser_options, INFRARED_APP_EXTENSION, &I_ir_10px); - furi_string_set(infrared->file_path, INFRARED_APP_FOLDER); browser_options.base_path = INFRARED_APP_FOLDER; browser_options.skip_assets = false; if(!dialog_file_browser_show( From 47e9fcf154962ab09317e3ac87ed3679c003e112 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 11 Oct 2024 20:50:21 +0100 Subject: [PATCH 24/24] Update changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a85a803dea..27c141276a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,9 @@ - Static encrypted backdoor support: collects static encrypted nonces to be cracked by MFKey using NXP/Fudan backdoor, allowing key recovery of all non-hardened MIFARE Classic tags on-device - Add SmartRider Parser (#203 by @jaylikesbunda) - Add API to enforce ISO15693 mode (#225 by @aaronjamt) -- Infrared: Bluray/DVD Universal Remote (#250 by @jaylikesbunda) +- Infrared: + - Bluray/DVD Universal Remote (#250 by @jaylikesbunda) + - Option to "Load from Library File" for Universal Remotes (#255 by @zxkmm) - Updater: New Yappy themed icon while updating (#253 by @the1anonlypr3 & @Kuronons & @nescap) - BadKB: - OFW: Add linux/gnome badusb demo files (by @thomasnemer)