""" Android Biometrics 组件 — BiometricManager, BiometricPrompt, 等 方法签名完全对齐 Android SDK """ from typing import Any, Callable, Dict, List, Optional, Tuple from .._core import Stub, AndroidOnlyError, android_context # ═══════════════════════════════════════════════════════════════ # BiometricConstants # ═══════════════════════════════════════════════════════════════ class BiometricConstants(Stub): """BiometricConstants — 生物识别常量""" BIOMETRIC_SUCCESS = 0 BIOMETRIC_ERROR_HW_UNAVAILABLE = 1 BIOMETRIC_ERROR_VENDOR = 8 BIOMETRIC_ERROR_LOCKOUT = 7 BIOMETRIC_ERROR_LOCKOUT_PERMANENT = 9 BIOMETRIC_ERROR_USER_CANCELED = 10 BIOMETRIC_ERROR_NO_BIOMETRIC = 11 BIOMETRIC_ERROR_HW_NOT_PRESENT = 12 BIOMETRIC_ERROR_NEGATIVE_BUTTON = 13 BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14 BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = 15 BIOMETRIC_ERROR_UNSUPPORTED = 65536 BIOMETRIC_ERROR_CANCELED = 5 BIOMETRIC_ERROR_TIMEOUT = 3 BIOMETRIC_ERROR_NONE_ENROLLED = 11 BIOMETRIC_ERROR_NO_HARDWARE = 12 BIOMETRIC_STATUS_OK = 0 # Authenticator types BIOMETRIC_STRONG = 0x0F BIOMETRIC_WEAK = 0xFF DEVICE_CREDENTIAL = 0x8000 # ═══════════════════════════════════════════════════════════════ # BiometricPrompt # ═══════════════════════════════════════════════════════════════ class BiometricPrompt(Stub): """BiometricPrompt — 生物识别提示 (API 28+)""" class AuthenticationCallback(Stub): """BiometricPrompt.AuthenticationCallback — 认证回调""" def onAuthenticationError(self, errorCode: int, errString: str): pass def onAuthenticationSucceeded(self, result: "BiometricPrompt.AuthenticationResult"): pass def onAuthenticationFailed(self): pass def onAuthenticationAcquired(self, acquireInfo: int): pass class AuthenticationResult(Stub): """BiometricPrompt.AuthenticationResult — 认证结果""" def __init__(self, cryptoObject: "BiometricPromptCryptoObject" = None, authenticationType: int = BiometricConstants.BIOMETRIC_STRONG): super().__init__() self._crypto_object = cryptoObject self._authentication_type = authenticationType def getCryptoObject(self) -> Optional["BiometricPromptCryptoObject"]: return self._crypto_object def getAuthenticationType(self) -> int: return self._authentication_type class PromptInfo(Stub): """BiometricPrompt.PromptInfo — 提示信息""" class Builder(Stub): """BiometricPrompt.PromptInfo.Builder — 提示信息构建器""" def __init__(self): super().__init__() self._title = "" self._subtitle = "" self._description = "" self._device_credential_allowed = False self._allowed_authenticators = 0 self._confirmation_required = True self._negative_button_text = "" def setTitle(self, title: str) -> "BiometricPrompt.PromptInfo.Builder": self._title = title return self def setSubtitle(self, subtitle: str) -> "BiometricPrompt.PromptInfo.Builder": self._subtitle = subtitle return self def setDescription(self, description: str) -> "BiometricPrompt.PromptInfo.Builder": self._description = description return self def setDeviceCredentialAllowed(self, allowed: bool) -> "BiometricPrompt.PromptInfo.Builder": self._device_credential_allowed = allowed return self def setAllowedAuthenticators(self, authenticators: int) -> "BiometricPrompt.PromptInfo.Builder": self._allowed_authenticators = authenticators return self def setConfirmationRequired(self, required: bool) -> "BiometricPrompt.PromptInfo.Builder": self._confirmation_required = required return self def setNegativeButtonText(self, text: str) -> "BiometricPrompt.PromptInfo.Builder": self._negative_button_text = text return self def build(self) -> "BiometricPrompt.PromptInfo": info = BiometricPrompt.PromptInfo() info._title = self._title info._subtitle = self._subtitle info._description = self._description info._device_credential_allowed = self._device_credential_allowed info._allowed_authenticators = self._allowed_authenticators info._confirmation_required = self._confirmation_required info._negative_button_text = self._negative_button_text return info def __init__(self): super().__init__() self._title = "" self._subtitle = "" self._description = "" self._device_credential_allowed = False self._allowed_authenticators = 0 self._confirmation_required = True self._negative_button_text = "" def getTitle(self) -> str: return self._title def getSubtitle(self) -> str: return self._subtitle def getDescription(self) -> str: return self._description def isDeviceCredentialAllowed(self) -> bool: return self._device_credential_allowed def getAllowedAuthenticators(self) -> int: return self._allowed_authenticators def isConfirmationRequired(self) -> bool: return self._confirmation_required def getNegativeButtonText(self) -> str: return self._negative_button_text def __init__(self, context, callback: AuthenticationCallback = None, handler=None): super().__init__() self._context = context self._callback = callback self._cancelled = False def authenticate(self, crypto: "BiometricPromptCryptoObject" = None, cancel: Any = None, executor=None, callback: AuthenticationCallback = None): self._cancelled = False if callback: self._callback = callback if self._callback: # Simulate failed authentication on desktop self._callback.onAuthenticationError( BiometricConstants.BIOMETRIC_ERROR_NO_HARDWARE, "No biometric hardware available on this device" ) def authenticate(self, promptInfo: PromptInfo, crypto: "BiometricPromptCryptoObject" = None): self._cancelled = False if self._callback: self._callback.onAuthenticationError( BiometricConstants.BIOMETRIC_ERROR_NO_HARDWARE, "No biometric hardware available on this device" ) def cancelAuthentication(self): self._cancelled = True if self._callback: self._callback.onAuthenticationError( BiometricConstants.BIOMETRIC_ERROR_CANCELED, "Authentication cancelled" ) def cancel(self): self.cancelAuthentication() def isCancelled(self) -> bool: return self._cancelled # ═══════════════════════════════════════════════════════════════ # BiometricPromptCryptoObject # ═══════════════════════════════════════════════════════════════ class BiometricPromptCryptoObject(Stub): """BiometricPromptCryptoObject — 加密对象""" def __init__(self, signature=None, cipher=None, mac=None): super().__init__() self._signature = signature self._cipher = cipher self._mac = mac def getSignature(self): return self._signature def getCipher(self): return self._cipher def getMac(self): return self._mac # ═══════════════════════════════════════════════════════════════ # BiometricPromptAuthenticationResult # ═══════════════════════════════════════════════════════════════ BiometricPromptAuthenticationResult = BiometricPrompt.AuthenticationResult # ═══════════════════════════════════════════════════════════════ # BiometricManager # ═══════════════════════════════════════════════════════════════ class BiometricManager(Stub): """BiometricManager — 生物识别管理器 (API 29+)""" BIOMETRIC_SUCCESS = BiometricConstants.BIOMETRIC_SUCCESS BIOMETRIC_ERROR_HW_UNAVAILABLE = BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE BIOMETRIC_ERROR_NONE_ENROLLED = BiometricConstants.BIOMETRIC_ERROR_NONE_ENROLLED BIOMETRIC_ERROR_NO_HARDWARE = BiometricConstants.BIOMETRIC_ERROR_NO_HARDWARE BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = BiometricConstants.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED BIOMETRIC_ERROR_UNSUPPORTED = BiometricConstants.BIOMETRIC_ERROR_UNSUPPORTED BIOMETRIC_STATUS_OK = BiometricConstants.BIOMETRIC_STATUS_OK BIOMETRIC_ERROR_VENDOR = BiometricConstants.BIOMETRIC_ERROR_VENDOR BIOMETRIC_ERROR_USER_CANCELED = BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED BIOMETRIC_ERROR_CANCELED = BiometricConstants.BIOMETRIC_ERROR_CANCELED BIOMETRIC_ERROR_TIMEOUT = BiometricConstants.BIOMETRIC_ERROR_TIMEOUT BIOMETRIC_ERROR_LOCKOUT = BiometricConstants.BIOMETRIC_ERROR_LOCKOUT BIOMETRIC_ERROR_LOCKOUT_PERMANENT = BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT # Authenticators AUTHENTICATOR_BIOMETRIC_STRONG = BiometricConstants.BIOMETRIC_STRONG AUTHENTICATOR_BIOMETRIC_WEAK = BiometricConstants.BIOMETRIC_WEAK AUTHENTICATOR_DEVICE_CREDENTIAL = BiometricConstants.DEVICE_CREDENTIAL def __init__(self, context=None): super().__init__() self._context = context def canAuthenticate(self, authenticators: int = AUTHENTICATOR_BIOMETRIC_STRONG) -> int: """Check if biometric authentication is available""" return BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE @staticmethod def fromContext(context) -> "BiometricManager": """Get BiometricManager from context""" return BiometricManager(context) def toString(self) -> str: return "BiometricManager(desktop - no hardware)" # ═══════════════════════════════════════════════════════════════ # __all__ # ═══════════════════════════════════════════════════════════════ __all__ = [ "BiometricManager", "BiometricPrompt", "BiometricPromptAuthenticationResult", "BiometricPromptCryptoObject", "BiometricConstants", ]