diff --git a/flutter/lib/common/hbbs/hbbs.dart b/flutter/lib/common/hbbs/hbbs.dart index d102d9f02..8e5c2d02a 100644 --- a/flutter/lib/common/hbbs/hbbs.dart +++ b/flutter/lib/common/hbbs/hbbs.dart @@ -1,4 +1,5 @@ -import 'dart:io'; +import 'dart:convert'; +import 'package:flutter/material.dart'; import 'package:flutter_hbb/models/peer_model.dart'; @@ -70,16 +71,6 @@ class PeerPayload { } } -class DeviceInfo { - static Map toJson() { - final Map data = {}; - data['os'] = Platform.operatingSystem; - data['type'] = "client"; - data['name'] = bind.mainGetHostname(); - return data; - } -} - class LoginRequest { String? username; String? password; @@ -88,7 +79,6 @@ class LoginRequest { bool? autoLogin; String? type; String? verificationCode; - Map deviceInfo = DeviceInfo.toJson(); LoginRequest( {this.username, @@ -110,6 +100,13 @@ class LoginRequest { if (verificationCode != null) { data['verificationCode'] = verificationCode; } + + Map deviceInfo = {}; + try { + deviceInfo = jsonDecode(bind.mainGetLoginDeviceInfo()); + } catch (e) { + debugPrint('Failed to decode get device info: $e'); + } data['deviceInfo'] = deviceInfo; return data; } diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 122af0c2b..ef4c9e2ba 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -637,8 +637,8 @@ pub fn main_get_default_sound_input() -> Option { None } -pub fn main_get_hostname() -> SyncReturn { - SyncReturn(get_hostname()) +pub fn main_get_login_device_info() -> SyncReturn { + SyncReturn(get_login_device_info_json()) } pub fn main_change_id(new_id: String) { diff --git a/src/hbbs_http/account.rs b/src/hbbs_http/account.rs index 2afd4b83e..e76dda76c 100644 --- a/src/hbbs_http/account.rs +++ b/src/hbbs_http/account.rs @@ -148,7 +148,12 @@ impl OidcSession { .unwrap() .client .post(format!("{}/api/oidc/auth", api_server)) - .json(&HashMap::from([("op", op), ("id", id), ("uuid", uuid)])) + .json(&serde_json::json!({ + "op": op, + "id": id, + "uuid": uuid, + "deviceInfo": crate::ui_interface::get_login_device_info(), + })) .send()? .try_into()?) } diff --git a/src/plugin/native_handlers/ui.rs b/src/plugin/native_handlers/ui.rs index d4ee91299..aec7facd8 100644 --- a/src/plugin/native_handlers/ui.rs +++ b/src/plugin/native_handlers/ui.rs @@ -2,10 +2,7 @@ use std::{collections::HashMap, ffi::c_void, os::raw::c_int}; use serde_json::json; -use crate::{ - define_method_prefix, - flutter::{APP_TYPE_MAIN}, -}; +use crate::{define_method_prefix, flutter::APP_TYPE_MAIN}; use super::PluginNativeHandler; @@ -26,7 +23,8 @@ pub struct PluginNativeUIHandler; /// ``` /// [Safety] /// Please make sure the callback u provided is VALID, or memory or calling issues may occur to cause the program crash! -pub type OnUIReturnCallback = extern "C" fn(return_code: c_int, data: *const c_void, data_len: u64, user_data: *const c_void); +pub type OnUIReturnCallback = + extern "C" fn(return_code: c_int, data: *const c_void, data_len: u64, user_data: *const c_void); impl PluginNativeHandler for PluginNativeUIHandler { define_method_prefix!("ui_"); @@ -41,9 +39,7 @@ impl PluginNativeHandler for PluginNativeUIHandler { if let Some(cb) = data.get("cb") { if let Some(cb) = cb.as_u64() { let user_data = match data.get("user_data") { - Some(user_data) => { - user_data.as_u64().unwrap_or(0) - }, + Some(user_data) => user_data.as_u64().unwrap_or(0), None => 0, }; self.select_peers_async(cb, user_data); @@ -68,9 +64,7 @@ impl PluginNativeHandler for PluginNativeUIHandler { if let Some(on_tap_cb) = data.get("on_tap_cb") { if let Some(on_tap_cb) = on_tap_cb.as_u64() { let user_data = match data.get("user_data") { - Some(user_data) => { - user_data.as_u64().unwrap_or(0) - }, + Some(user_data) => user_data.as_u64().unwrap_or(0), None => 0, }; self.register_ui_entry(title, on_tap_cb, user_data); @@ -109,10 +103,10 @@ impl PluginNativeUIHandler { /// "user_data": 0 // An opaque pointer value passed to the callback. /// } /// ``` - /// - /// [Arguments] + /// + /// [Arguments] /// @param cb: the function address with type [OnUIReturnCallback]. - /// @param user_data: the function will be called with this value. + /// @param user_data: the function will be called with this value. fn select_peers_async(&self, cb: u64, user_data: u64) { let mut param = HashMap::new(); param.insert("name", json!("native_ui")); diff --git a/src/ui_interface.rs b/src/ui_interface.rs index dbd673880..b5f0cdb18 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -44,6 +44,13 @@ pub struct UiStatus { pub id: String, } +#[derive(Debug, Clone, Serialize)] +pub struct LoginDeviceInfo { + pub os: String, + pub r#type: String, + pub name: String, +} + lazy_static::lazy_static! { static ref UI_STATUS : Arc> = Arc::new(Mutex::new(UiStatus{ status_num: 0, @@ -959,6 +966,21 @@ pub fn get_hostname() -> String { crate::common::hostname() } +#[inline] +pub fn get_login_device_info() -> LoginDeviceInfo { + LoginDeviceInfo { + // std::env::consts::OS is better than whoami::platform() here. + os: std::env::consts::OS.to_owned(), + r#type: "client".to_owned(), + name: crate::common::hostname(), + } +} + +#[inline] +pub fn get_login_device_info_json() -> String { + serde_json::to_string(&get_login_device_info()).unwrap_or_default() +} + // notice: avoiding create ipc connection repeatedly, // because windows named pipe has serious memory leak issue. #[cfg(not(any(target_os = "android", target_os = "ios")))]