plugin_framework, handle plugin list

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou 2023-05-09 22:59:38 +08:00
parent db71dd039d
commit 4eb6bd82a4
8 changed files with 57 additions and 33 deletions

View File

@ -126,6 +126,7 @@ void runMainApp(bool startService) async {
// await windowManager.ensureInitialized();
gFFI.serverModel.startService();
bind.pluginSyncUi(syncTo: kAppTypeMain);
bind.pluginListReload();
}
gFFI.userModel.refreshCurrentUser();
runApp(App());

View File

@ -231,6 +231,7 @@ class FfiModel with ChangeNotifier {
} else if (name == 'fingerprint') {
FingerprintState.find(peerId).value = evt['fingerprint'] ?? '';
} else if (name == 'plugin_manager') {
debugPrint('REMOVE ME ==================== plugin_manager $evt');
pluginManager.handleEvent(evt);
} else if (name == 'plugin_event') {
handlePluginEvent(

View File

@ -1,6 +1,7 @@
// The plugin manager is a singleton class that manages the plugins.
// 1. It merge metadata and the desc of plugins.
import 'dart:convert';
import 'dart:collection';
import 'package:flutter/material.dart';
@ -211,17 +212,19 @@ class PluginManager with ChangeNotifier {
}
}
void _handlePluginList(List<dynamic> evt) {
void _handlePluginList(String pluginList) {
_plugins.clear();
for (var p in evt) {
final plugin = _getPluginFromEvent(p);
if (plugin == null) {
continue;
try {
for (var p in json.decode(pluginList) as List<dynamic>) {
final plugin = _getPluginFromEvent(p);
if (plugin == null) {
continue;
}
_plugins.add(plugin);
}
_plugins.add(plugin);
} catch (e) {
debugPrint('Failed to decode plugin list \'$pluginList\'');
}
notifyListeners();
}

View File

@ -35,6 +35,7 @@ chrono = "0.4"
backtrace = "0.3"
libc = "0.2"
dlopen = "0.1"
toml = "0.7"
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
mac_address = "1.1"
@ -55,5 +56,4 @@ winapi = { version = "0.3", features = ["winuser"] }
osascript = "0.3"
[dev-dependencies]
toml = "0.7"
serde_json = "1.0"

View File

@ -46,6 +46,7 @@ pub mod keyboard;
pub use sysinfo;
#[cfg(not(any(target_os = "android", target_os = "ios")))]
pub use dlopen;
pub use toml;
#[cfg(feature = "quic")]
pub type Stream = quic::Connection;

View File

@ -1570,7 +1570,7 @@ pub fn plugin_list_reload() {
#[cfg(feature = "plugin_framework")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
{
crate::plugin::load_plugin_list(false);
crate::plugin::load_plugin_list();
}
}

View File

@ -3,7 +3,7 @@
use super::{desc::Meta as PluginMeta, ipc::InstallStatus, *};
use crate::{common::is_server, flutter};
use hbb_common::{allow_err, bail, log, tokio};
use hbb_common::{allow_err, bail, config::load_path, log, tokio, toml};
use serde_derive::{Deserialize, Serialize};
use serde_json;
use std::{
@ -21,7 +21,7 @@ lazy_static::lazy_static! {
static ref PLUGIN_INFO: Arc<Mutex<HashMap<String, PluginInfo>>> = Arc::new(Mutex::new(HashMap::new()));
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct ManagerMeta {
pub version: String,
pub description: String,
@ -45,24 +45,47 @@ pub struct PluginInfo {
}
static PLUGIN_SOURCE_LOCAL: &str = "local";
pub(super) static PLUGIN_SOURCE_LOCAL_URL: &str = "plugins";
#[cfg(not(debug_assertions))]
fn get_plugin_source_list() -> Vec<PluginSource> {
// Only one source for now.
vec![PluginSource {
name: "rustdesk".to_string(),
#[cfg(debug_assertions)]
url: PLUGIN_SOURCE_LOCAL_URL.to_string(),
#[cfg(not(debug_assertions))]
url: "https://github.com/fufesou/rustdesk-plugins".to_string(),
description: "".to_string(),
}]
}
#[cfg(debug_assertions)]
fn get_source_plugins() -> HashMap<String, PluginInfo> {
let meta_file = super::get_plugins_dir().unwrap().join("meta.toml");
let mut plugins = HashMap::new();
let meta = load_path::<ManagerMeta>(meta_file);
let source = PluginSource {
name: "rustdesk".to_string(),
url: "https://github.com/fufesou/rustdesk-plugins".to_string(),
description: "".to_string(),
};
for plugin in meta.plugins.iter() {
plugins.insert(
plugin.id.clone(),
PluginInfo {
source: source.clone(),
plugin: plugin.clone(),
installed_version: "".to_string(),
install_time: "".to_string(),
invalid_reason: "".to_string(),
},
);
}
plugins
}
#[cfg(not(debug_assertions))]
fn get_source_plugins() -> HashMap<String, PluginInfo> {
let mut plugins = HashMap::new();
for source in get_plugin_source_list().into_iter() {
let url = format!("{}/meta.json", source.url);
let url = format!("{}/meta.toml", source.url);
match reqwest::blocking::get(&url) {
Ok(resp) => {
if !resp.status().is_success() {
@ -109,16 +132,8 @@ fn send_plugin_list_event(plugins: &HashMap<String, PluginInfo>) {
}
}
pub fn load_plugin_list(load_local: bool) {
pub fn load_plugin_list() {
let mut plugin_info_lock = PLUGIN_INFO.lock().unwrap();
if load_local {
if is_server() {
allow_err!(super::plugins::load_plugins());
return;
}
}
let mut plugins = get_source_plugins();
for (id, info) in super::plugins::get_plugin_infos().read().unwrap().iter() {
if let Some(p) = plugins.get_mut(id) {
@ -130,7 +145,7 @@ pub fn load_plugin_list(load_local: bool) {
PluginInfo {
source: PluginSource {
name: PLUGIN_SOURCE_LOCAL.to_string(),
url: PLUGIN_SOURCE_LOCAL_URL.to_string(),
url: PLUGIN_SOURCE_LOCAL_DIR.to_string(),
description: "".to_string(),
},
plugin: info.desc.meta().clone(),
@ -163,9 +178,7 @@ pub fn install_plugin(id: &str) -> ResultType<()> {
}
}
pub(super) fn remove_plugins() {
}
pub(super) fn remove_plugins() {}
// 1. Add to uninstall list.
// 2. Try remove.

View File

@ -1,4 +1,4 @@
use hbb_common::{libc, tokio, ResultType};
use hbb_common::{libc, tokio, ResultType, allow_err, log};
use std::{
env,
ffi::{c_char, c_int, c_void, CStr},
@ -38,6 +38,8 @@ 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";
static PLUGIN_SOURCE_LOCAL_DIR: &str = "plugins";
pub use config::{ManagerConfig, PeerConfig, SharedConfig};
use crate::common::is_server;
@ -91,14 +93,17 @@ pub fn init() {
std::thread::spawn(move || manager::start_ipc());
if is_server() {
manager::remove_plugins();
allow_err!(plugins::load_plugins());
}
load_plugin_list(true);
load_plugin_list();
}
#[inline]
fn get_plugins_dir() -> ResultType<PathBuf> {
// to-do: linux and macos
Ok(PathBuf::from(env::var("ProgramData")?).join(manager::PLUGIN_SOURCE_LOCAL_URL))
Ok(PathBuf::from(env::var("ProgramData")?)
.join("RustDesk")
.join(PLUGIN_SOURCE_LOCAL_DIR))
}
#[inline]