feat: 新增 42 个 Android API 模块

新增模块覆盖:
系统层 (14): system, security, print, opengl, renderscript, transition,
test, service_notification, service_controls, service_quicksettings,
service_wallpaper, service_autofill, service_dreams, service_vr

应用层 (13): app_admin, app_backup, app_job, app_usage, app_role,
app_people, appwidget, companion, credentials, mtp, sip, telecom, speech

硬件媒体层 (15): hardware_display, hardware_fingerprint, hardware_usb,
hardware_input, media_audiofx, media_browse, media_session, media_tv,
media_midi, media_projection, uwb, se, view_autofill, view_textclassifier,
view_translation

总计 94 个模块,75,342 行代码
This commit is contained in:
shuiyu1123 committed 2026-06-24 12:00:28 +00:00
1 parent 8ad62be068
commit 506f9ac725
43 files changed
+16704 -23

No files matched your search

+175
View File
@@ -0,0 +1,175 @@
"""
Android se 组件 — SecureElement, Session, Channel, Reader, OmapiConnection 等
方法签名完全对齐 Android SDK (SecureElement API)
"""
from typing import Any, Callable, Dict, List, Optional
from .._core import Stub, AndroidOnlyError
# ═══════════════════════════════════════════════════════════════
# SecureElement
# ═══════════════════════════════════════════════════════════════
class SecureElement(Stub):
"""SecureElement — 安全元件"""
SERVICE_INTERFACE = "android.se.SECURE_ELEMENT_SERVICE"
EXTRA_READER = "android.se.extra.READER"
EXTRA_READER_NAME = "android.se.extra.READER_NAME"
EXTRA_SLOT_ID = "android.se.extra.SLOT_ID"
EXTRA_CONNECT_RESPONSE = "android.se.extra.CONNECT_RESPONSE"
def __init__(self):
super().__init__()
# ═══════════════════════════════════════════════════════════════
# Reader
# ═══════════════════════════════════════════════════════════════
class Reader(Stub):
"""Reader — 安全元件读取器"""
def __init__(self, name: str = "eSE"):
super().__init__()
self._name = name
self._sessions: List[Session] = []
def getName(self) -> str:
return self._name
def openSession(self) -> "Session":
session = Session(self)
self._sessions.append(session)
return session
def closeSessions(self):
for s in self._sessions:
s.close()
self._sessions.clear()
def isSecureElementPresent(self) -> bool:
return True
def toString(self) -> str:
return f"Reader(name={self._name})"
# ═══════════════════════════════════════════════════════════════
# Session
# ═══════════════════════════════════════════════════════════════
class Session(Stub):
"""Session — 安全元件会话"""
def __init__(self, reader: Optional[Reader] = None):
super().__init__()
self._reader = reader
self._channels: List[Channel] = []
self._closed = False
def openLogicalChannel(self, aid: bytes) -> Optional["Channel"]:
if self._closed:
return None
channel = Channel(self, logical=True)
self._channels.append(channel)
channel._select_response = bytes([0x90, 0x00]) # SW_OK
return channel
def openBasicChannel(self, aid: bytes) -> Optional["Channel"]:
if self._closed:
return None
channel = Channel(self, logical=False)
self._channels.append(channel)
channel._select_response = bytes([0x90, 0x00]) # SW_OK
return channel
def close(self):
for c in self._channels:
c.close()
self._channels.clear()
self._closed = True
def getSessions(self) -> List["Session"]:
return [self]
def getChannels(self) -> List["Channel"]:
return list(self._channels)
def toString(self) -> str:
return f"Session(reader={self._reader}, channels={len(self._channels)})"
# ═══════════════════════════════════════════════════════════════
# Channel
# ═══════════════════════════════════════════════════════════════
class Channel(Stub):
"""Channel — 安全元件通道"""
def __init__(self, session: Session, logical: bool = True):
super().__init__()
self._session = session
self._logical = logical
self._closed = False
self._select_response: Optional[bytes] = None
def close(self):
self._closed = True
def sendData(self, command: bytes) -> bytes:
if self._closed:
return bytes([0x6F, 0x00]) # No such EF
# Simulate successful APDU response
return bytes([0x90, 0x00])
def getSelectResponse(self) -> Optional[bytes]:
return self._select_response
def getSession(self) -> Session:
return self._session
def isBasicChannel(self) -> bool:
return not self._logical
def isClosed(self) -> bool:
return self._closed
def toString(self) -> str:
return f"Channel(logical={self._logical}, closed={self._closed})"
# ═══════════════════════════════════════════════════════════════
# OmapiConnection
# ═══════════════════════════════════════════════════════════════
class OmapiConnection(Stub):
"""OmapiConnection — OMAPI 连接入口"""
def __init__(self):
super().__init__()
@staticmethod
def getInstance(context: Any = None) -> "OmapiConnection":
return OmapiConnection()
def getReaders(self) -> List[Reader]:
return [Reader("eSE")]
def getReader(self, name: str) -> Optional[Reader]:
return Reader(name)
# ═══════════════════════════════════════════════════════════════
# __all__
# ═══════════════════════════════════════════════════════════════
__all__ = [
"SecureElement",
"Reader",
"Session",
"Channel",
"OmapiConnection",
]