mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-09-13 11:04:25 +08:00
del: 移除安卓支持
This commit is contained in:
@@ -1,44 +0,0 @@
|
||||
//! Android Amlogic platform capabilities.
|
||||
|
||||
use super::{FeatureCapability, PlatformCapabilities, PlatformMode};
|
||||
|
||||
#[cfg(feature = "android")]
|
||||
#[allow(dead_code)]
|
||||
fn _keep_android_bionic_ifaddrs_shim_linked() {
|
||||
let _ = crate::platform::android_bionic::freeifaddrs
|
||||
as unsafe extern "C" fn(*mut crate::platform::android_bionic::ifaddrs);
|
||||
let _ = crate::platform::android_bionic::getifaddrs
|
||||
as unsafe extern "C" fn(*mut *mut crate::platform::android_bionic::ifaddrs) -> i32;
|
||||
}
|
||||
|
||||
pub fn capabilities() -> PlatformCapabilities {
|
||||
#[cfg(feature = "android")]
|
||||
_keep_android_bionic_ifaddrs_shim_linked();
|
||||
|
||||
PlatformCapabilities {
|
||||
mode: PlatformMode::AndroidAmlogic,
|
||||
mode_label: PlatformMode::AndroidAmlogic.label(),
|
||||
video_capture: FeatureCapability::available(["v4l2_uvc"])
|
||||
.with_selected_backend(Some("v4l2_uvc".to_string())),
|
||||
encoder: FeatureCapability::available(["ffmpeg_mediacodec_h264", "mjpeg"])
|
||||
.with_selected_backend(Some(
|
||||
if cfg!(feature = "android-mediacodec") {
|
||||
"ffmpeg_mediacodec_h264"
|
||||
} else {
|
||||
"mjpeg"
|
||||
}
|
||||
.to_string(),
|
||||
)),
|
||||
hid: FeatureCapability::available(["otg_configfs", "ch9329", "none"]),
|
||||
atx: FeatureCapability::available(["gpio", "usb_relay", "serial", "wol", "none"]),
|
||||
msd: FeatureCapability::available(["otg_configfs"]),
|
||||
otg: FeatureCapability::available(["configfs"]),
|
||||
audio: FeatureCapability::available(["alsa", "opus"])
|
||||
.with_selected_backend(Some("alsa".to_string())),
|
||||
rustdesk: FeatureCapability::available(["builtin"]),
|
||||
vnc: FeatureCapability::available(["builtin", "tight_jpeg", "h264"]),
|
||||
diagnostics: FeatureCapability::available(["android_linux"]),
|
||||
extensions: FeatureCapability::unsupported("unsupported on Android Amlogic v1"),
|
||||
service_installation: FeatureCapability::available(["android_foreground_service"]),
|
||||
}
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::mem::{size_of, zeroed};
|
||||
use std::os::raw::{c_char, c_int, c_uint, c_void};
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ifaddrs {
|
||||
pub ifa_next: *mut ifaddrs,
|
||||
pub ifa_name: *mut c_char,
|
||||
pub ifa_flags: c_uint,
|
||||
pub ifa_addr: *mut libc::sockaddr,
|
||||
pub ifa_netmask: *mut libc::sockaddr,
|
||||
pub ifa_ifu: *mut libc::sockaddr,
|
||||
pub ifa_data: *mut c_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct AddrNode {
|
||||
ifa: ifaddrs,
|
||||
name: CString,
|
||||
addr: libc::sockaddr_in,
|
||||
next: *mut AddrNode,
|
||||
}
|
||||
|
||||
fn sockaddr_to_ipv4(addr: libc::sockaddr) -> Option<std::net::Ipv4Addr> {
|
||||
if addr.sa_family as c_int != libc::AF_INET {
|
||||
return None;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let sin = &*(&addr as *const libc::sockaddr as *const libc::sockaddr_in);
|
||||
Some(std::net::Ipv4Addr::from(u32::from_be(sin.sin_addr.s_addr)))
|
||||
}
|
||||
}
|
||||
|
||||
fn query_ipv4(iface_name: &str) -> Option<libc::sockaddr_in> {
|
||||
let name = CString::new(iface_name).ok()?;
|
||||
if name.as_bytes().len() >= libc::IFNAMSIZ {
|
||||
return None;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let fd = libc::socket(libc::AF_INET, libc::SOCK_DGRAM, 0);
|
||||
if fd < 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut request: libc::ifreq = zeroed();
|
||||
std::ptr::copy_nonoverlapping(
|
||||
name.as_ptr(),
|
||||
request.ifr_name.as_mut_ptr(),
|
||||
name.as_bytes_with_nul().len(),
|
||||
);
|
||||
|
||||
let request_code = libc::SIOCGIFADDR.try_into().ok()?;
|
||||
let rc = libc::ioctl(fd, request_code, &mut request);
|
||||
libc::close(fd);
|
||||
if rc < 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let addr = request.ifr_ifru.ifru_addr;
|
||||
if addr.sa_family as c_int != libc::AF_INET {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut sin: libc::sockaddr_in = zeroed();
|
||||
std::ptr::copy_nonoverlapping(
|
||||
&addr as *const libc::sockaddr as *const u8,
|
||||
&mut sin as *mut libc::sockaddr_in as *mut u8,
|
||||
size_of::<libc::sockaddr_in>(),
|
||||
);
|
||||
Some(sin)
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn getifaddrs(addrs: *mut *mut ifaddrs) -> c_int {
|
||||
if addrs.is_null() {
|
||||
return -1;
|
||||
}
|
||||
*addrs = std::ptr::null_mut();
|
||||
|
||||
let net_dir = match std::fs::read_dir("/sys/class/net") {
|
||||
Ok(dir) => dir,
|
||||
Err(_) => return -1,
|
||||
};
|
||||
|
||||
let mut head: *mut AddrNode = std::ptr::null_mut();
|
||||
let mut tail: *mut AddrNode = std::ptr::null_mut();
|
||||
|
||||
for entry in net_dir.flatten() {
|
||||
let iface_name = match entry.file_name().into_string() {
|
||||
Ok(name) => name,
|
||||
Err(_) => continue,
|
||||
};
|
||||
if iface_name == "lo" {
|
||||
continue;
|
||||
}
|
||||
|
||||
let operstate_path = entry.path().join("operstate");
|
||||
let is_up = std::fs::read_to_string(&operstate_path)
|
||||
.map(|s| s.trim() == "up")
|
||||
.unwrap_or(false);
|
||||
if !is_up {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some(addr) = query_ipv4(&iface_name) else {
|
||||
continue;
|
||||
};
|
||||
let ip = sockaddr_to_ipv4(unsafe {
|
||||
std::mem::transmute::<libc::sockaddr_in, libc::sockaddr>(addr)
|
||||
});
|
||||
if ip
|
||||
.map(|ip| ip.is_loopback() || ip.is_unspecified())
|
||||
.unwrap_or(true)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let name = match CString::new(iface_name) {
|
||||
Ok(name) => name,
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
let mut node = Box::new(AddrNode {
|
||||
ifa: ifaddrs {
|
||||
ifa_next: std::ptr::null_mut(),
|
||||
ifa_name: std::ptr::null_mut(),
|
||||
ifa_flags: 0,
|
||||
ifa_addr: std::ptr::null_mut(),
|
||||
ifa_netmask: std::ptr::null_mut(),
|
||||
ifa_ifu: std::ptr::null_mut(),
|
||||
ifa_data: std::ptr::null_mut(),
|
||||
},
|
||||
name,
|
||||
addr,
|
||||
next: std::ptr::null_mut(),
|
||||
});
|
||||
|
||||
node.ifa.ifa_name = node.name.as_ptr() as *mut c_char;
|
||||
node.ifa.ifa_addr = &mut node.addr as *mut libc::sockaddr_in as *mut libc::sockaddr;
|
||||
node.ifa.ifa_ifu = std::ptr::null_mut();
|
||||
node.ifa.ifa_netmask = std::ptr::null_mut();
|
||||
node.ifa.ifa_flags = (libc::IFF_UP | libc::IFF_RUNNING) as c_uint;
|
||||
|
||||
let raw = Box::into_raw(node);
|
||||
if head.is_null() {
|
||||
head = raw;
|
||||
} else {
|
||||
(*tail).next = raw;
|
||||
(*tail).ifa.ifa_next = raw as *mut ifaddrs;
|
||||
}
|
||||
tail = raw;
|
||||
}
|
||||
|
||||
*addrs = if head.is_null() {
|
||||
std::ptr::null_mut()
|
||||
} else {
|
||||
head as *mut ifaddrs
|
||||
};
|
||||
0
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn freeifaddrs(addrs: *mut ifaddrs) {
|
||||
let mut current = addrs as *mut AddrNode;
|
||||
while !current.is_null() {
|
||||
let next = (*current).next;
|
||||
drop(Box::from_raw(current));
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
@@ -5,16 +5,13 @@ use serde::{Deserialize, Serialize};
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum PlatformMode {
|
||||
AndroidAmlogic,
|
||||
Linux,
|
||||
Windows,
|
||||
}
|
||||
|
||||
impl PlatformMode {
|
||||
pub const fn current() -> Self {
|
||||
if cfg!(feature = "android") {
|
||||
Self::AndroidAmlogic
|
||||
} else if cfg!(windows) {
|
||||
if cfg!(windows) {
|
||||
Self::Windows
|
||||
} else {
|
||||
Self::Linux
|
||||
@@ -23,7 +20,6 @@ impl PlatformMode {
|
||||
|
||||
pub const fn label(self) -> &'static str {
|
||||
match self {
|
||||
Self::AndroidAmlogic => "Android Amlogic",
|
||||
Self::Linux => "Linux",
|
||||
Self::Windows => "Windows",
|
||||
}
|
||||
@@ -86,15 +82,11 @@ pub struct PlatformCapabilities {
|
||||
|
||||
impl PlatformCapabilities {
|
||||
pub fn current() -> Self {
|
||||
#[cfg(feature = "android")]
|
||||
{
|
||||
return crate::platform::android::capabilities();
|
||||
}
|
||||
#[cfg(windows)]
|
||||
{
|
||||
return crate::platform::windows::capabilities();
|
||||
}
|
||||
#[cfg(all(unix, not(feature = "android")))]
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
return crate::platform::linux::capabilities();
|
||||
}
|
||||
|
||||
@@ -1,72 +1,21 @@
|
||||
use crate::config::AppConfig;
|
||||
#[cfg(windows)]
|
||||
use crate::config::AtxDriverType;
|
||||
#[cfg(any(windows, all(unix, feature = "android")))]
|
||||
#[cfg(windows)]
|
||||
use crate::config::HidBackend;
|
||||
|
||||
pub fn apply(config: &mut AppConfig) {
|
||||
#[cfg(not(any(windows, all(unix, feature = "android"))))]
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
let _ = config;
|
||||
}
|
||||
|
||||
#[cfg(all(unix, feature = "android"))]
|
||||
{
|
||||
apply_android(config);
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
apply_windows(config);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(unix, feature = "android"))]
|
||||
fn apply_android(config: &mut AppConfig) {
|
||||
let detected_udc = crate::otg::configfs::find_udc();
|
||||
if config
|
||||
.hid
|
||||
.otg_udc
|
||||
.as_deref()
|
||||
.map(str::trim)
|
||||
.unwrap_or("")
|
||||
.is_empty()
|
||||
{
|
||||
config.hid.otg_udc = detected_udc;
|
||||
}
|
||||
|
||||
let otg_available = config.hid.otg_udc.is_some();
|
||||
if !config.initialized && otg_available {
|
||||
config.hid.backend = HidBackend::Otg;
|
||||
} else if config.hid.backend == HidBackend::Ch9329
|
||||
&& config.hid.ch9329_port == "/dev/ttyUSB0"
|
||||
&& !std::path::Path::new(&config.hid.ch9329_port).exists()
|
||||
&& otg_available
|
||||
{
|
||||
config.hid.backend = HidBackend::Otg;
|
||||
}
|
||||
|
||||
if !config.initialized {
|
||||
config.audio.enabled = false;
|
||||
config.audio.device.clear();
|
||||
config.atx.enabled = false;
|
||||
config.rustdesk.enabled = false;
|
||||
config.rtsp.enabled = false;
|
||||
config.redfish.enabled = false;
|
||||
}
|
||||
|
||||
config
|
||||
.video
|
||||
.device
|
||||
.get_or_insert_with(|| "auto".to_string());
|
||||
config
|
||||
.video
|
||||
.format
|
||||
.get_or_insert_with(|| "MJPEG".to_string());
|
||||
config.web.bind_address = "0.0.0.0".to_string();
|
||||
config.web.bind_addresses = vec!["0.0.0.0".to_string()];
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn apply_windows(config: &mut AppConfig) {
|
||||
config.msd.enabled = false;
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
//! Platform selection and capability reporting.
|
||||
|
||||
#[cfg(feature = "android")]
|
||||
pub mod android;
|
||||
#[cfg(feature = "android")]
|
||||
pub mod android_bionic;
|
||||
pub mod capabilities;
|
||||
pub mod defaults;
|
||||
#[cfg(target_os = "linux")]
|
||||
|
||||
Reference in New Issue
Block a user