Merge pull request #4209 from fufesou/feat/plugin_framework
Feat/plugin framework
This commit is contained in:
		
						commit
						8a9af3a755
					
				| @ -260,10 +260,15 @@ class PluginItem extends StatelessWidget { | ||||
|   String? _getOption(OptionModel model, String key) { | ||||
|     var v = model.value; | ||||
|     if (v == null) { | ||||
|       if (peerId.isEmpty) { | ||||
|         v = bind.pluginGetSharedOption(id: pluginId, key: key); | ||||
|       } else { | ||||
|         v = bind.pluginGetSessionOption(id: pluginId, peer: peerId, key: key); | ||||
|       try { | ||||
|         if (peerId.isEmpty) { | ||||
|           v = bind.pluginGetSharedOption(id: pluginId, key: key); | ||||
|         } else { | ||||
|           v = bind.pluginGetSessionOption(id: pluginId, peer: peerId, key: key); | ||||
|         } | ||||
|       } catch (e) { | ||||
|         debugPrint('Failed to get option "$key", $e'); | ||||
|         v = null; | ||||
|       } | ||||
|     } | ||||
|     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() { | ||||
|  | ||||
| @ -60,6 +60,7 @@ pub struct Desc { | ||||
|     github: String, | ||||
|     location: Location, | ||||
|     config: Config, | ||||
|     listen_events: Vec<String>, | ||||
| } | ||||
| 
 | ||||
| impl Desc { | ||||
| @ -115,4 +116,8 @@ impl Desc { | ||||
|     pub fn config(&self) -> &Config { | ||||
|         &self.config | ||||
|     } | ||||
| 
 | ||||
|     pub fn listen_events(&self) -> &Vec<String> { | ||||
|         &self.listen_events | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -5,13 +5,13 @@ mod callback_msg; | ||||
| mod config; | ||||
| pub mod desc; | ||||
| mod errno; | ||||
| mod plog; | ||||
| pub mod ipc; | ||||
| mod plog; | ||||
| mod plugins; | ||||
| 
 | ||||
| pub use plugins::{ | ||||
|     handle_client_event, handle_server_event, handle_ui_event, load_plugin, load_plugins, | ||||
|     reload_plugin, sync_ui, unload_plugin, unload_plugins, | ||||
|     handle_client_event, handle_listen_event, handle_server_event, handle_ui_event, load_plugin, | ||||
|     load_plugins, reload_plugin, sync_ui, unload_plugin, unload_plugins, | ||||
| }; | ||||
| 
 | ||||
| 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_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}; | ||||
| 
 | ||||
| #[inline] | ||||
| @ -29,7 +34,7 @@ fn cstr_to_string(cstr: *const c_char) -> ResultType<String> { | ||||
| } | ||||
| 
 | ||||
| #[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(); | ||||
|     s.push(0); | ||||
|     unsafe { | ||||
|  | ||||
| @ -9,6 +9,7 @@ use hbb_common::{ | ||||
|     message_proto::{Message, Misc, PluginFailure, PluginRequest}, | ||||
|     ResultType, | ||||
| }; | ||||
| use serde_derive::Serialize; | ||||
| use std::{ | ||||
|     collections::HashMap, | ||||
|     ffi::{c_char, c_void}, | ||||
| @ -18,6 +19,7 @@ use std::{ | ||||
| 
 | ||||
| const METHOD_HANDLE_UI: &[u8; 10] = b"handle_ui\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! { | ||||
|     static ref PLUGIN_INFO: Arc<RwLock<HashMap<String, PluginInfo>>> = Default::default(); | ||||
| @ -249,6 +251,11 @@ make_plugin!( | ||||
|     server_call: PluginFuncServerCall | ||||
| ); | ||||
| 
 | ||||
| #[derive(Serialize)] | ||||
| pub struct MsgListenEvent { | ||||
|     pub event: String, | ||||
| } | ||||
| 
 | ||||
| #[cfg(target_os = "windows")] | ||||
| const DYLIB_SUFFIX: &str = ".dll"; | ||||
| #[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) | ||||
| } | ||||
| 
 | ||||
| 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] | ||||
| pub fn handle_client_event(id: &str, peer: &str, event: &[u8]) -> Message { | ||||
|     let mut peer: String = peer.to_owned(); | ||||
|  | ||||
| @ -563,6 +563,12 @@ impl Connection { | ||||
|         } else if video_privacy_conn_id == 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); | ||||
|         scrap::codec::Encoder::update(id, scrap::codec::EncodingUpdate::Remove); | ||||
|         video_service::VIDEO_QOS.lock().unwrap().reset(); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user