Merge pull request #4209 from fufesou/feat/plugin_framework
Feat/plugin framework
This commit is contained in:
		
						commit
						8a9af3a755
					
				| @ -260,11 +260,16 @@ class PluginItem extends StatelessWidget { | |||||||
|   String? _getOption(OptionModel model, String key) { |   String? _getOption(OptionModel model, String key) { | ||||||
|     var v = model.value; |     var v = model.value; | ||||||
|     if (v == null) { |     if (v == null) { | ||||||
|  |       try { | ||||||
|         if (peerId.isEmpty) { |         if (peerId.isEmpty) { | ||||||
|           v = bind.pluginGetSharedOption(id: pluginId, key: key); |           v = bind.pluginGetSharedOption(id: pluginId, key: key); | ||||||
|         } else { |         } else { | ||||||
|           v = bind.pluginGetSessionOption(id: pluginId, peer: peerId, key: key); |           v = bind.pluginGetSessionOption(id: pluginId, peer: peerId, key: key); | ||||||
|         } |         } | ||||||
|  |       } catch (e) { | ||||||
|  |         debugPrint('Failed to get option "$key", $e'); | ||||||
|  |         v = null; | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|     return v; |     return v; | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -961,6 +961,14 @@ impl<T: InvokeUiSession> Remote<T> { | |||||||
|                                     } |                                     } | ||||||
|                                 }); |                                 }); | ||||||
|                             } |                             } | ||||||
|  | 
 | ||||||
|  |                             // on connection established client
 | ||||||
|  |                             #[cfg(all(feature = "flutter", feature = "plugin_framework"))] | ||||||
|  |                             #[cfg(not(any(target_os = "android", target_os = "ios")))] | ||||||
|  |                             crate::plugin::handle_listen_event( | ||||||
|  |                                 crate::plugin::EVENT_ON_CONN_CLIENT.to_owned(), | ||||||
|  |                                 self.handler.id.clone(), | ||||||
|  |                             ) | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
|                         if self.handler.is_file_transfer() { |                         if self.handler.is_file_transfer() { | ||||||
|  | |||||||
| @ -60,6 +60,7 @@ pub struct Desc { | |||||||
|     github: String, |     github: String, | ||||||
|     location: Location, |     location: Location, | ||||||
|     config: Config, |     config: Config, | ||||||
|  |     listen_events: Vec<String>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Desc { | impl Desc { | ||||||
| @ -115,4 +116,8 @@ impl Desc { | |||||||
|     pub fn config(&self) -> &Config { |     pub fn config(&self) -> &Config { | ||||||
|         &self.config |         &self.config | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     pub fn listen_events(&self) -> &Vec<String> { | ||||||
|  |         &self.listen_events | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -5,13 +5,13 @@ mod callback_msg; | |||||||
| mod config; | mod config; | ||||||
| pub mod desc; | pub mod desc; | ||||||
| mod errno; | mod errno; | ||||||
| mod plog; |  | ||||||
| pub mod ipc; | pub mod ipc; | ||||||
|  | mod plog; | ||||||
| mod plugins; | mod plugins; | ||||||
| 
 | 
 | ||||||
| pub use plugins::{ | pub use plugins::{ | ||||||
|     handle_client_event, handle_server_event, handle_ui_event, load_plugin, load_plugins, |     handle_client_event, handle_listen_event, handle_server_event, handle_ui_event, load_plugin, | ||||||
|     reload_plugin, sync_ui, unload_plugin, unload_plugins, |     load_plugins, reload_plugin, sync_ui, unload_plugin, unload_plugins, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const MSG_TO_UI_TYPE_PLUGIN_DESC: &str = "plugin_desc"; | const MSG_TO_UI_TYPE_PLUGIN_DESC: &str = "plugin_desc"; | ||||||
| @ -19,6 +19,11 @@ const MSG_TO_UI_TYPE_PLUGIN_EVENT: &str = "plugin_event"; | |||||||
| const MSG_TO_UI_TYPE_PLUGIN_RELOAD: &str = "plugin_reload"; | const MSG_TO_UI_TYPE_PLUGIN_RELOAD: &str = "plugin_reload"; | ||||||
| const MSG_TO_UI_TYPE_PLUGIN_OPTION: &str = "plugin_option"; | const MSG_TO_UI_TYPE_PLUGIN_OPTION: &str = "plugin_option"; | ||||||
| 
 | 
 | ||||||
|  | pub const EVENT_ON_CONN_CLIENT: &str = "on_conn_client"; | ||||||
|  | pub const EVENT_ON_CONN_SERVER: &str = "on_conn_server"; | ||||||
|  | pub const EVENT_ON_CONN_CLOSE_CLIENT: &str = "on_conn_close_client"; | ||||||
|  | pub const EVENT_ON_CONN_CLOSE_SERVER: &str = "on_conn_close_server"; | ||||||
|  | 
 | ||||||
| pub use config::{ManagerConfig, PeerConfig, SharedConfig}; | pub use config::{ManagerConfig, PeerConfig, SharedConfig}; | ||||||
| 
 | 
 | ||||||
| #[inline] | #[inline] | ||||||
| @ -29,7 +34,7 @@ fn cstr_to_string(cstr: *const c_char) -> ResultType<String> { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[inline] | #[inline] | ||||||
| pub fn str_to_cstr_ret(s: &str) -> *const c_char { | fn str_to_cstr_ret(s: &str) -> *const c_char { | ||||||
|     let mut s = s.as_bytes().to_vec(); |     let mut s = s.as_bytes().to_vec(); | ||||||
|     s.push(0); |     s.push(0); | ||||||
|     unsafe { |     unsafe { | ||||||
|  | |||||||
| @ -9,6 +9,7 @@ use hbb_common::{ | |||||||
|     message_proto::{Message, Misc, PluginFailure, PluginRequest}, |     message_proto::{Message, Misc, PluginFailure, PluginRequest}, | ||||||
|     ResultType, |     ResultType, | ||||||
| }; | }; | ||||||
|  | use serde_derive::Serialize; | ||||||
| use std::{ | use std::{ | ||||||
|     collections::HashMap, |     collections::HashMap, | ||||||
|     ffi::{c_char, c_void}, |     ffi::{c_char, c_void}, | ||||||
| @ -18,6 +19,7 @@ use std::{ | |||||||
| 
 | 
 | ||||||
| const METHOD_HANDLE_UI: &[u8; 10] = b"handle_ui\0"; | const METHOD_HANDLE_UI: &[u8; 10] = b"handle_ui\0"; | ||||||
| const METHOD_HANDLE_PEER: &[u8; 12] = b"handle_peer\0"; | const METHOD_HANDLE_PEER: &[u8; 12] = b"handle_peer\0"; | ||||||
|  | pub const METHOD_HANDLE_LISTEN_EVENT: &[u8; 20] = b"handle_listen_event\0"; | ||||||
| 
 | 
 | ||||||
| lazy_static::lazy_static! { | lazy_static::lazy_static! { | ||||||
|     static ref PLUGIN_INFO: Arc<RwLock<HashMap<String, PluginInfo>>> = Default::default(); |     static ref PLUGIN_INFO: Arc<RwLock<HashMap<String, PluginInfo>>> = Default::default(); | ||||||
| @ -249,6 +251,11 @@ make_plugin!( | |||||||
|     server_call: PluginFuncServerCall |     server_call: PluginFuncServerCall | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
|  | #[derive(Serialize)] | ||||||
|  | pub struct MsgListenEvent { | ||||||
|  |     pub event: String, | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #[cfg(target_os = "windows")] | #[cfg(target_os = "windows")] | ||||||
| const DYLIB_SUFFIX: &str = ".dll"; | const DYLIB_SUFFIX: &str = ".dll"; | ||||||
| #[cfg(target_os = "linux")] | #[cfg(target_os = "linux")] | ||||||
| @ -415,6 +422,59 @@ pub fn handle_server_event(id: &str, peer: &str, event: &[u8]) -> ResultType<()> | |||||||
|     handle_event(METHOD_HANDLE_PEER, id, peer, event) |     handle_event(METHOD_HANDLE_PEER, id, peer, event) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | fn _handle_listen_event(event: String, peer: String) { | ||||||
|  |     let mut plugins = Vec::new(); | ||||||
|  |     for info in PLUGIN_INFO.read().unwrap().values() { | ||||||
|  |         if info.desc.listen_events().contains(&event.to_string()) { | ||||||
|  |             plugins.push(info.desc.id().to_string()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if plugins.is_empty() { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if let Ok(evt) = serde_json::to_string(&MsgListenEvent { | ||||||
|  |         event: event.clone(), | ||||||
|  |     }) { | ||||||
|  |         let mut evt_bytes = evt.as_bytes().to_vec(); | ||||||
|  |         evt_bytes.push(0); | ||||||
|  |         let mut peer: String = peer.to_owned(); | ||||||
|  |         peer.push('\0'); | ||||||
|  |         for id in plugins { | ||||||
|  |             match PLUGINS.read().unwrap().get(&id) { | ||||||
|  |                 Some(plugin) => { | ||||||
|  |                     let ret = (plugin.client_call)( | ||||||
|  |                         METHOD_HANDLE_LISTEN_EVENT.as_ptr() as _, | ||||||
|  |                         peer.as_ptr() as _, | ||||||
|  |                         evt_bytes.as_ptr() as _, | ||||||
|  |                         evt_bytes.len(), | ||||||
|  |                     ); | ||||||
|  |                     if !ret.is_null() { | ||||||
|  |                         let (code, msg) = get_code_msg_from_ret(ret); | ||||||
|  |                         free_c_ptr(ret as _); | ||||||
|  |                         log::error!( | ||||||
|  |                             "Failed to handle plugin listen event, id: {}, event: {}, code: {}, msg: {}", | ||||||
|  |                             id, | ||||||
|  |                             event, | ||||||
|  |                             code, | ||||||
|  |                             msg | ||||||
|  |                         ); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 None => { | ||||||
|  |                     log::error!("Plugin {} not found when handle_listen_event", id); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[inline] | ||||||
|  | pub fn handle_listen_event(event: String, peer: String) { | ||||||
|  |     std::thread::spawn(|| _handle_listen_event(event, peer)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #[inline] | #[inline] | ||||||
| pub fn handle_client_event(id: &str, peer: &str, event: &[u8]) -> Message { | pub fn handle_client_event(id: &str, peer: &str, event: &[u8]) -> Message { | ||||||
|     let mut peer: String = peer.to_owned(); |     let mut peer: String = peer.to_owned(); | ||||||
|  | |||||||
| @ -563,6 +563,12 @@ impl Connection { | |||||||
|         } else if video_privacy_conn_id == 0 { |         } else if video_privacy_conn_id == 0 { | ||||||
|             let _ = privacy_mode::turn_off_privacy(0); |             let _ = privacy_mode::turn_off_privacy(0); | ||||||
|         } |         } | ||||||
|  |         #[cfg(all(feature = "flutter", feature = "plugin_framework"))] | ||||||
|  |         #[cfg(not(any(target_os = "android", target_os = "ios")))] | ||||||
|  |         crate::plugin::handle_listen_event( | ||||||
|  |             crate::plugin::EVENT_ON_CONN_CLOSE_SERVER.to_owned(), | ||||||
|  |             conn.lr.my_id.clone(), | ||||||
|  |         ); | ||||||
|         video_service::notify_video_frame_fetched(id, None); |         video_service::notify_video_frame_fetched(id, None); | ||||||
|         scrap::codec::Encoder::update(id, scrap::codec::EncodingUpdate::Remove); |         scrap::codec::Encoder::update(id, scrap::codec::EncodingUpdate::Remove); | ||||||
|         video_service::VIDEO_QOS.lock().unwrap().reset(); |         video_service::VIDEO_QOS.lock().unwrap().reset(); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user