feat: Linux 真实实现层 — 从存根库变为可用生产力工具

新增 _linux_impl.py (800+行):
- LinuxNetwork: 真实IP/接口/DNS/网关/MAC (ip命令+/proc/net)
- LinuxBluetooth: 真实蓝牙状态/扫描/配对/连接 (bluetoothctl)
- LinuxSensors: 真实温度/CPU频率/风扇 (/sys/class/hwmon)
- LinuxAudio: 真实音量控制/静音 (amixer)
- LinuxClipboard: 真实剪贴板读写 (xclip+tkinter回退)
- LinuxPower: 真实CPU/内存/电池 (psutil+/sys/class/power_supply)
- LinuxLocation: 真实IP地理定位 (ip-api.com)
- LinuxNotify: 真实桌面通知 (notify-send)
- LinuxDisplay: 真实屏幕尺寸/截屏/鼠标位置 (xdotool+X11)
- LinuxUIAutomation: 真实点击/输入/按键/滚动 (xdotool)
- LinuxCamera: 真实摄像头拍照 (opencv/V4L2)
- LinuxProcess: 真实进程列表/系统信息/应用管理 (psutil+/proc)
- LinuxShell: 真实命令执行 (subprocess)

改造10+核心类使用Linux真实实现:
- BluetoothAdapter/SensorManager/AudioManager
- ConnectivityManager/WifiManager/TelephonyManager
- LocationManager/PowerManager/BatteryManager/Build
- ActivityManager/Activity/Toast/Display/ClipboardManager
- NotificationManager

15项真实行为测试全部通过:
- 真实IP: 10.60.218.244
- 真实位置: 北京 39.9042, 116.407
- 真实主机名: work-41-vci-g427c
- 真实内核: 5.15.120.byteatom-ck.14
- 真实内存: 1.8GB/3.8GB
- 真实进程列表
This commit is contained in:
shuiyu1123 committed 2026-06-24 15:40:49 +00:00
1 parent 8c3bd3c415
commit 690022cea3
17 files changed
+2083 -8

No files matched your search

+95
View File
@@ -17,6 +17,13 @@ from .._core import (
_sdcard_root, _app_data_dir, _package_name,
)
# Linux 真实实现导入
try:
from .._linux_impl import IS_LINUX, LinuxNetwork, HAS_IP
_USE_LINUX = IS_LINUX
except ImportError:
_USE_LINUX = False
# ═══════════════════════════════════════════════════════════════
# Uri (re-export from content)
@@ -379,6 +386,38 @@ class NetworkInfo(Stub):
}
return names.get(type_, "UNKNOWN")
@classmethod
def from_linux_data(cls, data: Optional[dict] = None,
network_type: int = 9) -> "NetworkInfo":
"""从 Linux 真实网络数据构造 NetworkInfo
data 字典可包含: ip, interface, connected, type_name 等
"""
if data is None:
data = {}
connected = bool(data.get("connected", False))
state = "CONNECTED" if connected else "DISCONNECTED"
detailed_state = "CONNECTED" if connected else "DISCONNECTED"
type_name = data.get("type_name") or cls._default_type_name_static(network_type)
extra_info = data.get("ip") or data.get("interface")
return cls(
type_=network_type,
state=state,
detailed_state=detailed_state,
type_name=type_name,
extra_info=extra_info,
is_available=True,
roaming=False,
)
@staticmethod
def _default_type_name_static(type_: int) -> str:
names = {
0: "MOBILE", 1: "WIFI", 6: "WIMAX", 7: "BLUETOOTH",
9: "ETHERNET", 17: "VPN",
}
return names.get(type_, "UNKNOWN")
def getType(self) -> int:
return self._type
@@ -1230,15 +1269,71 @@ class ConnectivityManager(Stub):
self._network_caps: Dict[int, NetworkCapabilities] = {}
self._link_props: Dict[int, LinkProperties] = {}
def _get_linux_active_info(self) -> Optional[NetworkInfo]:
"""从 Linux 真实网络信息构造活跃 NetworkInfo"""
try:
interfaces = LinuxNetwork.get_interfaces()
# 有真实网络接口 (非环回) 且 operstate=up 即视为已连接
connected = any(
(iface.get("ifname") or iface.get("name", "")) != "lo"
and iface.get("operstate", "").lower() == "up"
for iface in interfaces
)
# 若有活跃接口但 get_connectivity 为 False (外网不可达), 仍视为已连接
if not connected:
connected = LinuxNetwork.get_connectivity()
ip = LinuxNetwork.get_ip_address()
iface_name = ""
for iface in interfaces:
name = iface.get("ifname") or iface.get("name", "")
state = iface.get("operstate", "")
if name and name != "lo" and state.lower() == "up":
iface_name = name
break
# 判断网络类型 (无线接口 -> WIFI, 否则 ETHERNET)
net_type = self.TYPE_ETHERNET
for iface in interfaces:
name = iface.get("ifname") or iface.get("name", "")
if name and name.startswith(("wl", "wlan", "wlp")):
net_type = self.TYPE_WIFI
iface_name = iface_name or name
break
data = {
"connected": connected,
"ip": ip,
"interface": iface_name,
"type_name": "WIFI" if net_type == self.TYPE_WIFI else "ETHERNET",
}
return NetworkInfo.from_linux_data(data, network_type=net_type)
except Exception:
return self._active_network_info
def getActiveNetworkInfo(self) -> Optional[NetworkInfo]:
if _USE_LINUX:
return self._get_linux_active_info()
return self._active_network_info
def getNetworkInfo(self, network_type: int) -> Optional[NetworkInfo]:
if _USE_LINUX:
info = self._get_linux_active_info()
if info is not None and info.getType() == network_type:
return info
# 请求的类型与活跃网络不同时, 返回断开状态
return NetworkInfo(
type_=network_type, state="DISCONNECTED",
detailed_state="DISCONNECTED", is_available=False,
)
network = self._networks.get(network_type)
if network:
return NetworkInfo(type_=network_type, state="CONNECTED", is_available=True)
return self._active_network_info
def getConnectivityStatus(self) -> bool:
"""返回当前网络连通性 (True=已连接)"""
if _USE_LINUX:
return LinuxNetwork.get_connectivity()
return True
def getNetworkInfoForUid(self, network: Network, uid: int) -> Optional[NetworkInfo]:
return self._active_network_info