diff --git a/applications/ibutton/ibutton.c b/applications/ibutton/ibutton.c index b30a4c61..7ee1110e 100644 --- a/applications/ibutton/ibutton.c +++ b/applications/ibutton/ibutton.c @@ -87,6 +87,8 @@ static void ibutton_rpc_command_callback(RpcAppSystemEvent event, void* context) if(event == RpcAppEventSessionClose) { view_dispatcher_send_custom_event( ibutton->view_dispatcher, iButtonCustomEventRpcSessionClose); + rpc_system_app_set_callback(ibutton->rpc_ctx, NULL, NULL); + ibutton->rpc_ctx = NULL; } else if(event == RpcAppEventAppExit) { view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventRpcExit); } else if(event == RpcAppEventLoadFile) { diff --git a/applications/ibutton/scenes/ibutton_scene_rpc.c b/applications/ibutton/scenes/ibutton_scene_rpc.c index a3f5eeee..0755c8ff 100644 --- a/applications/ibutton/scenes/ibutton_scene_rpc.c +++ b/applications/ibutton/scenes/ibutton_scene_rpc.c @@ -29,7 +29,7 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) { if(event.event == iButtonCustomEventRpcLoad) { const char* arg = rpc_system_app_get_data(ibutton->rpc_ctx); bool result = false; - if(arg) { + if(arg && (string_empty_p(ibutton->file_path))) { string_set_str(ibutton->file_path, arg); if(ibutton_load_key_data(ibutton, ibutton->file_path, false)) { ibutton_worker_emulate_start(ibutton->key_worker, ibutton->key); @@ -51,17 +51,17 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) { string_clear(key_name); result = true; + } else { + string_reset(ibutton->file_path); } } rpc_system_app_confirm(ibutton->rpc_ctx, RpcAppEventLoadFile, result); } else if(event.event == iButtonCustomEventRpcExit) { rpc_system_app_confirm(ibutton->rpc_ctx, RpcAppEventAppExit, true); - ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop); + scene_manager_stop(ibutton->scene_manager); view_dispatcher_stop(ibutton->view_dispatcher); } else if(event.event == iButtonCustomEventRpcSessionClose) { - rpc_system_app_set_callback(ibutton->rpc_ctx, NULL, NULL); - ibutton->rpc_ctx = NULL; - ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop); + scene_manager_stop(ibutton->scene_manager); view_dispatcher_stop(ibutton->view_dispatcher); } } diff --git a/applications/infrared/infrared.c b/applications/infrared/infrared.c index aef14f9b..3b4da647 100644 --- a/applications/infrared/infrared.c +++ b/applications/infrared/infrared.c @@ -46,6 +46,8 @@ static void infrared_rpc_command_callback(RpcAppSystemEvent event, void* context if(event == RpcAppEventSessionClose) { view_dispatcher_send_custom_event( infrared->view_dispatcher, InfraredCustomEventTypeRpcSessionClose); + rpc_system_app_set_callback(infrared->rpc_ctx, NULL, NULL); + infrared->rpc_ctx = NULL; } else if(event == RpcAppEventAppExit) { view_dispatcher_send_custom_event( infrared->view_dispatcher, InfraredCustomEventTypeRpcExit); diff --git a/applications/infrared/scenes/infrared_scene_rpc.c b/applications/infrared/scenes/infrared_scene_rpc.c index bc9c8652..cb5535fe 100644 --- a/applications/infrared/scenes/infrared_scene_rpc.c +++ b/applications/infrared/scenes/infrared_scene_rpc.c @@ -1,20 +1,28 @@ #include "../infrared_i.h" #include "gui/canvas.h" +typedef enum { + InfraredRpcStateIdle, + InfraredRpcStateLoaded, + InfraredRpcStateSending, +} InfraredRpcState; + void infrared_scene_rpc_on_enter(void* context) { Infrared* infrared = context; Popup* popup = infrared->popup; - popup_set_header(popup, "Infrared", 82, 28, AlignCenter, AlignBottom); - popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop); + popup_set_header(popup, "Infrared", 89, 42, AlignCenter, AlignBottom); + popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop); - popup_set_icon(popup, 2, 14, &I_Warning_30x23); // TODO: icon + popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61); popup_set_context(popup, context); popup_set_callback(popup, infrared_popup_closed_callback); view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup); + scene_manager_set_scene_state(infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateIdle); + notification_message(infrared->notifications, &sequence_display_backlight_on); } @@ -24,6 +32,8 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { consumed = true; + InfraredRpcState state = + scene_manager_get_scene_state(infrared->scene_manager, InfraredSceneRpc); if(event.event == InfraredCustomEventTypeBackPressed) { view_dispatcher_stop(infrared->view_dispatcher); } else if(event.event == InfraredCustomEventTypePopupClosed) { @@ -31,39 +41,51 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) { } else if(event.event == InfraredCustomEventTypeRpcLoad) { bool result = false; const char* arg = rpc_system_app_get_data(infrared->rpc_ctx); - if(arg) { + if(arg && (state == InfraredRpcStateIdle)) { string_set_str(infrared->file_path, arg); result = infrared_remote_load(infrared->remote, infrared->file_path); infrared_worker_tx_set_get_signal_callback( infrared->worker, infrared_worker_tx_get_signal_steady_callback, infrared); + if(result) { + scene_manager_set_scene_state( + infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateLoaded); + } } const char* remote_name = infrared_remote_get_name(infrared->remote); infrared_text_store_set(infrared, 0, "loaded\n%s", remote_name); popup_set_text( - infrared->popup, infrared->text_store[0], 82, 32, AlignCenter, AlignTop); + infrared->popup, infrared->text_store[0], 89, 44, AlignCenter, AlignTop); rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventLoadFile, result); } else if(event.event == InfraredCustomEventTypeRpcButtonPress) { bool result = false; const char* arg = rpc_system_app_get_data(infrared->rpc_ctx); - if(arg) { + if(arg && (state == InfraredRpcStateLoaded)) { size_t button_index = 0; if(infrared_remote_find_button_by_name(infrared->remote, arg, &button_index)) { infrared_tx_start_button_index(infrared, button_index); result = true; + scene_manager_set_scene_state( + infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateSending); } } rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventButtonRelease, result); } else if(event.event == InfraredCustomEventTypeRpcButtonRelease) { - infrared_tx_stop(infrared); - rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventButtonRelease, true); + bool result = false; + if(state == InfraredRpcStateSending) { + infrared_tx_stop(infrared); + result = true; + scene_manager_set_scene_state( + infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateLoaded); + } + rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventButtonRelease, result); } else if(event.event == InfraredCustomEventTypeRpcExit) { + scene_manager_stop(infrared->scene_manager); view_dispatcher_stop(infrared->view_dispatcher); rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventAppExit, true); } else if(event.event == InfraredCustomEventTypeRpcSessionClose) { - rpc_system_app_set_callback(infrared->rpc_ctx, NULL, NULL); - infrared->rpc_ctx = NULL; + scene_manager_stop(infrared->scene_manager); view_dispatcher_stop(infrared->view_dispatcher); } } @@ -72,6 +94,9 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) { void infrared_scene_rpc_on_exit(void* context) { Infrared* infrared = context; - infrared_tx_stop(infrared); + if(scene_manager_get_scene_state(infrared->scene_manager, InfraredSceneRpc) == + InfraredRpcStateSending) { + infrared_tx_stop(infrared); + } popup_reset(infrared->popup); } diff --git a/applications/lfrfid/lfrfid_app.cpp b/applications/lfrfid/lfrfid_app.cpp index 5b762ae1..f1a575de 100644 --- a/applications/lfrfid/lfrfid_app.cpp +++ b/applications/lfrfid/lfrfid_app.cpp @@ -56,6 +56,9 @@ static void rpc_command_callback(RpcAppSystemEvent rpc_event, void* context) { LfRfidApp::Event event; event.type = LfRfidApp::EventType::RpcSessionClose; app->view_controller.send_event(&event); + // Detach RPC + rpc_system_app_set_callback(app->rpc_ctx, NULL, NULL); + app->rpc_ctx = NULL; } else if(rpc_event == RpcAppEventAppExit) { LfRfidApp::Event event; event.type = LfRfidApp::EventType::Exit; @@ -80,16 +83,19 @@ void LfRfidApp::run(void* _args) { rpc_ctx = (RpcAppSystem*)rpc_ctx_ptr; rpc_system_app_set_callback(rpc_ctx, rpc_command_callback, this); rpc_system_app_send_started(rpc_ctx); + view_controller.attach_to_gui(ViewDispatcherTypeDesktop); scene_controller.add_scene(SceneType::Rpc, new LfRfidAppSceneRpc()); scene_controller.process(100, SceneType::Rpc); } else { string_set_str(file_path, args); load_key_data(file_path, &worker.key, true); + view_controller.attach_to_gui(ViewDispatcherTypeFullscreen); scene_controller.add_scene(SceneType::Emulate, new LfRfidAppSceneEmulate()); scene_controller.process(100, SceneType::Emulate); } } else { + view_controller.attach_to_gui(ViewDispatcherTypeFullscreen); scene_controller.add_scene(SceneType::Start, new LfRfidAppSceneStart()); scene_controller.add_scene(SceneType::Read, new LfRfidAppSceneRead()); scene_controller.add_scene(SceneType::RetryConfirm, new LfRfidAppSceneRetryConfirm()); diff --git a/applications/lfrfid/lfrfid_app.h b/applications/lfrfid/lfrfid_app.h index b0d4c589..db022c9a 100644 --- a/applications/lfrfid/lfrfid_app.h +++ b/applications/lfrfid/lfrfid_app.h @@ -101,5 +101,4 @@ public: bool save_key_data(string_t path, RfidKey* key); void make_app_folder(); - //bool rpc_command_callback(RpcAppSystemEvent event, const char* arg, void* context); }; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp b/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp index 43b23628..54a57c9a 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp @@ -6,9 +6,9 @@ void LfRfidAppSceneRpc::on_enter(LfRfidApp* app, bool /* need_restore */) { auto popup = app->view_controller.get(); - popup->set_header("LF RFID", 89, 30, AlignCenter, AlignTop); - popup->set_text("RPC mode", 89, 43, AlignCenter, AlignTop); - popup->set_icon(0, 3, &I_RFIDDolphinSend_97x61); + popup->set_header("LF RFID", 89, 42, AlignCenter, AlignBottom); + popup->set_text("RPC mode", 89, 44, AlignCenter, AlignTop); + popup->set_icon(0, 12, &I_RFIDDolphinSend_97x61); app->view_controller.switch_to(); @@ -27,33 +27,25 @@ bool LfRfidAppSceneRpc::on_event(LfRfidApp* app, LfRfidApp::Event* event) { app->view_controller.send_event(&view_event); rpc_system_app_confirm(app->rpc_ctx, RpcAppEventAppExit, true); } else if(event->type == LfRfidApp::EventType::RpcSessionClose) { - // Detach RPC - rpc_system_app_set_callback(app->rpc_ctx, NULL, NULL); - app->rpc_ctx = NULL; - consumed = true; LfRfidApp::Event view_event; view_event.type = LfRfidApp::EventType::Back; app->view_controller.send_event(&view_event); - } else if(event->type == LfRfidApp::EventType::EmulateStart) { - auto popup = app->view_controller.get(); - consumed = true; - emulating = true; - - app->text_store.set("emulating\n%s", app->worker.key.get_name()); - popup->set_text(app->text_store.text, 89, 43, AlignCenter, AlignTop); - - notification_message(app->notification, &sequence_blink_start_magenta); } else if(event->type == LfRfidApp::EventType::RpcLoadFile) { const char* arg = rpc_system_app_get_data(app->rpc_ctx); + consumed = true; bool result = false; - if(arg) { + if(arg && !emulating) { string_set_str(app->file_path, arg); if(app->load_key_data(app->file_path, &(app->worker.key), false)) { - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::EmulateStart; - app->view_controller.send_event(&event); app->worker.start_emulate(); + emulating = true; + + auto popup = app->view_controller.get(); + app->text_store.set("emulating\n%s", app->worker.key.get_name()); + popup->set_text(app->text_store.text, 89, 44, AlignCenter, AlignTop); + + notification_message(app->notification, &sequence_blink_start_magenta); result = true; } } diff --git a/applications/lfrfid_debug/lfrfid_debug_app.cpp b/applications/lfrfid_debug/lfrfid_debug_app.cpp index 9cd9dcad..ef970e36 100644 --- a/applications/lfrfid_debug/lfrfid_debug_app.cpp +++ b/applications/lfrfid_debug/lfrfid_debug_app.cpp @@ -10,6 +10,7 @@ LfRfidDebugApp::~LfRfidDebugApp() { } void LfRfidDebugApp::run() { + view_controller.attach_to_gui(ViewDispatcherTypeFullscreen); scene_controller.add_scene(SceneType::Start, new LfRfidDebugAppSceneStart()); scene_controller.add_scene(SceneType::TuneScene, new LfRfidDebugAppSceneTune()); scene_controller.process(100); diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c index 9d32e871..6b8843db 100644 --- a/applications/nfc/nfc.c +++ b/applications/nfc/nfc.c @@ -21,6 +21,8 @@ static void nfc_rpc_command_callback(RpcAppSystemEvent event, void* context) { if(event == RpcAppEventSessionClose) { view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcSessionClose); + rpc_system_app_set_callback(nfc->rpc_ctx, NULL, NULL); + nfc->rpc_ctx = NULL; } else if(event == RpcAppEventAppExit) { view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit); } else if(event == RpcAppEventLoadFile) { diff --git a/applications/nfc/scenes/nfc_scene_rpc.c b/applications/nfc/scenes/nfc_scene_rpc.c index 94beccc6..7a9eb450 100644 --- a/applications/nfc/scenes/nfc_scene_rpc.c +++ b/applications/nfc/scenes/nfc_scene_rpc.c @@ -4,10 +4,10 @@ void nfc_scene_rpc_on_enter(void* context) { Nfc* nfc = context; Popup* popup = nfc->popup; - popup_set_header(popup, "NFC", 82, 28, AlignCenter, AlignBottom); - popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop); + popup_set_header(popup, "NFC", 89, 42, AlignCenter, AlignBottom); + popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop); - popup_set_icon(popup, 2, 14, &I_Warning_30x23); // TODO: icon + popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); @@ -31,13 +31,11 @@ bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) { consumed = true; if(event.event == NfcCustomEventViewExit) { rpc_system_app_confirm(nfc->rpc_ctx, RpcAppEventAppExit, true); + scene_manager_stop(nfc->scene_manager); view_dispatcher_stop(nfc->view_dispatcher); - nfc_blink_stop(nfc); } else if(event.event == NfcCustomEventRpcSessionClose) { - rpc_system_app_set_callback(nfc->rpc_ctx, NULL, NULL); - nfc->rpc_ctx = NULL; + scene_manager_stop(nfc->scene_manager); view_dispatcher_stop(nfc->view_dispatcher); - nfc_blink_stop(nfc); } else if(event.event == NfcCustomEventRpcLoad) { bool result = false; const char* arg = rpc_system_app_get_data(nfc->rpc_ctx); @@ -66,7 +64,7 @@ bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) { nfc_blink_start(nfc); nfc_text_store_set(nfc, "emulating\n%s", nfc->dev->dev_name); - popup_set_text(popup, nfc->text_store, 82, 32, AlignCenter, AlignTop); + popup_set_text(popup, nfc->text_store, 89, 44, AlignCenter, AlignTop); } } diff --git a/applications/subghz/scenes/subghz_scene_rpc.c b/applications/subghz/scenes/subghz_scene_rpc.c index c6f7df26..652499d0 100644 --- a/applications/subghz/scenes/subghz_scene_rpc.c +++ b/applications/subghz/scenes/subghz_scene_rpc.c @@ -1,16 +1,23 @@ #include "../subghz_i.h" +typedef enum { + SubGhzRpcStateIdle, + SubGhzRpcStateLoaded, +} SubGhzRpcState; + void subghz_scene_rpc_on_enter(void* context) { SubGhz* subghz = context; Popup* popup = subghz->popup; - popup_set_header(popup, "Sub-GHz", 82, 28, AlignCenter, AlignBottom); - popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop); + popup_set_header(popup, "Sub-GHz", 89, 42, AlignCenter, AlignBottom); + popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop); - popup_set_icon(popup, 2, 14, &I_Warning_30x23); // TODO: icon + popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdPopup); + scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateIdle); + notification_message(subghz->notifications, &sequence_display_backlight_on); } @@ -18,28 +25,21 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; Popup* popup = subghz->popup; bool consumed = false; + SubGhzRpcState state = scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneRpc); if(event.type == SceneManagerEventTypeCustom) { consumed = true; if(event.event == SubGhzCustomEventSceneExit) { - if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { - subghz_tx_stop(subghz); - subghz_sleep(subghz); - } + scene_manager_stop(subghz->scene_manager); view_dispatcher_stop(subghz->view_dispatcher); rpc_system_app_confirm(subghz->rpc_ctx, RpcAppEventAppExit, true); } else if(event.event == SubGhzCustomEventSceneRpcSessionClose) { - rpc_system_app_set_callback(subghz->rpc_ctx, NULL, NULL); - subghz->rpc_ctx = NULL; - subghz_blink_stop(subghz); - if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { - subghz_tx_stop(subghz); - subghz_sleep(subghz); - } - view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneExit); + scene_manager_stop(subghz->scene_manager); + view_dispatcher_stop(subghz->view_dispatcher); } else if(event.event == SubGhzCustomEventSceneRpcButtonPress) { bool result = false; - if(subghz->txrx->txrx_state == SubGhzTxRxStateSleep) { + if((subghz->txrx->txrx_state == SubGhzTxRxStateSleep) && + (state == SubGhzRpcStateLoaded)) { subghz_blink_start(subghz); result = subghz_tx_start(subghz, subghz->txrx->fff_data); result = true; @@ -57,8 +57,10 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { } else if(event.event == SubGhzCustomEventSceneRpcLoad) { bool result = false; const char* arg = rpc_system_app_get_data(subghz->rpc_ctx); - if(arg) { + if(arg && (state == SubGhzRpcStateIdle)) { if(subghz_key_load(subghz, arg, false)) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateLoaded); string_set_str(subghz->file_path, arg); result = true; string_t file_name; @@ -70,7 +72,7 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { SUBGHZ_MAX_LEN_NAME, "loaded\n%s", string_get_cstr(file_name)); - popup_set_text(popup, subghz->file_name_tmp, 82, 32, AlignCenter, AlignTop); + popup_set_text(popup, subghz->file_name_tmp, 89, 44, AlignCenter, AlignTop); string_clear(file_name); } @@ -83,6 +85,13 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { void subghz_scene_rpc_on_exit(void* context) { SubGhz* subghz = context; + + if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { + subghz_tx_stop(subghz); + subghz_sleep(subghz); + subghz_blink_stop(subghz); + } + Popup* popup = subghz->popup; popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c index 3770d52c..4eb4bbd6 100644 --- a/applications/subghz/subghz.c +++ b/applications/subghz/subghz.c @@ -32,6 +32,8 @@ static void subghz_rpc_command_callback(RpcAppSystemEvent event, void* context) if(event == RpcAppEventSessionClose) { view_dispatcher_send_custom_event( subghz->view_dispatcher, SubGhzCustomEventSceneRpcSessionClose); + rpc_system_app_set_callback(subghz->rpc_ctx, NULL, NULL); + subghz->rpc_ctx = NULL; } else if(event == RpcAppEventAppExit) { view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneExit); } else if(event == RpcAppEventLoadFile) { diff --git a/lib/app-scened-template/view_controller.hpp b/lib/app-scened-template/view_controller.hpp index d08751c5..15028f53 100644 --- a/lib/app-scened-template/view_controller.hpp +++ b/lib/app-scened-template/view_controller.hpp @@ -26,7 +26,6 @@ public: 0)...); gui = static_cast(furi_record_open("gui")); - view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen); }; ~ViewController() { @@ -96,6 +95,10 @@ public: furi_check(result == FuriStatusOk); } + void attach_to_gui(ViewDispatcherType type) { + view_dispatcher_attach_to_gui(view_dispatcher, gui, type); + } + private: /** * @brief ViewModulesHolder