[FL-3315] Desktop,Rpc: desktop status subscription (#2696)
* Desktop,Rpc: desktop status subscription * Desktop,RPC: properly handle unsubscribe Co-authored-by: Sergey Gavrilov <who.just.the.doctor@gmail.com>
This commit is contained in:
		
							parent
							
								
									88f0b63577
								
							
						
					
					
						commit
						080324f7e0
					
				| @ -147,6 +147,9 @@ void desktop_lock(Desktop* desktop) { | |||||||
|         desktop->scene_manager, DesktopSceneLocked, SCENE_LOCKED_FIRST_ENTER); |         desktop->scene_manager, DesktopSceneLocked, SCENE_LOCKED_FIRST_ENTER); | ||||||
|     scene_manager_next_scene(desktop->scene_manager, DesktopSceneLocked); |     scene_manager_next_scene(desktop->scene_manager, DesktopSceneLocked); | ||||||
|     notification_message(desktop->notification, &sequence_display_backlight_off_delay_1000); |     notification_message(desktop->notification, &sequence_display_backlight_off_delay_1000); | ||||||
|  | 
 | ||||||
|  |     DesktopStatus status = {.locked = true}; | ||||||
|  |     furi_pubsub_publish(desktop->status_pubsub, &status); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void desktop_unlock(Desktop* desktop) { | void desktop_unlock(Desktop* desktop) { | ||||||
| @ -165,6 +168,9 @@ void desktop_unlock(Desktop* desktop) { | |||||||
|         cli_session_open(cli, &cli_vcp); |         cli_session_open(cli, &cli_vcp); | ||||||
|         furi_record_close(RECORD_CLI); |         furi_record_close(RECORD_CLI); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     DesktopStatus status = {.locked = false}; | ||||||
|  |     furi_pubsub_publish(desktop->status_pubsub, &status); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void desktop_set_dummy_mode_state(Desktop* desktop, bool enabled) { | void desktop_set_dummy_mode_state(Desktop* desktop, bool enabled) { | ||||||
| @ -308,6 +314,8 @@ Desktop* desktop_alloc() { | |||||||
|     desktop->auto_lock_timer = |     desktop->auto_lock_timer = | ||||||
|         furi_timer_alloc(desktop_auto_lock_timer_callback, FuriTimerTypeOnce, desktop); |         furi_timer_alloc(desktop_auto_lock_timer_callback, FuriTimerTypeOnce, desktop); | ||||||
| 
 | 
 | ||||||
|  |     desktop->status_pubsub = furi_pubsub_alloc(); | ||||||
|  | 
 | ||||||
|     furi_record_create(RECORD_DESKTOP, desktop); |     furi_record_create(RECORD_DESKTOP, desktop); | ||||||
| 
 | 
 | ||||||
|     return desktop; |     return desktop; | ||||||
| @ -331,6 +339,11 @@ void desktop_api_unlock(Desktop* instance) { | |||||||
|     view_dispatcher_send_custom_event(instance->view_dispatcher, DesktopLockedEventUnlocked); |     view_dispatcher_send_custom_event(instance->view_dispatcher, DesktopLockedEventUnlocked); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | FuriPubSub* desktop_api_get_status_pubsub(Desktop* instance) { | ||||||
|  |     furi_assert(instance); | ||||||
|  |     return instance->status_pubsub; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int32_t desktop_srv(void* p) { | int32_t desktop_srv(void* p) { | ||||||
|     UNUSED(p); |     UNUSED(p); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,5 +1,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | #include <furi.h> | ||||||
|  | 
 | ||||||
| typedef struct Desktop Desktop; | typedef struct Desktop Desktop; | ||||||
| 
 | 
 | ||||||
| #define RECORD_DESKTOP "desktop" | #define RECORD_DESKTOP "desktop" | ||||||
| @ -7,3 +9,9 @@ typedef struct Desktop Desktop; | |||||||
| bool desktop_api_is_locked(Desktop* instance); | bool desktop_api_is_locked(Desktop* instance); | ||||||
| 
 | 
 | ||||||
| void desktop_api_unlock(Desktop* instance); | void desktop_api_unlock(Desktop* instance); | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     bool locked; | ||||||
|  | } DesktopStatus; | ||||||
|  | 
 | ||||||
|  | FuriPubSub* desktop_api_get_status_pubsub(Desktop* instance); | ||||||
|  | |||||||
| @ -71,6 +71,8 @@ struct Desktop { | |||||||
|     FuriPubSubSubscription* input_events_subscription; |     FuriPubSubSubscription* input_events_subscription; | ||||||
|     FuriTimer* auto_lock_timer; |     FuriTimer* auto_lock_timer; | ||||||
| 
 | 
 | ||||||
|  |     FuriPubSub* status_pubsub; | ||||||
|  | 
 | ||||||
|     bool in_transition; |     bool in_transition; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -8,6 +8,8 @@ | |||||||
| typedef struct { | typedef struct { | ||||||
|     RpcSession* session; |     RpcSession* session; | ||||||
|     Desktop* desktop; |     Desktop* desktop; | ||||||
|  |     FuriPubSub* status_pubsub; | ||||||
|  |     FuriPubSubSubscription* status_subscription; | ||||||
| } RpcDesktop; | } RpcDesktop; | ||||||
| 
 | 
 | ||||||
| static void rpc_desktop_on_is_locked_request(const PB_Main* request, void* context) { | static void rpc_desktop_on_is_locked_request(const PB_Main* request, void* context) { | ||||||
| @ -39,11 +41,63 @@ static void rpc_desktop_on_unlock_request(const PB_Main* request, void* context) | |||||||
|     rpc_send_and_release_empty(session, request->command_id, PB_CommandStatus_OK); |     rpc_send_and_release_empty(session, request->command_id, PB_CommandStatus_OK); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void rpc_desktop_on_desktop_pubsub(const void* message, void* context) { | ||||||
|  |     RpcDesktop* rpc_desktop = context; | ||||||
|  |     RpcSession* session = rpc_desktop->session; | ||||||
|  |     const DesktopStatus* status = message; | ||||||
|  | 
 | ||||||
|  |     PB_Main rpc_message = { | ||||||
|  |         .command_id = 0, | ||||||
|  |         .command_status = PB_CommandStatus_OK, | ||||||
|  |         .has_next = false, | ||||||
|  |         .which_content = PB_Main_desktop_status_tag, | ||||||
|  |         .content.desktop_status.locked = status->locked, | ||||||
|  |     }; | ||||||
|  |     rpc_send_and_release(session, &rpc_message); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void rpc_desktop_on_status_subscribe_request(const PB_Main* request, void* context) { | ||||||
|  |     furi_assert(request); | ||||||
|  |     furi_assert(context); | ||||||
|  |     furi_assert(request->which_content == PB_Main_desktop_status_subscribe_request_tag); | ||||||
|  | 
 | ||||||
|  |     FURI_LOG_D(TAG, "StatusSubscribeRequest"); | ||||||
|  |     RpcDesktop* rpc_desktop = context; | ||||||
|  |     RpcSession* session = rpc_desktop->session; | ||||||
|  | 
 | ||||||
|  |     if(rpc_desktop->status_subscription) { | ||||||
|  |         rpc_send_and_release_empty(session, request->command_id, PB_CommandStatus_ERROR); | ||||||
|  |     } else { | ||||||
|  |         rpc_desktop->status_subscription = furi_pubsub_subscribe( | ||||||
|  |             rpc_desktop->status_pubsub, rpc_desktop_on_desktop_pubsub, rpc_desktop); | ||||||
|  |         rpc_send_and_release_empty(session, request->command_id, PB_CommandStatus_OK); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void rpc_desktop_on_status_unsubscribe_request(const PB_Main* request, void* context) { | ||||||
|  |     furi_assert(request); | ||||||
|  |     furi_assert(context); | ||||||
|  |     furi_assert(request->which_content == PB_Main_desktop_status_unsubscribe_request_tag); | ||||||
|  | 
 | ||||||
|  |     FURI_LOG_D(TAG, "StatusUnsubscribeRequest"); | ||||||
|  |     RpcDesktop* rpc_desktop = context; | ||||||
|  |     RpcSession* session = rpc_desktop->session; | ||||||
|  | 
 | ||||||
|  |     if(rpc_desktop->status_subscription) { | ||||||
|  |         furi_pubsub_unsubscribe(rpc_desktop->status_pubsub, rpc_desktop->status_subscription); | ||||||
|  |         rpc_desktop->status_subscription = NULL; | ||||||
|  |         rpc_send_and_release_empty(session, request->command_id, PB_CommandStatus_OK); | ||||||
|  |     } else { | ||||||
|  |         rpc_send_and_release_empty(session, request->command_id, PB_CommandStatus_ERROR); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void* rpc_desktop_alloc(RpcSession* session) { | void* rpc_desktop_alloc(RpcSession* session) { | ||||||
|     furi_assert(session); |     furi_assert(session); | ||||||
| 
 | 
 | ||||||
|     RpcDesktop* rpc_desktop = malloc(sizeof(RpcDesktop)); |     RpcDesktop* rpc_desktop = malloc(sizeof(RpcDesktop)); | ||||||
|     rpc_desktop->desktop = furi_record_open(RECORD_DESKTOP); |     rpc_desktop->desktop = furi_record_open(RECORD_DESKTOP); | ||||||
|  |     rpc_desktop->status_pubsub = desktop_api_get_status_pubsub(rpc_desktop->desktop); | ||||||
|     rpc_desktop->session = session; |     rpc_desktop->session = session; | ||||||
| 
 | 
 | ||||||
|     RpcHandler rpc_handler = { |     RpcHandler rpc_handler = { | ||||||
| @ -58,6 +112,12 @@ void* rpc_desktop_alloc(RpcSession* session) { | |||||||
|     rpc_handler.message_handler = rpc_desktop_on_unlock_request; |     rpc_handler.message_handler = rpc_desktop_on_unlock_request; | ||||||
|     rpc_add_handler(session, PB_Main_desktop_unlock_request_tag, &rpc_handler); |     rpc_add_handler(session, PB_Main_desktop_unlock_request_tag, &rpc_handler); | ||||||
| 
 | 
 | ||||||
|  |     rpc_handler.message_handler = rpc_desktop_on_status_subscribe_request; | ||||||
|  |     rpc_add_handler(session, PB_Main_desktop_status_subscribe_request_tag, &rpc_handler); | ||||||
|  | 
 | ||||||
|  |     rpc_handler.message_handler = rpc_desktop_on_status_unsubscribe_request; | ||||||
|  |     rpc_add_handler(session, PB_Main_desktop_status_unsubscribe_request_tag, &rpc_handler); | ||||||
|  | 
 | ||||||
|     return rpc_desktop; |     return rpc_desktop; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -65,6 +125,10 @@ void rpc_desktop_free(void* context) { | |||||||
|     furi_assert(context); |     furi_assert(context); | ||||||
|     RpcDesktop* rpc_desktop = context; |     RpcDesktop* rpc_desktop = context; | ||||||
| 
 | 
 | ||||||
|  |     if(rpc_desktop->status_subscription) { | ||||||
|  |         furi_pubsub_unsubscribe(rpc_desktop->status_pubsub, rpc_desktop->status_subscription); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     furi_assert(rpc_desktop->desktop); |     furi_assert(rpc_desktop->desktop); | ||||||
|     furi_record_close(RECORD_DESKTOP); |     furi_record_close(RECORD_DESKTOP); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1 +1 @@ | |||||||
| Subproject commit a13c5ddd0397511bd4c6de4afdd1031a5b6f5bca | Subproject commit f71c4b7f750f2539a1fed08925d8da3abdc80ff9 | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 あく
						あく