""" Android Device Administration API — DevicePolicyManager, DeviceAdminInfo, DeviceAdminReceiver, SystemUpdatePolicy 方法签名完全对齐 Android SDK """ import os as _os import sys import tempfile import shutil from typing import Any, Dict, List, Optional, Tuple, Callable from .._core import Stub, AndroidOnlyError from ..java.lang import RuntimeException IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {}) __all__ = [ "DevicePolicyManager", "DeviceAdminInfo", "DeviceAdminReceiver", "SystemUpdatePolicy", ] # ═══════════════════════════════════════════════════════════════ # DevicePolicyManager 常量 # ═══════════════════════════════════════════════════════════════ class DevicePolicyManager(Stub): """DevicePolicyManager — 设备策略管理器 (桌面存根)""" # --- Action 常量 --- ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN" ACTION_DEVICE_ADMIN_SET_DOWNLOAD_URL = "android.app.action.DEVICE_ADMIN_SET_DOWNLOAD_URL" ACTION_ADMIN_POLICY_COMPLIANCE = "android.app.action.ADMIN_POLICY_COMPLIANCE" ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.PROVISION_MANAGED_PROFILE" ACTION_PROVISION_FINANCED_DEVICE = "android.app.action.PROVISION_FINANCED_DEVICE" ACTION_STATE_USER_SETUP_COMPLETE = "android.app.action.STATE_USER_SETUP_COMPLETE" ACTION_DEVICE_OWNER_CHANGED = "android.app.action.DEVICE_OWNER_CHANGED" ACTION_PROFILE_OWNER_CHANGED = "android.app.action.PROFILE_OWNER_CHANGED" ACTION_SET_NEW_PARENT_PROFILE_PASSWORD = "android.app.action.SET_NEW_PARENT_PROFILE_PASSWORD" ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD" ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION" ACTION_SYSTEM_UPDATE_POLICY_CHANGED = "android.app.action.SYSTEM_UPDATE_POLICY_CHANGED" ACTION_APPLICATION_VERB = "android.app.action.APPLICATION_VERB" ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED" ACTION_ORG_OWNED_PROVISIONING = "android.app.action.ORG_OWNED_PROVISIONING" ACTION_GET_PROVISIONING_MODE = "android.app.action.GET_PROVISIONING_MODE" ACTION_ADMIN_SERVICE = "android.app.action.ADMIN_SERVICE" # --- Password quality constants --- PASSWORD_QUALITY_UNSPECIFIED = 0 PASSWORD_QUALITY_BIOMETRIC_WEAK = 0x8000 PASSWORD_QUALITY_SOMETHING = 0x10000 PASSWORD_QUALITY_NUMERIC = 0x20000 PASSWORD_QUALITY_NUMERIC_COMPLEX = 0x30000 PASSWORD_QUALITY_ALPHABETIC = 0x40000 PASSWORD_QUALITY_ALPHANUMERIC = 0x50000 PASSWORD_QUALITY_COMPLEX = 0x60000 PASSWORD_QUALITY_MANAGED = 0x80000 # --- Encryption status --- ENCRYPTION_STATUS_UNSUPPORTED = 0 ENCRYPTION_STATUS_INACTIVE = 1 ENCRYPTION_STATUS_ACTIVATING = 2 ENCRYPTION_STATUS_ACTIVE = 3 ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY = 4 # --- Keyguard disable flags --- KEYGUARD_DISABLE_FEATURES_NONE = 0 KEYGUARD_DISABLE_FEATURES_ALL = 0x7FFFFFFF KEYGUARD_DISABLE_SECURE_CAMERA = 2 KEYGUARD_DISABLE_SECURE_NOTIFICATIONS = 4 KEYGUARD_DISABLE_TRUST_AGENTS = 8 KEYGUARD_DISABLE_FINGERPRINT = 16 KEYGUARD_DISABLE_REMOTE_INPUT = 32 KEYGUARD_DISABLE_FACE = 64 KEYGUARD_DISABLE_IRIS = 128 KEYGUARD_DISABLE_PASSCODE = 256 # --- Lock screen info flags --- FLAG_EVOLVING_DEVICE_ADMIN = 1 << 0 FLAG_PARENT_CAN_ACCESS_LOCK_SCREEN = 1 << 1 FLAG_SELF_PROFILE_DISABLED = 1 << 2 # --- Other constants --- PERMISSION_GRANT_STATE_DEFAULT = 0 PERMISSION_GRANT_STATE_GRANTED = 1 PERMISSION_GRANT_STATE_DENIED = 2 STATE_USER_SETUP_COMPLETE = 1 STATE_USER_UNMANAGED = 0 STATE_USER_MANAGED = 2 LEAVE_ALL_KEYS = 0xFFFFFFFF WIPE_EXTERNAL_STORAGE = 1 WIPE_RESET_PROTECTION_DATA = 2 WIPE_SILENTLY = 4 SKIP_SETUP_WIZARD = 1 SETTINGS_HOME = "settings_home" SETTINGS_GLOBAL = "settings_global" SETTINGS_SECURE = "settings_secure" SETTINGS_SYSTEM = "settings_system" LOCK_TASK_FEATURE_NONE = 0 LOCK_TASK_FEATURE_SYSTEM_INFO = 1 LOCK_TASK_FEATURE_KEYGUARD = 2 LOCK_TASK_FEATURE_HOME = 4 LOCK_TASK_FEATURE_GLOBAL_ACTIONS = 8 LOCK_TASK_FEATURE_NOTIFICATIONS = 16 LOCK_TASK_FEATURE_OVERVIEW = 32 LOCK_TASK_FEATURE_CREDENTIALS = 64 LOCK_TASK_FEATURE_ACCESSIBILITY = 128 LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START = 256 def __init__(self): super().__init__() self._active_admins: List[Dict[str, Any]] = [] self._password_quality = self.PASSWORD_QUALITY_UNSPECIFIED self._camera_disabled = False self._keyguard_disabled = False def isAdminActive(self, admin: "DeviceAdminInfo") -> bool: """检查设备管理器是否已激活""" return any(a.getComponent() == admin.getComponent() for a in self._active_admins) def isDeviceOwnerApp(self, packageName: str) -> bool: """检查应用是否为设备所有者""" return False def isProfileOwnerApp(self, packageName: str) -> bool: """检查应用是否为配置文件所有者""" return False def resetPassword(self, password: str, flags: int = 0) -> bool: """重置设备密码 (桌面存根)""" raise AndroidOnlyError("DevicePolicyManager.resetPassword() 仅在 Android 设备上可用") def lockNow(self): """立即锁定设备""" raise AndroidOnlyError("DevicePolicyManager.lockNow() 仅在 Android 设备上可用") def wipeData(self, flags: int = 0): """擦除设备数据""" raise AndroidOnlyError("DevicePolicyManager.wipeData() 仅在 Android 设备上可用") def setCameraDisabled(self, admin: "DeviceAdminInfo", disabled: bool): """设置相机禁用状态""" self._camera_disabled = disabled def setKeyguardDisabled(self, admin: "DeviceAdminInfo", disabled: bool) -> bool: """设置锁屏禁用状态""" self._keyguard_disabled = disabled return True def installCaCert(self, admin: "DeviceAdminInfo", certBuffer: bytes) -> bool: """安装 CA 证书 (桌面存根)""" raise AndroidOnlyError("DevicePolicyManager.installCaCert() 仅在 Android 设备上可用") def uninstallCaCert(self, admin: "DeviceAdminInfo", certBuffer: bytes): """卸载 CA 证书 (桌面存根)""" raise AndroidOnlyError("DevicePolicyManager.uninstallCaCert() 仅在 Android 设备上可用") def getActiveAdmins(self) -> Optional[List["DeviceAdminInfo"]]: """获取活跃的管理器列表""" return list(self._active_admins) if self._active_admins else None def createAdminProfileInfo( self, packageName: str, localizedName: str, parentComponent: Any = None, adminInfo: Any = None, profileOwner: bool = False, ) -> "DeviceAdminInfo": """创建管理员配置文件信息""" return DeviceAdminInfo( packageName=packageName, localizedName=localizedName, parentComponent=parentComponent, adminInfo=adminInfo, profileOwner=profileOwner, ) def toString(self) -> str: return f"DevicePolicyManager@active_admins={len(self._active_admins)}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return id(self) & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # DeviceAdminInfo # ═══════════════════════════════════════════════════════════════ class DeviceAdminInfo(Stub): """DeviceAdminInfo — 设备管理员信息""" USES_POLICY_WATCH_LOG = "uses_policy_watch_log" USES_POLICY_DISABLE_KEYGUARD_FEATURES = "uses_policy_disable_keyguard_features" USES_POLICY_DISABLE_CAMERA = "uses_policy_disable_camera" USES_POLICY_RESET_PASSWORD = "uses_policy_reset_password" USES_POLICY_FORCE_LOCK = "uses_policy_force_lock" USES_POLICY_WIPE_DATA = "uses_policy_wipe_data" USES_POLICY_EXPIRE_PASSWORD = "uses_policy_expire_password" USES_POLICY_LIMIT_PASSWORD = "uses_policy_limit_password" USES_ENCRYPTED_STORAGE = "uses_encrypted_storage" USES_POLICY_SETS_DEVICE_OWNER = "uses_policy_sets_device_owner" USES_POLICY_SETS_PROFILE_OWNER = "uses_policy_sets_profile_owner" USES_POLICY_INSTALL_CERT = "uses_policy_install_cert" USES_POLICY_UNINSTALL_CERT = "uses_policy_uninstall_cert" def __init__( self, packageName: str = "", localizedName: str = "", parentComponent: Any = None, adminInfo: Any = None, profileOwner: bool = False, ): super().__init__() self._packageName = packageName self._localizedName = localizedName self._parentComponent = parentComponent self._adminInfo = adminInfo self._profileOwner = profileOwner def getComponent(self) -> Optional[str]: """获取组件标识""" return self._parentComponent def getPackageName(self) -> str: return self._packageName def isVisible(self) -> bool: return True def isProfileOwner(self) -> bool: return self._profileOwner def toString(self) -> str: return f"DeviceAdminInfo(package={self._packageName})" def equals(self, other) -> bool: if not isinstance(other, DeviceAdminInfo): return False return self._packageName == other._packageName and self._parentComponent == other._parentComponent def hashCode(self) -> int: return hash(self._packageName) & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # DeviceAdminReceiver # ═══════════════════════════════════════════════════════════════ class DeviceAdminReceiver(Stub): """DeviceAdminReceiver — 设备管理员广播接收器""" ACTION_DEVICE_ADMIN_ENABLED = "android.app.action.DEVICE_ADMIN_ENABLED" ACTION_DEVICE_ADMIN_DISABLED = "android.app.action.DEVICE_ADMIN_DISABLED" ACTION_DEVICE_ADMIN_DISABLE_REQUESTED = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED" ACTION_PASSWORD_CHANGED = "android.app.action.ACTION_PASSWORD_CHANGED" ACTION_PASSWORD_FAILED = "android.app.action.ACTION_PASSWORD_FAILED" ACTION_PASSWORD_SUCCEEDED = "android.app.action.ACTION_PASSWORD_SUCCEEDED" ACTION_PASSWORD_EXPIRING = "android.app.action.ACTION_PASSWORD_EXPIRING" ACTION_PROFILE_PROVISIONING_COMPLETE = "android.app.action.PROFILE_PROVISIONING_COMPLETE" ACTION_BUGREPORT_SHARING_ACCEPTED = "android.app.action.BUGREPORT_SHARING_ACCEPTED" ACTION_BUGREPORT_SHARING_DECLINED = "android.app.action.BUGREPORT_SHARING_DECLINED" ACTION_BUGREPORT_FAILED = "android.app.action.BUGREPORT_FAILED" ACTION_NOTIFY_PENDING_SYSTEM_UPDATE = "android.app.action.NOTIFY_PENDING_SYSTEM_UPDATE" ACTION_CHOOSE_PRIVATE_KEY_ALIAS = "android.app.action.CHOOSE_PRIVATE_KEY_ALIAS" ACTION_NETWORK_LOGS_AVAILABLE = "android.app.action.NETWORK_LOGS_AVAILABLE" ACTION_SECURITY_LOGS_AVAILABLE = "android.app.action.SECURITY_LOGS_AVAILABLE" ACTION_USER_ADDED = "android.app.action.USER_ADDED" ACTION_USER_REMOVED = "android.app.action.USER_REMOVED" ACTION_USER_STARTED = "android.app.action.USER_STARTED" ACTION_USER_STOPPED = "android.app.action.USER_STOPPED" ACTION_USER_SWITCHED = "android.app.action.USER_SWITCHED" ACTION_LOCK_TASK_ENTERING = "android.app.action.LOCK_TASK_ENTERING" ACTION_LOCK_TASK_EXITING = "android.app.action.LOCK_TASK_EXITING" def __init__(self): super().__init__() def onEnabled(self, context: Any, intent: Any): """管理员启用回调""" pass def onDisabled(self, context: Any, intent: Any): """管理员禁用回调""" pass def onPasswordChanged(self, context: Any, intent: Any): """密码更改回调""" pass def onPasswordExpiring(self, context: Any, intent: Any): """密码过期回调""" pass def onPasswordFailed(self, context: Any, intent: Any): """密码失败回调""" pass def onPasswordSucceeded(self, context: Any, intent: Any): """密码成功回调""" pass def onProfileProvisioningComplete(self, context: Any, intent: Any): """配置文件配置完成回调""" pass def onBugreportSharingAccepted(self, context: Any, intent: Any, bugreportHash: bytes): """错误报告分享接受回调""" pass def onBugreportSharingDeclined(self, context: Any, intent: Any): """错误报告分享拒绝回调""" pass def onBugreportFailed(self, context: Any, intent: Any, bugreportHash: bytes): """错误报告失败回调""" pass def onNotifyPendingSystemUpdate(self, context: Any, intent: Any, updateReceivedTime: int): """系统更新待处理通知回调""" pass def onNetworkLogsAvailable(self, context: Any, intent: Any, batchToken: int, networkLogsCount: int): """网络日志可用回调""" pass def onSecurityLogsAvailable(self, context: Any, intent: Any): """安全日志可用回调""" pass def onUserAdded(self, context: Any, intent: Any, newUserHandle: Any): """用户添加回调""" pass def onUserRemoved(self, context: Any, intent: Any, removedUserHandle: Any): """用户移除回调""" pass def onUserStarted(self, context: Any, intent: Any, userHandle: Any): """用户启动回调""" pass def onUserStopped(self, context: Any, intent: Any, userHandle: Any): """用户停止回调""" pass def onUserSwitched(self, context: Any, intent: Any, switchedUserHandle: Any): """用户切换回调""" pass def onLockTaskModeEntering(self, context: Any, intent: Any, pkg: str): """锁任务模式进入回调""" pass def onLockTaskModeExiting(self, context: Any, intent: Any): """锁任务模式退出回调""" pass def toString(self) -> str: return f"DeviceAdminReceiver@{hex(id(self))}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return id(self) & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # SystemUpdatePolicy # ═══════════════════════════════════════════════════════════════ class SystemUpdatePolicy(Stub): """SystemUpdatePolicy — 系统更新策略""" TYPE_INSTALL_AUTOMATIC = 1 TYPE_INSTALL_WINDOWED = 2 TYPE_POSTPONE = 3 def __init__(self, policyType: int = TYPE_INSTALL_AUTOMATIC): super().__init__() self._policyType = policyType self._startTime: Optional[str] = None self._endTime: Optional[str] = None def getPolicyType(self) -> int: return self._policyType def setPolicyType(self, policyType: int): self._policyType = policyType def setInstallWindow(self, startTime: str, endTime: str): """设置安装窗口时间段 (格式 HH:mm)""" self._startTime = startTime self._endTime = endTime def getStartTime(self) -> Optional[str]: return self._startTime def getEndTime(self) -> Optional[str]: return self._endTime @staticmethod def createPolicy(policyType: int) -> "SystemUpdatePolicy": return SystemUpdatePolicy(policyType=policyType) def toString(self) -> str: return f"SystemUpdatePolicy(type={self._policyType})" def equals(self, other) -> bool: if not isinstance(other, SystemUpdatePolicy): return False return self._policyType == other._policyType def hashCode(self) -> int: return self._policyType & 0x7FFFFFFF