新增模块覆盖: 系统层 (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 行代码
175 lines
6.2 KiB
Python
175 lines
6.2 KiB
Python
"""
|
|
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",
|
|
] |