Files
Android-pyApi/android_pyapi/android/managers.py
T
shuiyu1123 690022cea3 feat: Linux 真实实现层 — 从存根库变为可用生产力工具
新增 _linux_impl.py (800+行):
- LinuxNetwork: 真实IP/接口/DNS/网关/MAC (ip命令+/proc/net)
- LinuxBluetooth: 真实蓝牙状态/扫描/配对/连接 (bluetoothctl)
- LinuxSensors: 真实温度/CPU频率/风扇 (/sys/class/hwmon)
- LinuxAudio: 真实音量控制/静音 (amixer)
- LinuxClipboard: 真实剪贴板读写 (xclip+tkinter回退)
- LinuxPower: 真实CPU/内存/电池 (psutil+/sys/class/power_supply)
- LinuxLocation: 真实IP地理定位 (ip-api.com)
- LinuxNotify: 真实桌面通知 (notify-send)
- LinuxDisplay: 真实屏幕尺寸/截屏/鼠标位置 (xdotool+X11)
- LinuxUIAutomation: 真实点击/输入/按键/滚动 (xdotool)
- LinuxCamera: 真实摄像头拍照 (opencv/V4L2)
- LinuxProcess: 真实进程列表/系统信息/应用管理 (psutil+/proc)
- LinuxShell: 真实命令执行 (subprocess)

改造10+核心类使用Linux真实实现:
- BluetoothAdapter/SensorManager/AudioManager
- ConnectivityManager/WifiManager/TelephonyManager
- LocationManager/PowerManager/BatteryManager/Build
- ActivityManager/Activity/Toast/Display/ClipboardManager
- NotificationManager

15项真实行为测试全部通过:
- 真实IP: 10.60.218.244
- 真实位置: 北京 39.9042, 116.407
- 真实主机名: work-41-vci-g427c
- 真实内核: 5.15.120.byteatom-ck.14
- 真实内存: 1.8GB/3.8GB
- 真实进程列表
2026-06-24 15:40:49 +00:00

1773 lines
64 KiB
Python

"""
Android System Manager API — 所有剩余系统 Manager 类集合
方法签名完全对齐 Android SDK
"""
from __future__ import annotations
import os
import sys
import time
import json
import random
import socket
import uuid
import threading
from datetime import datetime, timedelta
from typing import Any, Dict, List, Optional, Set, Tuple, Callable, BinaryIO
from .._core import Stub, AndroidOnlyError, _app_data_dir, _sdcard_root
from ..java.lang import RuntimeException
# Linux 真实实现导入
try:
from .._linux_impl import IS_LINUX, LinuxNetwork, HAS_IP
_USE_LINUX = IS_LINUX
except ImportError:
_USE_LINUX = False
IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {})
# ═══════════════════════════════════════════════════════════════
# 全局常量
# ═══════════════════════════════════════════════════════════════
INVALID_ID = -1
MATCH_ALL = -1
# ═══════════════════════════════════════════════════════════════
# AccessibilityManager
# ═══════════════════════════════════════════════════════════════
class AccessibilityManager(Stub):
"""AccessibilityManager — 无障碍管理器 (桌面存根)"""
FLAG_CONTENT_CONTROLS = 0x00000001
FLAG_CONTENT_ICONS = 0x00000002
FLAG_CONTENT_TEXT = 0x00000004
FLAG_CONTENT_CONTENT_DESCRIPTION = 0x00000008
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._enabled = False
self._touch_exploration_enabled = False
self._high_text_contrast_enabled = False
self._animator_duration_scale = 1.0
self._display_magnification_enabled = False
self._accessibility_volume = 0
self._speech_rate = 1.0
self._listeners: List[Any] = []
def isEnabled(self) -> bool:
return self._enabled
def addAccessibilityStateChangeListener(self, listener: Any) -> bool:
if listener not in self._listeners:
self._listeners.append(listener)
return True
def removeAccessibilityStateChangeListener(self, listener: Any) -> bool:
if listener in self._listeners:
self._listeners.remove(listener)
return True
def isTouchExplorationEnabled(self) -> bool:
return self._touch_exploration_enabled
def isHighTextContrastEnabled(self) -> bool:
return self._high_text_contrast_enabled
def getAccessibilityServiceList(self) -> List[Any]:
return []
def addTouchExplorationStateChangeListener(self, listener: Any) -> None:
pass
def removeTouchExplorationStateChangeListener(self, listener: Any) -> None:
pass
def sendAccessibilityEvent(self, event: Any) -> None:
pass
def interrupt(self) -> None:
pass
def getEnabledAccessibilityServiceList(self, feedbackTypeFlags: int) -> List[Any]:
return []
def getInstalledAccessibilityServiceList(self) -> List[Any]:
return []
def toString(self) -> str:
return f"AccessibilityManager(enabled={self._enabled})"
# ═══════════════════════════════════════════════════════════════
# AccountManager (扩展)
# ═══════════════════════════════════════════════════════════════
class AccountManager(Stub):
"""AccountManager — 账户管理器 (扩展)"""
KEY_ACCOUNTS = "accounts"
KEY_ACCOUNT_NAME = "accountName"
KEY_ACCOUNT_TYPE = "accountType"
KEY_AUTHTOKEN = "authtoken"
KEY_AUTH_FAILED_MESSAGE = "authFailedMessage"
KEY_AUTH_TOKEN_LABEL = "authTokenLabelKey"
KEY_BOOLEAN_RESULT = "booleanResult"
KEY_ERROR_CODE = "errorCode"
KEY_ERROR_MESSAGE = "errorMessage"
KEY_INTENT = "intent"
KEY_PASSWORD = "password"
KEY_USERDATA = "userdata"
KEY_CUSTOM_TOKEN_EXPIRY = "customTokenExpiry"
KEY_ACCOUNT_ACCESS_ID = "accountAccessId"
ERROR_CODE_NETWORK_ERROR = 1
ERROR_CODE_UNSUPPORTED_OPERATION = 2
ERROR_CODE_INVALID_RESPONSE = 3
ERROR_CODE_REMOTE_EXCEPTION = 4
ERROR_CODE_MANAGEMENT_DISABLED = 5
ERROR_CODE_BAD_ARGUMENTS = 6
ERROR_CODE_BAD_REQUEST = 7
ERROR_CODE_DENIED = 8
ERROR_CODE_CANCELED = 9
ERROR_CODE_INVALID_CREDENTIALS = 10
ERROR_CODE_SESSION_EXPIRED = 11
ERROR_CODE_USER_RESTRICTION = 12
_instance: Optional["AccountManager"] = None
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._accounts: List[Any] = []
self._auth_tokens: Dict[str, str] = {}
self._user_data: Dict[str, Dict[str, str]] = {}
self._password_data: Dict[str, str] = {}
self._account_visibility: Dict[str, bool] = {}
self._lock = threading.Lock()
@staticmethod
def get(context: Any) -> "AccountManager":
if AccountManager._instance is None:
AccountManager._instance = AccountManager(context)
return AccountManager._instance
def getAccounts(self) -> List[Any]:
with self._lock:
return list(self._accounts)
def getAccountsByType(self, type_: str) -> List[Any]:
with self._lock:
return [a for a in self._accounts if getattr(a, "type", None) == type_]
def addAccountExplicitly(self, account: Any, password: Optional[str], userdata: Optional[Dict]) -> bool:
with self._lock:
if account not in self._accounts:
self._accounts.append(account)
name = getattr(account, "name", str(account))
if password is not None:
self._password_data[name] = password
if userdata:
self._user_data[name] = dict(userdata)
return True
return False
def removeAccountExplicitly(self, account: Any) -> bool:
with self._lock:
if account in self._accounts:
self._accounts.remove(account)
name = getattr(account, "name", str(account))
self._password_data.pop(name, None)
self._user_data.pop(name, None)
return True
return False
def getUserData(self, account: Any, key: str) -> Optional[str]:
with self._lock:
name = getattr(account, "name", str(account))
return self._user_data.get(name, {}).get(key)
def setUserData(self, account: Any, key: str, value: str) -> None:
with self._lock:
name = getattr(account, "name", str(account))
if name not in self._user_data:
self._user_data[name] = {}
self._user_data[name][key] = value
def getPassword(self, account: Any) -> Optional[str]:
with self._lock:
name = getattr(account, "name", str(account))
return self._password_data.get(name)
def setPassword(self, account: Any, password: str) -> None:
with self._lock:
name = getattr(account, "name", str(account))
self._password_data[name] = password
def clearPassword(self, account: Any) -> None:
with self._lock:
name = getattr(account, "name", str(account))
self._password_data.pop(name, None)
def getAuthToken(self, account: Any, authTokenType: str) -> Optional[str]:
with self._lock:
name = getattr(account, "name", str(account))
return self._auth_tokens.get(f"{name}:{authTokenType}")
def setAuthToken(self, account: Any, authTokenType: str, authToken: str) -> None:
with self._lock:
name = getattr(account, "name", str(account))
self._auth_tokens[f"{name}:{authTokenType}"] = authToken
def invalidateAuthToken(self, accountType: str, authToken: str) -> None:
with self._lock:
to_remove = [k for k, v in self._auth_tokens.items() if v == authToken]
for k in to_remove:
del self._auth_tokens[k]
def hasFeatures(self, account: Any, features: List[str], callback: Any, handler: Any = None) -> None:
pass
def getAccountVisibility(self, account: Any, packageName: str) -> int:
return 1
def toString(self) -> str:
return f"AccountManager(accounts={len(self._accounts)})"
# ═══════════════════════════════════════════════════════════════
# AlarmManager
# ═══════════════════════════════════════════════════════════════
class AlarmManager(Stub):
"""AlarmManager — 闹钟管理器"""
RTC_WAKEUP = 0
RTC = 1
ELAPSED_REALTIME_WAKEUP = 2
ELAPSED_REALTIME = 3
INTERVAL_FIFTEEN_MINUTES = 900000
INTERVAL_HALF_HOUR = 1800000
INTERVAL_HOUR = 3600000
INTERVAL_DAY = 86400000
FLAG_ALLOW_WHILE_IDLE_UNSCREEN_ON = 0x00000008
FLAG_ALLOW_WHILE_IDLE = 0x00000004
FLAG_STANDALONE = 0x00000002
FLAG_WAKE_FROM_IDLE = 0x00000001
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._alarms: List[Dict[str, Any]] = []
self._lock = threading.Lock()
self._next_id = 1
self._worker: Optional[threading.Thread] = None
self._running = True
def set(self, type_: int, triggerAtMillis: int, operation: Any) -> None:
with self._lock:
self._alarms.append({
"id": self._next_id,
"type": type_,
"trigger": triggerAtMillis,
"operation": operation,
"interval": 0,
"repeat": False,
"window": 0,
"allow_while_idle": False,
})
self._next_id += 1
def setRepeating(self, type_: int, triggerAtMillis: int, intervalMillis: int, operation: Any) -> None:
with self._lock:
self._alarms.append({
"id": self._next_id,
"type": type_,
"trigger": triggerAtMillis,
"operation": operation,
"interval": intervalMillis,
"repeat": True,
"window": 0,
"allow_while_idle": False,
})
self._next_id += 1
def setWindow(self, type_: int, windowStartMillis: int, windowLengthMillis: int, operation: Any) -> None:
with self._lock:
self._alarms.append({
"id": self._next_id,
"type": type_,
"trigger": windowStartMillis,
"operation": operation,
"interval": 0,
"repeat": False,
"window": windowLengthMillis,
"allow_while_idle": False,
})
self._next_id += 1
def setExact(self, type_: int, triggerAtMillis: int, operation: Any) -> None:
self.set(type_, triggerAtMillis, operation)
def setExactAndAllowWhileIdle(self, type_: int, triggerAtMillis: int, operation: Any) -> None:
self.set(type_, triggerAtMillis, operation)
def setAlarmClock(self, info: Any, triggerAtMillis: int, operation: Any) -> None:
pass
def cancel(self, operation: Any) -> None:
with self._lock:
self._alarms = [a for a in self._alarms if a.get("operation") != operation]
def getNextAlarmClock(self) -> Optional[Any]:
return None
def canScheduleExactAlarms(self) -> bool:
return True
def toString(self) -> str:
return f"AlarmManager(alarms={len(self._alarms)})"
# ═══════════════════════════════════════════════════════════════
# AppOpsManager
# ═══════════════════════════════════════════════════════════════
class AppOpsManager(Stub):
"""AppOpsManager — 应用操作管理器"""
MODE_ALLOWED = 0
MODE_IGNORED = 1
MODE_ERRORED = 2
MODE_DEFAULT = 3
MODE_FOREGROUND = 4
OPSTR_COARSE_LOCATION = "android:coarse_location"
OPSTR_FINE_LOCATION = "android:fine_location"
OPSTR_CAMERA = "android:camera"
OPSTR_RECORD_AUDIO = "android:record_audio"
OPSTR_READ_CONTACTS = "android:read_contacts"
OPSTR_WRITE_CONTACTS = "android:write_contacts"
OPSTR_READ_EXTERNAL_STORAGE = "android:read_external_storage"
OPSTR_WRITE_EXTERNAL_STORAGE = "android:write_external_storage"
OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications"
OPSTR_POST_NOTIFICATIONS = "android:post_notifications"
OPSTR_VIBRATE = "android:vibrate"
OPSTR_CALL_PHONE = "android:call_phone"
OPSTR_READ_SMS = "android:read_sms"
OPSTR_SEND_SMS = "android:send_sms"
OPSTR_RECEIVE_SMS = "android:receive_sms"
OPSTR_SYSTEM_ALERT_WINDOW = "android:system_alert_window"
OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages"
OPSTR_BLUETOOTH = "android:bluetooth"
OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan"
OPSTR_BLUETOOTH_ADVERTISE = "android:bluetooth_advertise"
OPSTR_BLUETOOTH_CONNECT = "android:bluetooth_connect"
OPSTR_NFC = "android:nfc"
OPSTR_NFC_PREFERRED_PAYMENT = "android:nfc_preferred_payment"
OPSTR_PICTURE_IN_PICTURE = "android:picture_in_picture"
OPSTR_FOREGROUND_SERVICE = "android:foreground_service"
OPSTR_MANAGE_EXTERNAL_STORAGE = "android:manage_external_storage"
OPSTR_BODY_SENSORS = "android:body_sensors"
OPSTR_ACTIVITY_RECOGNITION = "android:activity_recognition"
OPSTR_USE_BIOMETRIC = "android:use_biometric"
OPSTR_USE_FINGERPRINT = "android:use_fingerprint"
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._op_modes: Dict[str, Dict[str, int]] = {}
self._lock = threading.Lock()
def checkOp(self, op: str, uid: int, packageName: str) -> int:
with self._lock:
if packageName not in self._op_modes:
return AppOpsManager.MODE_ALLOWED
return self._op_modes[packageName].get(op, AppOpsManager.MODE_ALLOWED)
def noteOp(self, op: str, uid: int, packageName: str) -> int:
return self.checkOp(op, uid, packageName)
def startOp(self, op: str, uid: int, packageName: str) -> int:
return self.checkOp(op, uid, packageName)
def finishOp(self, op: str, uid: int, packageName: str) -> None:
pass
def setMode(self, code: int, uid: int, packageName: str, mode: int) -> None:
with self._lock:
if packageName not in self._op_modes:
self._op_modes[packageName] = {}
self._op_modes[packageName][str(code)] = mode
def toString(self) -> str:
return f"AppOpsManager(packages={len(self._op_modes)})"
# ═══════════════════════════════════════════════════════════════
# ClipboardManager
# ═══════════════════════════════════════════════════════════════
class ClipboardManager(Stub):
"""ClipboardManager — 剪贴板管理器"""
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._primary_clip: Optional[Any] = None
self._listeners: List[Callable] = []
self._has_clipboard = True
self._clipboard_history: List[Any] = []
self._max_history = 10
def setPrimaryClip(self, clip: Any) -> None:
self._primary_clip = clip
if clip is not None:
self._clipboard_history.append(clip)
if len(self._clipboard_history) > self._max_history:
self._clipboard_history.pop(0)
for listener in self._listeners:
try:
listener(clip)
except Exception:
pass
def clearPrimaryClip(self) -> None:
if self._primary_clip is not None:
self._clipboard_history.append(None)
self._primary_clip = None
def getPrimaryClip(self) -> Optional[Any]:
return self._primary_clip
def hasPrimaryClip(self) -> bool:
return self._primary_clip is not None
def hasClipboardText(self) -> bool:
if self._primary_clip is None:
return False
try:
return hasattr(self._primary_clip, "getText") and self._primary_clip.getText() is not None
except Exception:
return False
def getText(self) -> Optional[str]:
if self._primary_clip is not None:
try:
return self._primary_clip.getText()
except Exception:
pass
return None
def addPrimaryClipChangedListener(self, listener: Callable) -> None:
if listener not in self._listeners:
self._listeners.append(listener)
def removePrimaryClipChangedListener(self, listener: Callable) -> None:
if listener in self._listeners:
self._listeners.remove(listener)
def getClipboardHistory(self) -> List[Any]:
return list(self._clipboard_history)
def toString(self) -> str:
return f"ClipboardManager(has_clip={self.hasPrimaryClip()})"
# ═══════════════════════════════════════════════════════════════
# ConnectivityManager (扩展)
# ═══════════════════════════════════════════════════════════════
class ConnectivityManager(Stub):
"""ConnectivityManager — 连接管理器 (扩展)"""
TYPE_NONE = -1
TYPE_MOBILE = 0
TYPE_WIFI = 1
TYPE_MOBILE_MMS = 2
TYPE_MOBILE_SUPL = 3
TYPE_MOBILE_DUN = 4
TYPE_MOBILE_HIPRI = 5
TYPE_WIMAX = 6
TYPE_BLUETOOTH = 7
TYPE_DUMMY = 8
TYPE_ETHERNET = 9
TYPE_VPN = 17
TYPE_WIFI_P2P = 13
EXTRA_NETWORK_TYPE = "networkType"
EXTRA_IS_FAILOVER = "isFailover"
EXTRA_OTHER_NETWORK_INFO = "otherNetwork"
EXTRA_NO_CONNECTIVITY = "noConnectivity"
EXTRA_REASON = "reason"
EXTRA_EXTRA_INFO = "extraInfo"
EXTRA_NETWORK_INFO = "networkInfo"
EXTRA_NETWORK_REQUEST = "networkRequest"
EXTRA_NETWORK = "network"
CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE"
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._active_network_info: Optional[Any] = None
self._network_preference = ConnectivityManager.TYPE_WIFI
self._background_data_setting = True
self._network_callbacks: List[Any] = []
self._active_network: Optional[Any] = None
self._all_networks: List[Any] = []
def _get_linux_active_info(self):
"""从 Linux 真实网络信息构造活跃 NetworkInfo"""
try:
from .net import NetworkInfo
interfaces = LinuxNetwork.get_interfaces()
# 有真实网络接口 (非环回) 且 operstate=up 即视为已连接
connected = any(
(iface.get("ifname") or iface.get("name", "")) != "lo"
and iface.get("operstate", "").lower() == "up"
for iface in interfaces
)
if not connected:
connected = LinuxNetwork.get_connectivity()
ip = LinuxNetwork.get_ip_address()
iface_name = ""
net_type = ConnectivityManager.TYPE_ETHERNET
for iface in interfaces:
name = iface.get("ifname") or iface.get("name", "")
state = iface.get("operstate", "")
if name and name != "lo" and state.lower() == "up":
iface_name = iface_name or name
if name and name.startswith(("wl", "wlan", "wlp")):
net_type = ConnectivityManager.TYPE_WIFI
iface_name = name
data = {
"connected": connected,
"ip": ip,
"interface": iface_name,
"type_name": "WIFI" if net_type == ConnectivityManager.TYPE_WIFI else "ETHERNET",
}
return NetworkInfo.from_linux_data(data, network_type=net_type)
except Exception:
return self._active_network_info
def getActiveNetworkInfo(self) -> Optional[Any]:
if _USE_LINUX:
return self._get_linux_active_info()
return self._active_network_info
def getNetworkInfo(self, networkType: int) -> Optional[Any]:
if _USE_LINUX:
info = self._get_linux_active_info()
if info is not None and info.getType() == networkType:
return info
return None
return None
def getConnectivityStatus(self) -> bool:
"""返回当前网络连通性 (True=已连接)"""
if _USE_LINUX:
return LinuxNetwork.get_connectivity()
return False
def getAllNetworkInfo(self) -> List[Any]:
return self._all_networks
def isActiveNetworkMetered(self) -> bool:
return True
def getActiveNetwork(self) -> Optional[Any]:
return self._active_network
def getAllNetworks(self) -> List[Any]:
return list(self._all_networks)
def requestNetwork(self, request: Any, callback: Any) -> None:
pass
def registerNetworkCallback(self, request: Any, callback: Any) -> None:
if callback not in self._network_callbacks:
self._network_callbacks.append(callback)
def unregisterNetworkCallback(self, callback: Any) -> None:
if callback in self._network_callbacks:
self._network_callbacks.remove(callback)
def getNetworkCapabilities(self, network: Any) -> Optional[Any]:
return None
def getLinkProperties(self, network: Any) -> Optional[Any]:
return None
def setNetworkPreference(self, preference: int) -> None:
self._network_preference = preference
def getBackgroundDataSetting(self) -> bool:
return self._background_data_setting
def setBackgroundDataSetting(self, allow: bool) -> None:
self._background_data_setting = allow
def reportBadNetwork(self, network: Any) -> None:
pass
def toString(self) -> str:
return f"ConnectivityManager(active={self._active_network_info is not None})"
# ═══════════════════════════════════════════════════════════════
# DevicePolicyManager (扩展)
# ═══════════════════════════════════════════════════════════════
class DevicePolicyManager(Stub):
"""DevicePolicyManager — 设备策略管理器 (扩展)"""
ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN"
ACTION_DEVICE_ADMIN_ENABLED = "android.app.action.DEVICE_ADMIN_ENABLED"
ACTION_DEVICE_ADMIN_DISABLED = "android.app.action.DEVICE_ADMIN_DISABLED"
ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD"
ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION"
ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.PROVISION_MANAGED_PROFILE"
ACTION_SYSTEM_UPDATE_POLICY = "android.app.action.SYSTEM_UPDATE_POLICY"
KEYGUARD_DISABLE_FEATURES_NONE = 0
KEYGUARD_DISABLE_FEATURES_ALL = 0x7FFFFFFF
KEYGUARD_DISABLE_SECURE_CAMERA = 2
KEYGUARD_DISABLE_FINGERPRINT = 32
KEYGUARD_DISABLE_REMOTE_INPUT = 64
KEYGUARD_DISABLE_FACE = 128
KEYGUARD_DISABLE_IRIS = 256
KEYGUARD_DISABLE_BIOMETRICS = 32 | 128 | 256
KEYGUARD_DISABLE_SHORTCUTS = 512
KEYGUARD_DISABLE_WIDGETS_ALL = 1048576
PASSWORD_QUALITY_UNSPECIFIED = 0
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
PASSWORD_QUALITY_BIOMETRIC_WEAK = 0x8000
RESET_PASSWORD_REQUIRE_ENTRY = 0x0001
RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 0x0002
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._admin_receivers: List[Any] = []
self._password_quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED
self._password_length = 0
self._maximum_failed_passwords_for_wipe = 0
self._maximum_time_to_lock = 0
self._storage_encryption = False
self._camera_disabled = False
self._screen_capture_disabled = False
self._keyguard_disabled_features = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE
self._lock_task_packages: List[str] = []
def isDeviceOwnerApp(self, packageName: str) -> bool:
return False
def isProfileOwnerApp(self, packageName: str) -> bool:
return False
def getDeviceOwner(self) -> Optional[str]:
return None
def getProfileOwner(self) -> Optional[Any]:
return None
def setPasswordQuality(self, admin: Any, quality: int) -> None:
self._password_quality = quality
def getPasswordQuality(self, admin: Any = None) -> int:
return self._password_quality
def setPasswordMinimumLength(self, admin: Any, length: int) -> None:
self._password_length = length
def getPasswordMinimumLength(self, admin: Any = None) -> int:
return self._password_length
def resetPassword(self, password: str, flags: int = 0) -> bool:
return True
def setMaximumFailedPasswordsForWipe(self, admin: Any, num: int) -> None:
self._maximum_failed_passwords_for_wipe = num
def getMaximumFailedPasswordsForWipe(self, admin: Any = None) -> int:
return self._maximum_failed_passwords_for_wipe
def setMaximumTimeToLock(self, admin: Any, timeMs: int) -> None:
self._maximum_time_to_lock = timeMs
def getMaximumTimeToLock(self, admin: Any = None) -> int:
return self._maximum_time_to_lock
def lockNow(self) -> None:
pass
def wipeData(self, flags: int = 0) -> None:
raise RuntimeError("wipeData() would wipe device data")
def setStorageEncryption(self, admin: Any, encrypt: bool) -> int:
self._storage_encryption = encrypt
return 1
def getStorageEncryption(self, admin: Any = None) -> bool:
return self._storage_encryption
def setCameraDisabled(self, admin: Any, disabled: bool) -> None:
self._camera_disabled = disabled
def getCameraDisabled(self, admin: Any = None) -> bool:
return self._camera_disabled
def setScreenCaptureDisabled(self, admin: Any, disabled: bool) -> None:
self._screen_capture_disabled = disabled
def getScreenCaptureDisabled(self, admin: Any = None) -> bool:
return self._screen_capture_disabled
def setKeyguardDisabledFeatures(self, admin: Any, features: int) -> None:
self._keyguard_disabled_features = features
def getKeyguardDisabledFeatures(self, admin: Any = None) -> int:
return self._keyguard_disabled_features
def setLockTaskPackages(self, admin: Any, packages: List[str]) -> None:
self._lock_task_packages = list(packages)
def getLockTaskPackages(self, admin: Any = None) -> List[str]:
return list(self._lock_task_packages)
def isLockTaskPermitted(self, pkg: str) -> bool:
return pkg in self._lock_task_packages
def toString(self) -> str:
return f"DevicePolicyManager(password_quality=0x{self._password_quality:x})"
# ═══════════════════════════════════════════════════════════════
# DisplayManager (扩展)
# ═══════════════════════════════════════════════════════════════
class DisplayManager(Stub):
"""DisplayManager — 显示管理器 (扩展)"""
DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION"
VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR = 0x00000001
VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY = 0x00000002
VIRTUAL_DISPLAY_FLAG_PRESENTATION = 0x00000004
VIRTUAL_DISPLAY_FLAG_SECURE = 0x00000008
VIRTUAL_DISPLAY_FLAG_PUBLIC = 0x00000010
VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH = 0x00000020
VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT = 0x00000040
VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_SURFACE = 0x00000080
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._displays: Dict[int, Any] = {}
self._display_listeners: List[Any] = []
self._default_display: Optional[Any] = None
self._virtual_displays: Dict[str, Any] = {}
def getDisplay(self, displayId: int) -> Optional[Any]:
return self._displays.get(displayId)
def getDisplays(self, category: Optional[str] = None) -> List[Any]:
if category:
return [d for d in self._displays.values()]
return list(self._displays.values())
def getDefaultDisplay(self) -> Optional[Any]:
return self._default_display
def registerDisplayListener(self, listener: Any, handler: Any = None) -> None:
if listener not in self._display_listeners:
self._display_listeners.append(listener)
def unregisterDisplayListener(self, listener: Any) -> None:
if listener in self._display_listeners:
self._display_listeners.remove(listener)
def createVirtualDisplay(
self, name: str, width: int, height: int, densityDpi: int,
surface: Any, flags: int = 0
) -> Optional[Any]:
return None
def toString(self) -> str:
return f"DisplayManager(displays={len(self._displays)})"
# ═══════════════════════════════════════════════════════════════
# DownloadManager
# ═══════════════════════════════════════════════════════════════
class DownloadManager(Stub):
"""DownloadManager — 下载管理器"""
ACTION_DOWNLOAD_COMPLETE = "android.intent.action.DOWNLOAD_COMPLETE"
ACTION_NOTIFICATION_CLICKED = "android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED"
ACTION_VIEW_DOWNLOADS = "android.intent.action.VIEW_DOWNLOADS"
EXTRA_DOWNLOAD_ID = "extraDownloadId"
EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS = "extraNotificationClickDownloadIds"
INTENT_EXTRAS_SORT_BY_SIZE = "android.app.DownloadManager.extraSortBySize"
COLUMN_ID = "_id"
COLUMN_TITLE = "title"
COLUMN_DESCRIPTION = "description"
COLUMN_URI = "uri"
COLUMN_STATUS = "status"
COLUMN_REASON = "reason"
COLUMN_TOTAL_SIZE_BYTES = "total_size"
COLUMN_BYTES_DOWNLOADED_SO_FAR = "bytes_so_far"
COLUMN_MEDIA_TYPE = "media_type"
COLUMN_LOCAL_FILENAME = "local_filename"
COLUMN_LOCAL_URI = "local_uri"
COLUMN_LAST_MODIFIED_TIMESTAMP = "last_modified_timestamp"
STATUS_PENDING = 1
STATUS_RUNNING = 2
STATUS_PAUSED = 3
STATUS_SUCCESSFUL = 4
STATUS_FAILED = 5
STATUS_QUEUED = 6
STATUS_WAITING = 7
STATUS_WAITING_FOR_NETWORK = 8
STATUS_WAITING_FOR_WIFI = 9
ERROR_UNKNOWN = 1000
ERROR_DEVICE_NOT_FOUND = 1001
ERROR_CANNOT_RESUME = 1002
ERROR_FILE_ALREADY_EXISTS = 1003
ERROR_FILE_ERROR = 1004
ERROR_HTTP_DATA_ERROR = 1005
ERROR_INSUFFICIENT_SPACE = 1006
ERROR_TOO_MANY_REDIRECTS = 1007
ERROR_UNHANDLED_HTTP_CODE = 1008
ERROR_HTTP_406 = 1009
PAUSED_QUEUED_FOR_WIFI = 1
PAUSED_WAITING_TO_RETRY = 2
PAUSED_WAITING_FOR_NETWORK = 3
PAUSED_UNKNOWN = 4
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._downloads: Dict[int, Dict[str, Any]] = {}
self._next_id = 1
self._lock = threading.Lock()
def enqueue(self, request: Any) -> int:
with self._lock:
download_id = self._next_id
self._next_id += 1
self._downloads[download_id] = {
"id": download_id,
"status": DownloadManager.STATUS_PENDING,
"reason": 0,
"title": "",
"description": "",
"uri": "",
"total_size": -1,
"bytes_so_far": 0,
"local_filename": "",
}
return download_id
def query(self, query: Any) -> Any:
return None
def remove(self, varargs: List[int]) -> int:
removed = 0
with self._lock:
for download_id in varargs:
if download_id in self._downloads:
del self._downloads[download_id]
removed += 1
return removed
def getUriForDownloadedFile(self, downloadId: int) -> Optional[str]:
return None
def getMimeTypeForDownloadedFile(self, downloadId: int) -> Optional[str]:
return None
def restartDownload(self, downloadId: int) -> bool:
return False
def toString(self) -> str:
return f"DownloadManager(downloads={len(self._downloads)})"
# ═══════════════════════════════════════════════════════════════
# DropBoxManager
# ═══════════════════════════════════════════════════════════════
class DropBoxManager(Stub):
"""DropBoxManager — 日志收集管理器"""
IS_EMPTY = 0
IS_TEXT = 1
IS_GZIPPED = 2
IS_ENCRYPTED = 4
def __init__(self, context: Any = None):
super().__init__()
self._entries: Dict[str, List[Any]] = {}
self._max_entries = 100
def addText(self, tag: str, data: str) -> None:
if tag not in self._entries:
self._entries[tag] = []
self._entries[tag].append(("text", data, time.time()))
if len(self._entries[tag]) > self._max_entries:
self._entries[tag].pop(0)
def addData(self, tag: str, data: bytes, flags: int = 0) -> None:
if tag not in self._entries:
self._entries[tag] = []
self._entries[tag].append(("data", data, time.time(), flags))
if len(self._entries[tag]) > self._max_entries:
self._entries[tag].pop(0)
def getNextEntry(self, tag: str, msec: int) -> Optional[Any]:
return None
def isTagEnabled(self, tag: str) -> bool:
return True
def dump(self, pw: Any) -> None:
pass
def toString(self) -> str:
return f"DropBoxManager(entries={sum(len(v) for v in self._entries.values())})"
# ═══════════════════════════════════════════════════════════════
# FocusManager
# ═══════════════════════════════════════════════════════════════
class FocusManager(Stub):
"""FocusManager — 焦点管理器"""
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._focused_view: Optional[Any] = None
self._focus_cycle_enabled = True
self._focus_search_enabled = True
def getFocusedView(self) -> Optional[Any]:
return self._focused_view
def setFocusedView(self, view: Any) -> None:
self._focused_view = view
def clearFocus(self) -> None:
self._focused_view = None
def isFocusCycleEnabled(self) -> bool:
return self._focus_cycle_enabled
def setFocusCycleEnabled(self, enabled: bool) -> None:
self._focus_cycle_enabled = enabled
def requestFocus(self, view: Any, direction: int = 0) -> bool:
self._focused_view = view
return True
def toString(self) -> str:
return f"FocusManager(focused={self._focused_view is not None})"
# ═══════════════════════════════════════════════════════════════
# LauncherApps
# ═══════════════════════════════════════════════════════════════
class LauncherApps(Stub):
"""LauncherApps — 启动器应用管理器"""
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._callbacks: List[Any] = []
self._shortcuts: Dict[str, List[Any]] = {}
def getActivityList(self, packageName: str, user: Any) -> List[Any]:
return []
def getApplicationList(self, user: Any) -> List[Any]:
return []
def startAppDetails(self, component: Any, user: Any, sourceBounds: Any, opts: Any) -> None:
pass
def startMainActivity(self, component: Any, user: Any, sourceBounds: Any, opts: Any) -> None:
pass
def getShortcutConfigActivityList(self, packageName: str, user: Any) -> List[Any]:
return []
def hasShortcutHostPermission(self) -> bool:
return True
def getShortcuts(self, filter_: Any, user: Any) -> List[Any]:
return []
def pinShortcuts(self, packageName: str, shortcutIds: List[str], user: Any) -> bool:
return True
def registerCallback(self, callback: Any) -> None:
if callback not in self._callbacks:
self._callbacks.append(callback)
def unregisterCallback(self, callback: Any) -> None:
if callback in self._callbacks:
self._callbacks.remove(callback)
def toString(self) -> str:
return f"LauncherApps(callbacks={len(self._callbacks)})"
# ═══════════════════════════════════════════════════════════════
# MediaRouter
# ═══════════════════════════════════════════════════════════════
class MediaRouter(Stub):
"""MediaRouter — 媒体路由管理器"""
ROUTE_TYPE_LIVE_AUDIO = 1
ROUTE_TYPE_LIVE_VIDEO = 2
ROUTE_TYPE_REMOTE_DISPLAY = 4
ROUTE_TYPE_USER = 8
ROUTE_TYPE_ANY = 0x800000
UNSELECT_REASON_UNKNOWN = 0
UNSELECT_REASON_ROUTE_CHANGED = 1
UNSELECT_REASON_DISCONNECTED = 2
UNSELECT_REASON_STOPPED = 3
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._routes: List[Any] = []
self._selected_route: Optional[Any] = None
self._default_route: Optional[Any] = None
self._callbacks: List[Any] = []
def getDefaultRoute(self) -> Optional[Any]:
return self._default_route
def getSelectedRoute(self, type_: int) -> Optional[Any]:
return self._selected_route
def selectRoute(self, type_: int, route: Any) -> None:
self._selected_route = route
def addCallback(self, types: int, cb: Any) -> None:
if cb not in self._callbacks:
self._callbacks.append(cb)
def removeCallback(self, cb: Any) -> None:
if cb in self._callbacks:
self._callbacks.remove(cb)
def getRoutes(self) -> List[Any]:
return list(self._routes)
def isUserRouteAllowed(self) -> bool:
return True
def toString(self) -> str:
return f"MediaRouter(routes={len(self._routes)})"
# ═══════════════════════════════════════════════════════════════
# NetworkPolicyManager
# ═══════════════════════════════════════════════════════════════
class NetworkPolicyManager(Stub):
"""NetworkPolicyManager — 网络策略管理器"""
POLICY_NONE = 0
POLICY_REJECT_METERED_BACKGROUND = 1
POLICY_ALLOW_METERED_BACKGROUND = 4
RULE_ALLOW_ALL = 0
RULE_REJECT_METERED = 1
RULE_REJECT_ALL = 2
RULE_TEMPORARY_ALLOW_METERED = 3
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._uid_policies: Dict[int, int] = {}
self._uid_rules: Dict[int, int] = {}
self._restrict_background = False
def getUidPolicy(self, uid: int) -> int:
return self._uid_policies.get(uid, NetworkPolicyManager.POLICY_NONE)
def setUidPolicy(self, uid: int, policy: int) -> None:
self._uid_policies[uid] = policy
def getUidsWithPolicy(self, policy: int) -> List[int]:
return [uid for uid, p in self._uid_policies.items() if p == policy]
def isUidNetworkingBlocked(self, uid: int, metered: bool) -> bool:
return False
def registerListener(self, listener: Any) -> None:
pass
def unregisterListener(self, listener: Any) -> None:
pass
def toString(self) -> str:
return f"NetworkPolicyManager(uids={len(self._uid_policies)})"
# ═══════════════════════════════════════════════════════════════
# NotificationManager (扩展)
# ═══════════════════════════════════════════════════════════════
class NotificationManagerExt(Stub):
"""NotificationManager (Extension) — 额外通知管理器功能"""
def __init__(self, context: Any = None):
super().__init__()
self._context = context
def getSnoozeIntentForChannel(self, channelId: str) -> Optional[Any]:
return None
def matchesCallFilter(self, address: Any) -> bool:
return True
def getActiveNotificationsFromBinder(self) -> List[Any]:
return []
def getHistoricalNotifications(self) -> List[Any]:
return []
def canNotifyAsPackage(self, pkg: str) -> bool:
return True
def setNotificationDelegate(self, delegate: str) -> None:
pass
def getNotificationDelegate(self) -> Optional[str]:
return None
def updateNotificationChannelGroup(self, group: Any) -> None:
pass
def toString(self) -> str:
return "NotificationManager(Extension)"
# ═══════════════════════════════════════════════════════════════
# NsdManager (quick reference for net_nsd 模块)
# ═══════════════════════════════════════════════════════════════
class NsdManagerQuick(Stub):
"""NsdManager (Quick Reference)"""
PROTOCOL_DNS_SD = 0
FAILURE_ALREADY_ACTIVE = 3
FAILURE_INTERNAL_ERROR = 0
FAILURE_MAX_LIMIT = 4
FAILURE_SERVICE_NOT_FOUND = 1
FAILURE_SERVICE_NOT_RUNNING = 2
def __init__(self, context: Any = None):
super().__init__()
self._context = context
def discoverServices(self, serviceType: str, protocolType: int, listener: Any) -> None:
pass
def stopServiceDiscovery(self, listener: Any) -> None:
pass
def registerService(self, serviceInfo: Any, protocolType: int, listener: Any) -> None:
pass
def unregisterService(self, listener: Any) -> None:
pass
def resolveService(self, serviceInfo: Any, listener: Any) -> None:
pass
def toString(self) -> str:
return "NsdManager"
# ═══════════════════════════════════════════════════════════════
# RestrictionManager
# ═══════════════════════════════════════════════════════════════
class RestrictionManager(Stub):
"""RestrictionManager — 限制管理器"""
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._restrictions: Dict[str, Any] = {}
self._lock = threading.Lock()
def getApplicationRestrictions(self, packageName: str) -> Any:
return None
def setApplicationRestrictions(self, packageName: str, restrictions: Any) -> None:
pass
def hasRestrictionProvider(self) -> bool:
return False
def getManifestRestrictions(self, packageName: str) -> List[Any]:
return []
def getRestrictionsProvider(self, packageName: str) -> Optional[Any]:
return None
def notifyPermissionResponse(self, packageName: str, response: Any) -> None:
pass
def toString(self) -> str:
return "RestrictionManager"
# ═══════════════════════════════════════════════════════════════
# SubscriptionManager
# ═══════════════════════════════════════════════════════════════
class SubscriptionManager(Stub):
"""SubscriptionManager — 订阅管理器"""
DEFAULT_SUBSCRIPTION_ID = -1
INVALID_SUBSCRIPTION_ID = -2
ACTIVE_DATA_SUBSCRIPTION_ID = -3
EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX"
EXTRA_SLOT_INDEX = "android.telephony.extra.SLOT_INDEX"
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._subscriptions: List[Any] = []
def getActiveSubscriptionInfoList(self) -> List[Any]:
return list(self._subscriptions)
def getActiveSubscriptionInfo(self, subId: int) -> Optional[Any]:
for sub in self._subscriptions:
if getattr(sub, "subscriptionId", None) == subId:
return sub
return None
def getActiveSubscriptionInfoForSimSlotIndex(self, slotIndex: int) -> Optional[Any]:
for sub in self._subscriptions:
if getattr(sub, "simSlotIndex", None) == slotIndex:
return sub
return None
def getDefaultSubscriptionId(self) -> int:
return SubscriptionManager.DEFAULT_SUBSCRIPTION_ID
def setDefaultSubscriptionId(self, subId: int) -> None:
pass
def addOnSubscriptionsChangedListener(self, listener: Any) -> None:
pass
def removeOnSubscriptionsChangedListener(self, listener: Any) -> None:
pass
def getSlotIndex(self, subscriptionId: int) -> int:
return -1
def toString(self) -> str:
return f"SubscriptionManager(subscriptions={len(self._subscriptions)})"
# ═══════════════════════════════════════════════════════════════
# WallpaperManager (扩展)
# ═══════════════════════════════════════════════════════════════
class WallpaperManagerExt(Stub):
"""WallpaperManager (Extension)"""
def __init__(self, context: Any = None):
super().__init__()
self._context = context
def getWallpaperIdForWhom(self, which: int) -> int:
return -1
def getWallpaperUserId(self) -> int:
return 0
def setWallpaperOffsets(self, windowToken: Any, xOffset: float, yOffset: float) -> None:
pass
def clearWallpaperOffsets(self, windowToken: Any) -> None:
pass
def hasResourceWallpaper(self, resid: int) -> bool:
return False
def toString(self) -> str:
return "WallpaperManager(Extension)"
# ═══════════════════════════════════════════════════════════════
# WifiP2pManager / WifiP2pDevice / WifiP2pGroup / WifiP2pConfig
# ═══════════════════════════════════════════════════════════════
class WifiP2pDevice(Stub):
"""WifiP2pDevice — WiFi P2P 设备"""
CONNECTED = 0
INVITED = 1
FAILED = 2
AVAILABLE = 3
UNAVAILABLE = 4
def __init__(self):
super().__init__()
self.deviceName: Optional[str] = None
self.deviceAddress: Optional[str] = None
self.primaryDeviceType: Optional[str] = None
self.secondaryDeviceType: Optional[str] = None
self.status = WifiP2pDevice.AVAILABLE
self.wpsConfigMethodsSupported = 0
self.groupCapabilityFlags = 0
self.deviceCapabilityFlags = 0
self.serviceDiscoveryCapable = False
self.isGroupOwner = False
self._supports_wfd = False
self._interface_address: Optional[str] = None
def isGroupOwner(self) -> bool:
return self.isGroupOwner
def wpsDisplaySupported(self) -> bool:
return (self.wpsConfigMethodsSupported & 0x1000) != 0
def wpsKeypadSupported(self) -> bool:
return (self.wpsConfigMethodsSupported & 0x0100) != 0
def wpsPbcSupported(self) -> bool:
return (self.wpsConfigMethodsSupported & 0x0040) != 0
def equals(self, other: Any) -> bool:
if isinstance(other, WifiP2pDevice):
return self.deviceAddress == other.deviceAddress
return False
def hashCode(self) -> int:
return hash(self.deviceAddress) & 0x7FFFFFFF
def toString(self) -> str:
return f"WifiP2pDevice(name={self.deviceName}, addr={self.deviceAddress}, status={self.status})"
class WifiP2pGroup(Stub):
"""WifiP2pGroup — WiFi P2P 组"""
def __init__(self):
super().__init__()
self._network_name: Optional[str] = None
self._owner: Optional[WifiP2pDevice] = None
self._is_group_owner = False
self._passphrase: Optional[str] = None
self._interface: Optional[str] = None
self._clients: List[WifiP2pDevice] = []
self._frequency = 0
def getNetworkName(self) -> Optional[str]:
return self._network_name
def isGroupOwner(self) -> bool:
return self._is_group_owner
def getOwner(self) -> Optional[WifiP2pDevice]:
return self._owner
def getPassphrase(self) -> Optional[str]:
return self._passphrase
def getInterface(self) -> Optional[str]:
return self._interface
def getClientList(self) -> List[WifiP2pDevice]:
return list(self._clients)
def getFrequency(self) -> int:
return self._frequency
def addClient(self, device: WifiP2pDevice) -> None:
if device not in self._clients:
self._clients.append(device)
def removeClient(self, device: WifiP2pDevice) -> None:
if device in self._clients:
self._clients.remove(device)
def toString(self) -> str:
return f"WifiP2pGroup(net={self._network_name}, clients={len(self._clients)})"
class WifiP2pConfig(Stub):
"""WifiP2pConfig — WiFi P2P 配置"""
class Builder(Stub):
"""WifiP2pConfig.Builder — 构建器"""
def __init__(self):
super().__init__()
self._config = WifiP2pConfig()
def setDeviceAddress(self, address: str) -> "WifiP2pConfig.Builder":
self._config._device_address = address
return self
def setDeviceName(self, name: str) -> "WifiP2pConfig.Builder":
self._config._device_name = name
return self
def setGroupOwnerIntent(self, intent: int) -> "WifiP2pConfig.Builder":
self._config._group_owner_intent = intent
return self
def setNetworkName(self, name: str) -> "WifiP2pConfig.Builder":
self._config._network_name = name
return self
def setPassphrase(self, passphrase: str) -> "WifiP2pConfig.Builder":
self._config._passphrase = passphrase
return self
def enablePersistentMode(self, enabled: bool) -> "WifiP2pConfig.Builder":
self._config._persistent_mode = enabled
return self
def build(self) -> "WifiP2pConfig":
return self._config
def __init__(self):
super().__init__()
self._device_address: Optional[str] = None
self._device_name: Optional[str] = None
self._group_owner_intent = -1
self._network_name: Optional[str] = None
self._passphrase: Optional[str] = None
self._persistent_mode = False
self._wps_config = 0
self._net_id = -1
def getDeviceAddress(self) -> Optional[str]:
return self._device_address
def getDeviceName(self) -> Optional[str]:
return self._device_name
def getGroupOwnerIntent(self) -> int:
return self._group_owner_intent
def isPersistentMode(self) -> bool:
return self._persistent_mode
def toString(self) -> str:
return f"WifiP2pConfig(addr={self._device_address}, name={self._device_name})"
class WifiP2pManager(Stub):
"""WifiP2pManager — WiFi P2P 管理器"""
WIFI_P2P_STATE_ENABLED = 2
WIFI_P2P_STATE_DISABLED = 1
WIFI_P2P_PEERS_CHANGED_ACTION = "android.net.wifi.p2p.PEERS_CHANGED"
WIFI_P2P_STATE_CHANGED_ACTION = "android.net.wifi.p2p.STATE_CHANGED"
WIFI_P2P_CONNECTION_CHANGED_ACTION = "android.net.wifi.p2p.CONNECTION_STATE_CHANGE"
WIFI_P2P_THIS_DEVICE_CHANGED_ACTION = "android.net.wifi.p2p.THIS_DEVICE_CHANGED"
WIFI_P2P_DISCOVERY_CHANGED_ACTION = "android.net.wifi.p2p.DISCOVERY_STATE_CHANGE"
WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION = "android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED"
BUSY = 2
ERROR = 0
P2P_UNSUPPORTED = 1
NO_SERVICE_REQUESTS = 3
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._peers: List[WifiP2pDevice] = []
self._services: List[Any] = []
self._discovery_running = False
self._this_device: Optional[WifiP2pDevice] = None
self._groups: List[WifiP2pGroup] = []
self._listeners: Dict[str, List[Any]] = {}
def initialize(self, context: Any, looper: Any, listener: Any) -> "WifiP2pManager":
return self
def discoverPeers(self, channel: Any, listener: Any) -> None:
self._discovery_running = True
if listener:
listener.onSuccess()
def stopPeerDiscovery(self, channel: Any, listener: Any) -> None:
self._discovery_running = False
if listener:
listener.onSuccess()
def requestPeers(self, channel: Any, listener: Any) -> None:
if listener:
listener.onPeersAvailable(self._peers)
def connect(self, channel: Any, config: WifiP2pConfig, listener: Any) -> None:
if listener:
listener.onSuccess()
def cancelConnect(self, channel: Any, listener: Any) -> None:
if listener:
listener.onSuccess()
def createGroup(self, channel: Any, listener: Any) -> None:
if listener:
listener.onSuccess()
def removeGroup(self, channel: Any, listener: Any) -> None:
if listener:
listener.onSuccess()
def requestGroupInfo(self, channel: Any, listener: Any) -> None:
if listener and self._groups:
listener.onGroupInfoAvailable(self._groups[0] if self._groups else None)
def requestConnectionInfo(self, channel: Any, listener: Any) -> None:
if listener:
listener.onConnectionInfoAvailable(None)
def setDeviceName(self, channel: Any, deviceName: str, listener: Any) -> None:
if listener:
listener.onSuccess()
def setWpsPbc(self, channel: Any, iface: str, listener: Any) -> None:
if listener:
listener.onSuccess()
def setWpsPin(self, channel: Any, iface: str, pin: str, listener: Any) -> None:
if listener:
listener.onSuccess()
def getAvailableServiceInfo(self, device: WifiP2pDevice) -> Optional[Any]:
return None
def addServiceRequest(self, channel: Any, req: Any, listener: Any) -> None:
if listener:
listener.onSuccess()
def removeServiceRequest(self, channel: Any, req: Any, listener: Any) -> None:
if listener:
listener.onSuccess()
def setServiceResponseListener(self, channel: Any, listener: Any) -> None:
pass
def clearServiceResponses(self, channel: Any, listener: Any) -> None:
if listener:
listener.onSuccess()
def clearLocalServices(self, channel: Any, listener: Any) -> None:
if listener:
listener.onSuccess()
def requestServiceInfo(self, channel: Any, device: WifiP2pDevice, listener: Any) -> None:
if listener:
listener.onServiceInfoAvailable(None)
def getWifiP2pDeviceList(self) -> List[WifiP2pDevice]:
return list(self._peers)
def isDiscoveryRunning(self) -> bool:
return self._discovery_running
def toString(self) -> str:
return f"WifiP2pManager(peers={len(self._peers)}, discovery={self._discovery_running})"
# ═══════════════════════════════════════════════════════════════
# WindowManager
# ═══════════════════════════════════════════════════════════════
class WindowManager(Stub):
"""WindowManager — 窗口管理器"""
# LayoutParams 类型
TYPE_BASE_APPLICATION = 1
TYPE_APPLICATION = 2
TYPE_APPLICATION_STARTING = 3
TYPE_APPLICATION_PANEL = 1000
TYPE_APPLICATION_MEDIA = 1001
TYPE_APPLICATION_SUB_PANEL = 1002
TYPE_APPLICATION_ATTACHED_DIALOG = 1003
TYPE_APPLICATION_OVERLAY = 1004
TYPE_STATUS_BAR = 2000
TYPE_SYSTEM_ALERT = 2003
TYPE_SYSTEM_OVERLAY = 2006
TYPE_TOAST = 2005
TYPE_PHONE = 2002
TYPE_PRIORITY_PHONE = 2007
TYPE_SYSTEM_DIALOG = 2008
TYPE_KEYGUARD = 2004
TYPE_INPUT_METHOD = 2011
TYPE_INPUT_METHOD_DIALOG = 2012
TYPE_WALLPAPER = 2013
TYPE_NAVIGATION_BAR = 2019
TYPE_DREAM = 2024
TYPE_ACCESSIBILITY_OVERLAY = 2032
TYPE_VOLUME_OVERLAY = 2033
TYPE_SECURE_SYSTEM_OVERLAY = 2034
# LayoutParams 标志
FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001
FLAG_DIM_BEHIND = 0x00000002
FLAG_BLUR_BEHIND = 0x00000004
FLAG_NOT_FOCUSABLE = 0x00000008
FLAG_NOT_TOUCHABLE = 0x00000010
FLAG_NOT_TOUCH_MODAL = 0x00000020
FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040
FLAG_KEEP_SCREEN_ON = 0x00000080
FLAG_LAYOUT_IN_SCREEN = 0x00000100
FLAG_LAYOUT_NO_LIMITS = 0x00000200
FLAG_FULLSCREEN = 0x00000400
FLAG_FORCE_NOT_FULLSCREEN = 0x00000800
FLAG_DITHER = 0x00001000
FLAG_SECURE = 0x00002000
FLAG_SCALED = 0x00004000
FLAG_IGNORE_CHEEK_PRESSES = 0x00008000
FLAG_LAYOUT_INSET_DECOR = 0x00010000
FLAG_ALT_FOCUSABLE_IM = 0x00020000
FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000
FLAG_SHOW_WHEN_LOCKED = 0x00080000
FLAG_SHOW_WALLPAPER = 0x00100000
FLAG_TURN_SCREEN_ON = 0x00200000
FLAG_DISMISS_KEYGUARD = 0x00400000
FLAG_SPLIT_TOUCH = 0x00800000
FLAG_HARDWARE_ACCELERATED = 0x01000000
FLAG_LOCAL_FOCUS_MODE = 0x10000000
FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS = 0x20000000
FLAG_TRANSLUCENT_STATUS = 0x04000000
FLAG_TRANSLUCENT_NAVIGATION = 0x08000000
# 软输入模式
SOFT_INPUT_STATE_UNSPECIFIED = 0
SOFT_INPUT_STATE_UNCHANGED = 1
SOFT_INPUT_STATE_HIDDEN = 2
SOFT_INPUT_STATE_ALWAYS_HIDDEN = 3
SOFT_INPUT_STATE_VISIBLE = 4
SOFT_INPUT_STATE_ALWAYS_VISIBLE = 5
SOFT_INPUT_ADJUST_RESIZE = 0x10
SOFT_INPUT_ADJUST_PAN = 0x20
SOFT_INPUT_ADJUST_NOTHING = 0x30
SOFT_INPUT_ADJUST_UNSPECIFIED = 0x00
SOFT_INPUT_IS_FORWARD_NAVIGATION = 0x100
INVALID_DISPLAY = -1
DOCKED_INVALID = -1
DOCKED_LEFT = 1
DOCKED_TOP = 2
DOCKED_RIGHT = 3
DOCKED_BOTTOM = 4
class LayoutParams(Stub):
"""WindowManager.LayoutParams — 窗口布局参数"""
MATCH_PARENT = -1
WRAP_CONTENT = -2
def __init__(self, w: int = -1, h: int = -1, type_: int = 2, flags: int = 0):
super().__init__()
self.width = w
self.height = h
self.type = type_
self.flags = flags
self.x = 0
self.y = 0
self.horizontalWeight = 0.0
self.verticalWeight = 0.0
self.horizontalMargin = 0.0
self.verticalMargin = 0.0
self.gravity = 0
self.softInputMode = WindowManager.SOFT_INPUT_STATE_UNSPECIFIED
self.windowAnimations = -1
self.alpha = 1.0
self.dimAmount = 0.0
self.screenOrientation = -1
self.screenBrightness = -1.0
self.buttonBrightness = -1.0
self.token: Optional[Any] = None
self.packageName: Optional[str] = None
self.format = -1
self.systemUiVisibility = 0
self.subtreeSystemUiVisibility = 0
self.preferredRefreshRate: float = 0.0
self.colorMode = 0
def toString(self) -> str:
return f"LayoutParams({self.width}x{self.height}, type={self.type}, flags=0x{self.flags:x})"
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._default_display: Optional[Any] = None
self._current_window_focus: Optional[Any] = None
self._window_views: List[Any] = []
def getDefaultDisplay(self) -> Optional[Any]:
return self._default_display
def getCurrentWindowFocus(self) -> Optional[Any]:
return self._current_window_focus
def addView(self, view: Any, params: "WindowManager.LayoutParams") -> None:
self._window_views.append((view, params))
def updateViewLayout(self, view: Any, params: "WindowManager.LayoutParams") -> None:
for i, (v, p) in enumerate(self._window_views):
if v is view:
self._window_views[i] = (view, params)
break
def removeView(self, view: Any) -> None:
self._window_views = [(v, p) for v, p in self._window_views if v is not view]
def removeViewImmediate(self, view: Any) -> None:
self.removeView(view)
def getWindowViews(self) -> List[Any]:
return [v for v, _ in self._window_views]
def toString(self) -> str:
return f"WindowManager(views={len(self._window_views)})"
WindowManager_LayoutParams = WindowManager.LayoutParams