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