feat: 第三轮深度完善 — SQLite/JSON/网络/媒体/文本 真实实现

SQLite真实数据库:
- SQLiteDatabase: execSQL/insert/insertOrThrow/replace/update/delete/query 用sqlite3
- 修复getVersion/setVersion用PRAGMA user_version
- 修复getMaximumSize/getPageSize/setMaximumSize/setPageSize用PRAGMA
- SQLiteStatement: execute/simpleQueryForLong/simpleQueryForString/execQuery
- SQLiteOpenHelper: onCreate/onUpgrade/onDowngrade回调正确触发
- 修复SQLiteCursor.moveToPosition越界处理
- 修复ContentValues值对提取bug

JSON真实实现:
- JSONObject: isNull/append/putOnce/putOpt/getNames
- JSONArray: 完整put/get/opt/length/toString

网络真实实现:
- NetworkInterface: getByName/getNetworkInterfaces/getHardwareAddress 用/sys/class/net+fcntl.ioctl
- InterfaceAddress: 新增类
- ConnectivityManager: getActiveNetwork/getAllNetworks 用LinuxNetwork
- WifiManager: getScanResults用nmcli, setWifiEnabled用nmcli/rfkill
- BluetoothAdapter: getAddress/getName 用bluetoothctl

媒体真实实现:
- MediaPlayer: prepare检查文件, getCurrentPosition实时计算, getDuration/getVideoWidth用ffprobe
- MediaRecorder: setVideoSize/setVideoFrameRate/setVideoEncodingBitRate配置存储
- MediaMetadataRetriever: extractMetadata用ffprobe, getFrameAtTime用ffmpeg, getEmbeddedPicture用ffmpeg

文本真实实现:
- TextUtils: split用re.split, concat/indexOf/lastIndexOf/urlEncode/urlDecode
- SpannableString: setSpan/getSpans/getSpanFlags/nextSpanTransition 真实实现
- SpannableStringBuilder: 修复append重载bug

Provider增强:
- Settings: putBoolean/getBoolean
- MediaStore: getContentUri/VOLUME常量
- ContactsContract: 补全常量和CommonDataKinds

Util增强:
- Log: w/e/wtf支持Throwable参数, 修复wtf重复定义bug
- TypedValue: 修复complexToDimension/complexToFloat/getFloat实现

修复:
- __init__.py: 补全NetworkInterface/InetAddress/MediaMetadataRetriever/SpannableStringBuilder导出

统计: 221模块, 3666类, 31005方法, 183529行
This commit is contained in:
shuiyu1123 committed 2026-06-25 00:40:59 +00:00
1 parent 4235f8692c
commit fbb8263b13
13 files changed
+1373 -146

No files matched your search

+200 -23
View File
@@ -24,7 +24,7 @@ __all__ = [
"InetAddress", "InetSocketAddress",
"Socket", "ServerSocket", "DatagramSocket", "DatagramPacket",
"Proxy", "ProxySelector", "Authenticator", "PasswordAuthentication",
"NetworkInterface", "URI",
"NetworkInterface", "InterfaceAddress", "URI",
"CookieHandler", "CookieManager", "HttpCookie",
"URLDecoder", "URLEncoder",
"SocketException", "ConnectException", "BindException",
@@ -1289,26 +1289,79 @@ class PasswordAuthentication(Stub):
return self._password
# ============================================================
# InterfaceAddress
# ============================================================
class InterfaceAddress(Stub):
"""java.net.InterfaceAddress — 接口地址信息 (地址/广播/前缀长度)"""
def __init__(self, address=None, broadcast=None, prefix_length=0):
super().__init__()
self._address = address # InetAddress
self._broadcast = broadcast # InetAddress or None
self._prefix_length = prefix_length
def getAddress(self):
return self._address
def getBroadcast(self):
return self._broadcast
def getNetworkPrefixLength(self):
return self._prefix_length
def equals(self, other):
if isinstance(other, InterfaceAddress):
return (self._address == other._address
and self._prefix_length == other._prefix_length)
return False
def hashCode(self):
return hash((repr(self._address), self._prefix_length)) & 0x7FFFFFFF
def toString(self):
addr = self._address.getHostAddress() if self._address else "0.0.0.0"
return f"{addr}/{self._prefix_length}"
# ============================================================
# NetworkInterface
# ============================================================
class NetworkInterface(Stub):
_cache = {}
_initialized = False
def __init__(self, name, display_name, addrs):
super().__init__()
self._name = name
self._display_name = display_name
self._addrs = addrs
self._mac = None # bytes, hardware address
self._mtu = 1500
self._state = "unknown"
self._flags = 0
self._interface_addrs = [] # List[InterfaceAddress]
@staticmethod
def _read_sys_file(path):
try:
with open(path, "r") as f:
return f.read().strip()
except Exception:
return None
@staticmethod
def getByName(name):
if name in NetworkInterface._cache:
return NetworkInterface._cache[name]
if name is None:
return None
NetworkInterface._ensure_init()
return NetworkInterface._cache.get(name)
@staticmethod
def getByInetAddress(addr):
NetworkInterface._ensure_init()
for ni in NetworkInterface._cache.values():
for a in ni._addrs:
if a.equals(addr):
@@ -1317,8 +1370,18 @@ class NetworkInterface(Stub):
@staticmethod
def getNetworkInterfaces():
NetworkInterface._ensure_init()
return list(NetworkInterface._cache.values())
@staticmethod
def _ensure_init():
if not NetworkInterface._initialized:
NetworkInterface._initialized = True
try:
NetworkInterface._init_from_socket()
except Exception:
pass
def getName(self):
return self._name
@@ -1329,25 +1392,25 @@ class NetworkInterface(Stub):
return iter(self._addrs)
def getInterfaceAddresses(self):
return self._addrs
return list(self._interface_addrs)
def isUp(self):
return True
return self._state.lower() == "up" or (self._flags & 0x1) != 0
def isLoopback(self):
return self._name == "lo"
return (self._flags & 0x8) != 0 or self._name == "lo"
def isPointToPoint(self):
return False
return (self._flags & 0x10) != 0
def supportsMulticast(self):
return True
return (self._flags & 0x1000) != 0
def getHardwareAddress(self):
return None
return self._mac
def getMTU(self):
return 1500
return self._mtu
def getSubInterfaces(self):
return iter([])
@@ -1363,25 +1426,139 @@ class NetworkInterface(Stub):
@staticmethod
def _init_from_socket():
import netifaces
for iface_name in netifaces.interfaces():
"""从 /sys/class/net/ 和 socket/fcntl 枚举真实网络接口 (不依赖 netifaces)"""
import os as _os
net_dir = "/sys/class/net"
if not _os.path.isdir(net_dir):
# 非 Linux 环境: 尝试用 socket 获取本机地址
try:
hostname = _socket.gethostname()
addr = InetAddress.getByName(hostname)
ni = NetworkInterface(hostname, hostname, [addr])
NetworkInterface._cache[hostname] = ni
except Exception:
pass
return
# 尝试用 fcntl.ioctl 获取 IPv4 地址/掩码/广播
fcntl_available = True
try:
import fcntl as _fcntl
except ImportError:
fcntl_available = False
for iface_name in _os.listdir(net_dir):
addrs = []
ifaddresses = netifaces.ifaddresses(iface_name)
for family in [netifaces.AF_INET, netifaces.AF_INET6]:
if family in ifaddresses:
for addr_info in ifaddresses[family]:
interface_addrs = []
mac = None
mtu = 1500
state = "unknown"
flags = 0
# --- MAC 地址 ---
mac_str = NetworkInterface._read_sys_file(f"{net_dir}/{iface_name}/address")
if mac_str:
try:
mac = bytes(int(b, 16) for b in mac_str.split(":"))
except Exception:
mac = None
# --- MTU ---
mtu_str = NetworkInterface._read_sys_file(f"{net_dir}/{iface_name}/mtu")
if mtu_str:
try:
mtu = int(mtu_str)
except ValueError:
pass
# --- operstate ---
state = NetworkInterface._read_sys_file(
f"{net_dir}/{iface_name}/operstate") or "unknown"
# --- flags (十六进制字符串, 如 0x1003) ---
flags_str = NetworkInterface._read_sys_file(
f"{net_dir}/{iface_name}/flags")
if flags_str:
try:
flags = int(flags_str, 16)
except ValueError:
pass
# --- IPv4 地址 (fcntl.ioctl) ---
if fcntl_available:
sock = None
try:
sock = _socket.socket(_socket.AF_INET, _socket.SOCK_DGRAM)
packed = _struct.pack('256s', iface_name.encode()[:15])
# SIOCGIFADDR = 0x8915
result = _fcntl.ioctl(sock.fileno(), 0x8915, packed)
ip_raw = result[20:24]
inet_addr = InetAddress(iface_name, bytes(ip_raw))
addrs.append(inet_addr)
# SIOCGIFNETMASK = 0x891b
prefix = 24
try:
result = _fcntl.ioctl(sock.fileno(), 0x891b, packed)
netmask_str = _socket.inet_ntoa(result[20:24])
prefix = sum(bin(int(b)).count('1') for b in netmask_str.split('.'))
except Exception:
pass
# SIOCGIFBRDADDR = 0x8919 (广播地址)
broadcast_addr = None
try:
result = _fcntl.ioctl(sock.fileno(), 0x8919, packed)
bcast_raw = result[20:24]
broadcast_addr = InetAddress(iface_name, bytes(bcast_raw))
except Exception:
pass
interface_addrs.append(InterfaceAddress(
address=inet_addr,
broadcast=broadcast_addr,
prefix_length=prefix
))
except OSError:
pass # 接口没有 IPv4 地址
finally:
if sock is not None:
try:
addr = addr_info["addr"]
if "." in addr:
addrs.append(InetAddress(addr, _socket.inet_pton(_socket.AF_INET, addr)))
else:
addrs.append(InetAddress(addr, _socket.inet_pton(_socket.AF_INET6, addr)))
sock.close()
except Exception:
pass
NetworkInterface._cache[iface_name] = NetworkInterface(iface_name, iface_name, addrs)
# --- IPv6 地址 (/proc/net/if_inet6) ---
try:
with open("/proc/net/if_inet6", "r") as f:
for line in f:
parts = line.split()
if len(parts) >= 6 and parts[5] == iface_name:
hex_addr = parts[0]
raw = bytes.fromhex(hex_addr)
prefix6 = int(parts[2], 16) if parts[2] else 64
inet6_addr = InetAddress(iface_name, raw)
addrs.append(inet6_addr)
interface_addrs.append(InterfaceAddress(
address=inet6_addr,
broadcast=None,
prefix_length=prefix6
))
except Exception:
pass
ni = NetworkInterface(iface_name, iface_name, addrs)
ni._mac = mac
ni._mtu = mtu
ni._state = state
ni._flags = flags
ni._interface_addrs = interface_addrs
NetworkInterface._cache[iface_name] = ni
# 初始化缓存
try:
NetworkInterface._init_from_socket()
NetworkInterface._ensure_init()
except Exception:
pass