新增 _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 - 真实进程列表
969 lines
34 KiB
Python
969 lines
34 KiB
Python
"""
|
|
Android app.tasks 包 — TaskManager, TaskInfo, TaskStackListener,
|
|
ActivityManager 任务/进程/内存信息等
|
|
方法签名完全对齐 Android SDK
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import sys
|
|
import time
|
|
from typing import Any, Callable, Dict, List, Optional, Tuple
|
|
|
|
from .._core import Stub, AndroidOnlyError
|
|
|
|
try:
|
|
from .._linux_impl import IS_LINUX, LinuxProcess, LinuxPower
|
|
_USE_LINUX = IS_LINUX
|
|
except ImportError:
|
|
_USE_LINUX = False
|
|
|
|
__all__ = [
|
|
"TaskManager", "TaskInfo", "TaskStackListener", "TaskSnapshot",
|
|
"TaskDescription", "ActivityManager",
|
|
]
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# 常量
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
PROCESS_STATE_UNKNOWN = -1
|
|
PROCESS_STATE_PERSISTENT = 0
|
|
PROCESS_STATE_PERSISTENT_UI = 1
|
|
PROCESS_STATE_TOP = 2
|
|
PROCESS_STATE_BOUND_TOP = 3
|
|
PROCESS_STATE_FOREGROUND_SERVICE = 4
|
|
PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 5
|
|
PROCESS_STATE_IMPORTANT_FOREGROUND = 6
|
|
PROCESS_STATE_IMPORTANT_BACKGROUND = 7
|
|
PROCESS_STATE_TRANSIENT_BACKGROUND = 8
|
|
PROCESS_STATE_BACKUP = 9
|
|
PROCESS_STATE_SERVICE = 10
|
|
PROCESS_STATE_RECEIVER = 11
|
|
PROCESS_STATE_TOP_SLEEPING = 12
|
|
PROCESS_STATE_HEAVY_WEIGHT = 13
|
|
PROCESS_STATE_HOME = 14
|
|
PROCESS_STATE_LAST_ACTIVITY = 15
|
|
PROCESS_STATE_CACHED_ACTIVITY = 16
|
|
PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 17
|
|
PROCESS_STATE_CACHED_EMPTY = 18
|
|
|
|
IMPORTANCE_FOREGROUND = 100
|
|
IMPORTANCE_FOREGROUND_SERVICE = 125
|
|
IMPORTANCE_VISIBLE = 200
|
|
IMPORTANCE_SERVICE = 300
|
|
IMPORTANCE_CACHED = 400
|
|
IMPORTANCE_CANT_SAVE_STATE = 170
|
|
IMPORTANCE_GONE = 1000
|
|
IMPORTANCE_BACKGROUND = 500
|
|
IMPORTANCE_TOP_SLEEPING = 325
|
|
IMPORTANCE_HAS_PREVIOUS = 650
|
|
|
|
TASK_ID_NONE = -1
|
|
TASK_LOCK_STATE_UNLOCKED = 0
|
|
TASK_LOCK_STATE_LOCKED = 1
|
|
TASK_LOCK_STATE_PINNED = 2
|
|
|
|
TASK_NON_FULLSCREEN = 0
|
|
TASK_FULLSCREEN = 1
|
|
TASK_FLOATING = 2
|
|
TASK_SPLIT_SCREEN_PRIMARY = 3
|
|
TASK_SPLIT_SCREEN_SECONDARY = 4
|
|
TASK_FREEFORM = 5
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# TaskDescription
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class TaskDescription(Stub):
|
|
"""TaskDescription — 任务描述"""
|
|
|
|
def __init__(self, label: str = "", icon: Any = None, colorPrimary: int = 0,
|
|
colorBackground: int = 0, statusBarColor: int = 0,
|
|
navigationBarColor: int = 0):
|
|
super().__init__()
|
|
self._label = label
|
|
self._icon = icon
|
|
self._color_primary = colorPrimary
|
|
self._color_background = colorBackground
|
|
self._status_bar_color = statusBarColor
|
|
self._navigation_bar_color = navigationBarColor
|
|
|
|
def getLabel(self) -> str:
|
|
return self._label
|
|
|
|
def getIcon(self) -> Optional[Any]:
|
|
return self._icon
|
|
|
|
def getPrimaryColor(self) -> int:
|
|
return self._color_primary
|
|
|
|
def getBackgroundColor(self) -> int:
|
|
return self._color_background
|
|
|
|
def getStatusBarColor(self) -> int:
|
|
return self._status_bar_color
|
|
|
|
def getNavigationBarColor(self) -> int:
|
|
return self._navigation_bar_color
|
|
|
|
def toString(self) -> str:
|
|
return f"TaskDescription(label={self._label})"
|
|
|
|
def equals(self, other: Any) -> bool:
|
|
if not isinstance(other, TaskDescription):
|
|
return False
|
|
return self._label == other._label
|
|
|
|
def hashCode(self) -> int:
|
|
return hash(self._label) & 0x7FFFFFFF
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# TaskSnapshot
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class TaskSnapshot(Stub):
|
|
"""TaskSnapshot — 任务快照"""
|
|
|
|
def __init__(self, taskId: int = 0, snapshot: Any = None,
|
|
width: int = 0, height: int = 0,
|
|
isRealSnapshot: bool = True,
|
|
isTranslucent: bool = False,
|
|
isPrivate: bool = False,
|
|
topActivityComponent: str = "",
|
|
snapshotScale: float = 1.0):
|
|
super().__init__()
|
|
self._task_id = taskId
|
|
self._snapshot = snapshot
|
|
self._width = width
|
|
self._height = height
|
|
self._is_real_snapshot = isRealSnapshot
|
|
self._is_translucent = isTranslucent
|
|
self._is_private = isPrivate
|
|
self._top_activity = topActivityComponent
|
|
self._snapshot_scale = snapshotScale
|
|
|
|
def getTaskId(self) -> int:
|
|
return self._task_id
|
|
|
|
def getSnapshot(self) -> Any:
|
|
return self._snapshot
|
|
|
|
def getWidth(self) -> int:
|
|
return self._width
|
|
|
|
def getHeight(self) -> int:
|
|
return self._height
|
|
|
|
def isRealSnapshot(self) -> bool:
|
|
return self._is_real_snapshot
|
|
|
|
def isTranslucent(self) -> bool:
|
|
return self._is_translucent
|
|
|
|
def isPrivate(self) -> bool:
|
|
return self._is_private
|
|
|
|
def getTopActivityComponent(self) -> str:
|
|
return self._top_activity
|
|
|
|
def getSnapshotScale(self) -> float:
|
|
return self._snapshot_scale
|
|
|
|
def toString(self) -> str:
|
|
return f"TaskSnapshot(task={self._task_id}, size={self._width}x{self._height})"
|
|
|
|
def equals(self, other: Any) -> bool:
|
|
if not isinstance(other, TaskSnapshot):
|
|
return False
|
|
return self._task_id == other._task_id
|
|
|
|
def hashCode(self) -> int:
|
|
return self._task_id & 0x7FFFFFFF
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# TaskInfo
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class TaskInfo(Stub):
|
|
"""TaskInfo — 任务信息"""
|
|
|
|
def __init__(self, taskId: int = 0, baseIntent: Any = None,
|
|
baseActivity: Any = None, topActivity: Any = None,
|
|
origActivity: Any = None, description: Any = None,
|
|
numActivities: int = 0, numRunning: int = 0,
|
|
isRunning: bool = False, supportsSplitScreen: bool = False,
|
|
resizeMode: int = TASK_FULLSCREEN,
|
|
userId: int = 0, displayId: int = 0,
|
|
isVisible: bool = False, isPersistable: bool = True,
|
|
lockState: int = TASK_LOCK_STATE_UNLOCKED,
|
|
isRooted: bool = False,
|
|
pictureInPictureEnabled: bool = False):
|
|
super().__init__()
|
|
self._task_id = taskId
|
|
self._base_intent = baseIntent
|
|
self._base_activity = baseActivity
|
|
self._top_activity = topActivity
|
|
self._orig_activity = origActivity
|
|
self._description = description or TaskDescription()
|
|
self._num_activities = numActivities
|
|
self._num_running = numRunning
|
|
self._is_running = isRunning
|
|
self._supports_split_screen = supportsSplitScreen
|
|
self._resize_mode = resizeMode
|
|
self._user_id = userId
|
|
self._display_id = displayId
|
|
self._is_visible = isVisible
|
|
self._is_persistable = isPersistable
|
|
self._lock_state = lockState
|
|
self._is_rooted = isRooted
|
|
self._pip_enabled = pictureInPictureEnabled
|
|
|
|
def getTaskId(self) -> int:
|
|
return self._task_id
|
|
|
|
def getBaseIntent(self) -> Any:
|
|
return self._base_intent
|
|
|
|
def getBaseActivity(self) -> Any:
|
|
return self._base_activity
|
|
|
|
def getTopActivity(self) -> Any:
|
|
return self._top_activity
|
|
|
|
def getOrigActivity(self) -> Any:
|
|
return self._orig_activity
|
|
|
|
def getDescription(self) -> Any:
|
|
return self._description
|
|
|
|
def getNumActivities(self) -> int:
|
|
return self._num_activities
|
|
|
|
def getNumRunning(self) -> int:
|
|
return self._num_running
|
|
|
|
def isRunning(self) -> bool:
|
|
return self._is_running
|
|
|
|
def supportsSplitScreen(self) -> bool:
|
|
return self._supports_split_screen
|
|
|
|
def getResizeMode(self) -> int:
|
|
return self._resize_mode
|
|
|
|
def getUserId(self) -> int:
|
|
return self._user_id
|
|
|
|
def getDisplayId(self) -> int:
|
|
return self._display_id
|
|
|
|
def isVisible(self) -> bool:
|
|
return self._is_visible
|
|
|
|
def isPersistable(self) -> bool:
|
|
return self._is_persistable
|
|
|
|
def getLockState(self) -> int:
|
|
return self._lock_state
|
|
|
|
def isRooted(self) -> bool:
|
|
return self._is_rooted
|
|
|
|
def isPictureInPictureEnabled(self) -> bool:
|
|
return self._pip_enabled
|
|
|
|
def toString(self) -> str:
|
|
return (f"TaskInfo(id={self._task_id}, "
|
|
f"activities={self._num_activities}, "
|
|
f"running={self._is_running})")
|
|
|
|
def equals(self, other: Any) -> bool:
|
|
if not isinstance(other, TaskInfo):
|
|
return False
|
|
return self._task_id == other._task_id
|
|
|
|
def hashCode(self) -> int:
|
|
return self._task_id & 0x7FFFFFFF
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# TaskStackListener
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class TaskStackListener(Stub):
|
|
"""TaskStackListener — 任务栈监听器"""
|
|
|
|
def onTaskStackChanged(self):
|
|
pass
|
|
|
|
def onTaskCreated(self, taskId: int, componentName: Any):
|
|
pass
|
|
|
|
def onTaskRemoved(self, taskId: int):
|
|
pass
|
|
|
|
def onTaskMovedToFront(self, taskInfo: TaskInfo):
|
|
pass
|
|
|
|
def onTaskMovedToBack(self, taskInfo: TaskInfo):
|
|
pass
|
|
|
|
def onTaskDescriptionChanged(self, taskInfo: TaskInfo,
|
|
taskDescription: TaskDescription):
|
|
pass
|
|
|
|
def onTaskSnapshotChanged(self, taskId: int, snapshot: TaskSnapshot):
|
|
pass
|
|
|
|
def onTaskDisplayChanged(self, taskId: int, newDisplayId: int):
|
|
pass
|
|
|
|
def onTaskProfileLocked(self, taskId: int, userId: int):
|
|
pass
|
|
|
|
def onRecentTaskListUpdated(self):
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return f"TaskStackListener@{hex(id(self))}"
|
|
|
|
def equals(self, other: Any) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return id(self) & 0x7FFFFFFF
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# TaskManager
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class TaskManager(Stub):
|
|
"""TaskManager — 任务管理器"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._tasks: Dict[int, TaskInfo] = {}
|
|
self._listeners: Dict[int, TaskStackListener] = {}
|
|
self._snapshots: Dict[int, TaskSnapshot] = {}
|
|
self._next_id = 100
|
|
|
|
def getTasks(self, maxNum: int = 10) -> List[TaskInfo]:
|
|
return list(self._tasks.values())[:maxNum]
|
|
|
|
def getTaskInfo(self, taskId: int) -> Optional[TaskInfo]:
|
|
return self._tasks.get(taskId)
|
|
|
|
def getRecentTasks(self, maxNum: int = 10, flags: int = 0) -> List[TaskInfo]:
|
|
return list(self._tasks.values())[:maxNum]
|
|
|
|
def addTask(self, taskInfo: TaskInfo):
|
|
self._tasks[taskInfo.getTaskId()] = taskInfo
|
|
|
|
def removeTask(self, taskId: int):
|
|
self._tasks.pop(taskId, None)
|
|
|
|
def moveTaskToFront(self, taskId: int, flags: int = 0):
|
|
pass
|
|
|
|
def moveTaskToBack(self, taskId: int):
|
|
pass
|
|
|
|
def cancelTaskWindowTransition(self, taskId: int):
|
|
pass
|
|
|
|
def setTaskDescription(self, taskId: int, description: TaskDescription):
|
|
task = self._tasks.get(taskId)
|
|
if task:
|
|
self._tasks[taskId] = task
|
|
|
|
def takeTaskSnapshot(self, taskId: int) -> Optional[TaskSnapshot]:
|
|
return self._snapshots.get(taskId)
|
|
|
|
def registerTaskStackListener(self, listener: TaskStackListener):
|
|
lid = id(listener)
|
|
self._listeners[lid] = listener
|
|
|
|
def unregisterTaskStackListener(self, listener: TaskStackListener):
|
|
lid = id(listener)
|
|
self._listeners.pop(lid, None)
|
|
|
|
def createTask(self, componentName: str) -> int:
|
|
task_id = self._next_id
|
|
self._next_id += 1
|
|
task = TaskInfo(taskId=task_id, baseActivity=componentName, isRunning=True)
|
|
self._tasks[task_id] = task
|
|
return task_id
|
|
|
|
def getTaskCount(self) -> int:
|
|
return len(self._tasks)
|
|
|
|
def getRunningTaskCount(self) -> int:
|
|
return sum(1 for t in self._tasks.values() if t.isRunning())
|
|
|
|
def toString(self) -> str:
|
|
return f"TaskManager(tasks={len(self._tasks)})"
|
|
|
|
def equals(self, other: Any) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return id(self) & 0x7FFFFFFF
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# ActivityManager 任务/进程/内存信息内部类
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class ActivityManager(Stub):
|
|
"""ActivityManager — 活动管理器 (任务/进程/内存相关内部类)"""
|
|
|
|
RECENT_IGNORE_UNAVAILABLE = 0x00000002
|
|
RECENT_WITH_EXCLUDED = 0x00000001
|
|
RECENT_INCLUDE_PROFILES = 0x00000004
|
|
RECENT_INGORE_DOCKED_STACK_TOP = 0x00000008
|
|
RECENT_INGORE_PINNED_STACK = 0x00000010
|
|
|
|
START_SUCCESS = 0
|
|
START_INTENT_NOT_RESOLVED = -1
|
|
START_CLASS_NOT_FOUND = -2
|
|
START_FORWARD_AND_REQUEST_CONFLICT = -3
|
|
START_PERMISSION_DENIED = -4
|
|
START_NOT_ACTIVITY = -5
|
|
START_NOT_VOICE_COMPATIBLE = -6
|
|
START_NOT_CURRENT_USER = -7
|
|
START_RETURN_LOCK_ERROR = -8
|
|
START_LOCK_ERROR = -9
|
|
START_SWITCHES_CANCELED = -10
|
|
START_ABORTED = -11
|
|
|
|
MOVETASK_WITH_HOME = 0x00000001
|
|
MOVETASK_NO_ANIMATION = 0x00000002
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# RecentTaskInfo
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class RecentTaskInfo(Stub):
|
|
"""ActivityManager.RecentTaskInfo — 最近任务信息"""
|
|
|
|
def __init__(self, taskId: int = 0, baseIntent: Any = None,
|
|
origActivity: Any = None, description: Any = None,
|
|
userId: int = 0, persistentId: int = 0,
|
|
affiliatedTaskId: int = 0, affiliatedTaskColor: int = 0,
|
|
isExcluded: bool = False, isDockable: bool = True,
|
|
resizeMode: int = TASK_FULLSCREEN,
|
|
topActivity: Any = None, baseActivity: Any = None):
|
|
super().__init__()
|
|
self._task_id = taskId
|
|
self._base_intent = baseIntent
|
|
self._orig_activity = origActivity
|
|
self._description = description
|
|
self._user_id = userId
|
|
self._persistent_id = persistentId
|
|
self._affiliated_task_id = affiliatedTaskId
|
|
self._affiliated_task_color = affiliatedTaskColor
|
|
self._is_excluded = isExcluded
|
|
self._is_dockable = isDockable
|
|
self._resize_mode = resizeMode
|
|
self._top_activity = topActivity
|
|
self._base_activity = baseActivity
|
|
|
|
def getTaskId(self) -> int:
|
|
return self._task_id
|
|
|
|
def getBaseIntent(self) -> Any:
|
|
return self._base_intent
|
|
|
|
def getOrigActivity(self) -> Any:
|
|
return self._orig_activity
|
|
|
|
def getDescription(self) -> Any:
|
|
return self._description
|
|
|
|
def getUserId(self) -> int:
|
|
return self._user_id
|
|
|
|
def getPersistentId(self) -> int:
|
|
return self._persistent_id
|
|
|
|
def getAffiliatedTaskId(self) -> int:
|
|
return self._affiliated_task_id
|
|
|
|
def getAffiliatedTaskColor(self) -> int:
|
|
return self._affiliated_task_color
|
|
|
|
def isExcluded(self) -> bool:
|
|
return self._is_excluded
|
|
|
|
def isDockable(self) -> bool:
|
|
return self._is_dockable
|
|
|
|
def getResizeMode(self) -> int:
|
|
return self._resize_mode
|
|
|
|
def getTopActivity(self) -> Any:
|
|
return self._top_activity
|
|
|
|
def getBaseActivity(self) -> Any:
|
|
return self._base_activity
|
|
|
|
def toString(self) -> str:
|
|
return f"RecentTaskInfo(id={self._task_id})"
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# AppTask
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class AppTask(Stub):
|
|
"""ActivityManager.AppTask — 应用任务"""
|
|
|
|
def __init__(self, taskInfo: Optional[RecentTaskInfo] = None):
|
|
super().__init__()
|
|
self._task_info = taskInfo
|
|
|
|
def getTaskInfo(self) -> Optional["ActivityManager.RecentTaskInfo"]:
|
|
return self._task_info
|
|
|
|
def moveToFront(self):
|
|
pass
|
|
|
|
def startActivity(self, intent: Any, options: Any = None):
|
|
pass
|
|
|
|
def setExcludeFromRecents(self, exclude: bool):
|
|
pass
|
|
|
|
def finishAndRemoveTask(self):
|
|
pass
|
|
|
|
def setTaskDescription(self, description: TaskDescription):
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return f"AppTask(info={self._task_info})"
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# StackInfo
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class StackInfo(Stub):
|
|
"""ActivityManager.StackInfo — 栈信息"""
|
|
|
|
def __init__(self, stackId: int = 0, bounds: Any = None,
|
|
taskIds: List[int] = None, taskNames: List[str] = None,
|
|
displayId: int = 0, topActivity: Any = None,
|
|
visible: bool = False, position: int = 0,
|
|
isWindowingMode: int = TASK_FULLSCREEN):
|
|
super().__init__()
|
|
self._stack_id = stackId
|
|
self._bounds = bounds
|
|
self._task_ids = taskIds or []
|
|
self._task_names = taskNames or []
|
|
self._display_id = displayId
|
|
self._top_activity = topActivity
|
|
self._visible = visible
|
|
self._position = position
|
|
self._windowing_mode = isWindowingMode
|
|
|
|
def getStackId(self) -> int:
|
|
return self._stack_id
|
|
|
|
def getBounds(self) -> Any:
|
|
return self._bounds
|
|
|
|
def getTaskIds(self) -> List[int]:
|
|
return list(self._task_ids)
|
|
|
|
def getTaskNames(self) -> List[str]:
|
|
return list(self._task_names)
|
|
|
|
def getDisplayId(self) -> int:
|
|
return self._display_id
|
|
|
|
def getTopActivity(self) -> Any:
|
|
return self._top_activity
|
|
|
|
def isVisible(self) -> bool:
|
|
return self._visible
|
|
|
|
def getPosition(self) -> int:
|
|
return self._position
|
|
|
|
def getWindowingMode(self) -> int:
|
|
return self._windowing_mode
|
|
|
|
def toString(self) -> str:
|
|
return f"StackInfo(id={self._stack_id}, tasks={len(self._task_ids)})"
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# RunningTaskInfo
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class RunningTaskInfo(Stub):
|
|
"""ActivityManager.RunningTaskInfo — 运行中任务信息"""
|
|
|
|
def __init__(self, taskId: int = 0, baseActivity: Any = None,
|
|
topActivity: Any = None, numActivities: int = 0,
|
|
numRunning: int = 0, description: Any = None,
|
|
thumbnail: Any = None, isRunning: bool = True):
|
|
super().__init__()
|
|
self._task_id = taskId
|
|
self._base_activity = baseActivity
|
|
self._top_activity = topActivity
|
|
self._num_activities = numActivities
|
|
self._num_running = numRunning
|
|
self._description = description
|
|
self._thumbnail = thumbnail
|
|
self._is_running = isRunning
|
|
|
|
def getTaskId(self) -> int:
|
|
return self._task_id
|
|
|
|
def getBaseActivity(self) -> Any:
|
|
return self._base_activity
|
|
|
|
def getTopActivity(self) -> Any:
|
|
return self._top_activity
|
|
|
|
def getNumActivities(self) -> int:
|
|
return self._num_activities
|
|
|
|
def getNumRunning(self) -> int:
|
|
return self._num_running
|
|
|
|
def getDescription(self) -> Any:
|
|
return self._description
|
|
|
|
def getThumbnail(self) -> Any:
|
|
return self._thumbnail
|
|
|
|
def isRunning(self) -> bool:
|
|
return self._is_running
|
|
|
|
def toString(self) -> str:
|
|
return f"RunningTaskInfo(id={self._task_id}, activities={self._num_activities})"
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# RunningServiceInfo
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class RunningServiceInfo(Stub):
|
|
"""ActivityManager.RunningServiceInfo — 运行中服务信息"""
|
|
|
|
def __init__(self, service: Any = None, process: str = "",
|
|
uid: int = 0, pid: int = 0, clientCount: int = 0,
|
|
clientLabel: int = 0, clientPackage: str = "",
|
|
crashCount: int = 0, flags: int = 0,
|
|
started: bool = False, foreground: bool = False,
|
|
restarting: bool = False):
|
|
super().__init__()
|
|
self._service = service
|
|
self._process = process
|
|
self._uid = uid
|
|
self._pid = pid
|
|
self._client_count = clientCount
|
|
self._client_label = clientLabel
|
|
self._client_package = clientPackage
|
|
self._crash_count = crashCount
|
|
self._flags = flags
|
|
self._started = started
|
|
self._foreground = foreground
|
|
self._restarting = restarting
|
|
|
|
def getService(self) -> Any:
|
|
return self._service
|
|
|
|
def getProcess(self) -> str:
|
|
return self._process
|
|
|
|
def getUid(self) -> int:
|
|
return self._uid
|
|
|
|
def getPid(self) -> int:
|
|
return self._pid
|
|
|
|
def getClientCount(self) -> int:
|
|
return self._client_count
|
|
|
|
def getClientLabel(self) -> int:
|
|
return self._client_label
|
|
|
|
def getClientPackage(self) -> str:
|
|
return self._client_package
|
|
|
|
def getCrashCount(self) -> int:
|
|
return self._crash_count
|
|
|
|
def getFlags(self) -> int:
|
|
return self._flags
|
|
|
|
def isStarted(self) -> bool:
|
|
return self._started
|
|
|
|
def isForeground(self) -> bool:
|
|
return self._foreground
|
|
|
|
def isRestarting(self) -> bool:
|
|
return self._restarting
|
|
|
|
def toString(self) -> str:
|
|
return f"RunningServiceInfo(service={self._service}, pid={self._pid})"
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# RunningAppProcessInfo
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class RunningAppProcessInfo(Stub):
|
|
"""ActivityManager.RunningAppProcessInfo — 运行中应用进程信息"""
|
|
|
|
IMPORTANCE_FOREGROUND = IMPORTANCE_FOREGROUND
|
|
IMPORTANCE_FOREGROUND_SERVICE = IMPORTANCE_FOREGROUND_SERVICE
|
|
IMPORTANCE_VISIBLE = IMPORTANCE_VISIBLE
|
|
IMPORTANCE_SERVICE = IMPORTANCE_SERVICE
|
|
IMPORTANCE_CACHED = IMPORTANCE_CACHED
|
|
IMPORTANCE_GONE = IMPORTANCE_GONE
|
|
IMPORTANCE_BACKGROUND = IMPORTANCE_BACKGROUND
|
|
IMPORTANCE_TOP_SLEEPING = IMPORTANCE_TOP_SLEEPING
|
|
|
|
REASON_UNKNOWN = 0
|
|
REASON_PROVIDER_IN_USE = 1
|
|
REASON_SERVICE_IN_USE = 2
|
|
REASON_BACKGROUND = 3
|
|
REASON_CRASH = 4
|
|
REASON_ANR = 5
|
|
REASON_LOW_MEMORY = 6
|
|
REASON_USER_STOPPED = 7
|
|
REASON_PERMISSION_CHANGE = 8
|
|
REASON_ABORTED = 9
|
|
|
|
def __init__(self, processName: str = "", pid: int = 0,
|
|
uid: int = 0, pkgList: List[str] = None,
|
|
importance: int = IMPORTANCE_FOREGROUND,
|
|
importanceReasonCode: int = REASON_UNKNOWN,
|
|
importanceReasonPid: int = 0,
|
|
importanceReasonComponent: Any = None,
|
|
lastActivityTime: int = 0,
|
|
lru: int = 0):
|
|
super().__init__()
|
|
self.processName = processName
|
|
self.pid = pid
|
|
self.uid = uid
|
|
self.pkgList = pkgList or []
|
|
self.importance = importance
|
|
self.importanceReasonCode = importanceReasonCode
|
|
self.importanceReasonPid = importanceReasonPid
|
|
self.importanceReasonComponent = importanceReasonComponent
|
|
self.lastActivityTime = lastActivityTime
|
|
self.lru = lru
|
|
|
|
def getProcessName(self) -> str:
|
|
return self.processName
|
|
|
|
def getPid(self) -> int:
|
|
return self.pid
|
|
|
|
def getUid(self) -> int:
|
|
return self.uid
|
|
|
|
def getPackageList(self) -> List[str]:
|
|
return list(self.pkgList)
|
|
|
|
def getImportance(self) -> int:
|
|
return self.importance
|
|
|
|
def getImportanceReasonCode(self) -> int:
|
|
return self.importanceReasonCode
|
|
|
|
def getImportanceReasonPid(self) -> int:
|
|
return self.importanceReasonPid
|
|
|
|
def getImportanceReasonComponent(self) -> Any:
|
|
return self.importanceReasonComponent
|
|
|
|
def toString(self) -> str:
|
|
return (f"RunningAppProcessInfo(process={self.processName}, "
|
|
f"pid={self.pid}, importance={self.importance})")
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# ProcessErrorStateInfo
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class ProcessErrorStateInfo(Stub):
|
|
"""ActivityManager.ProcessErrorStateInfo — 进程错误状态信息"""
|
|
|
|
CRASHED = 1
|
|
NOT_RESPONDING = 2
|
|
NO_ERROR = 0
|
|
|
|
def __init__(self, condition: int = NO_ERROR, processName: str = "",
|
|
pid: int = 0, uid: int = 0, tag: str = "",
|
|
shortMessage: str = "", longMessage: str = "",
|
|
crashedApp: str = "",
|
|
stackTrace: str = ""):
|
|
super().__init__()
|
|
self._condition = condition
|
|
self._process_name = processName
|
|
self._pid = pid
|
|
self._uid = uid
|
|
self._tag = tag
|
|
self._short_message = shortMessage
|
|
self._long_message = longMessage
|
|
self._crash_app = crashedApp
|
|
self._stack_trace = stackTrace
|
|
|
|
def getCondition(self) -> int:
|
|
return self._condition
|
|
|
|
def getProcessName(self) -> str:
|
|
return self._process_name
|
|
|
|
def getPid(self) -> int:
|
|
return self._pid
|
|
|
|
def getUid(self) -> int:
|
|
return self._uid
|
|
|
|
def getTag(self) -> str:
|
|
return self._tag
|
|
|
|
def getShortMessage(self) -> str:
|
|
return self._short_message
|
|
|
|
def getLongMessage(self) -> str:
|
|
return self._long_message
|
|
|
|
def getCrashApp(self) -> str:
|
|
return self._crash_app
|
|
|
|
def getStackTrace(self) -> str:
|
|
return self._stack_trace
|
|
|
|
def toString(self) -> str:
|
|
return (f"ProcessErrorStateInfo(condition={self._condition}, "
|
|
f"process={self._process_name})")
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# MemoryInfo
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class MemoryInfo(Stub):
|
|
"""ActivityManager.MemoryInfo — 内存信息"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.availMem: int = 0
|
|
self.totalMem: int = 0
|
|
self.threshold: int = 0
|
|
self.lowMemory: bool = False
|
|
self.hiddenAppThreshold: int = 0
|
|
self.secondaryServerThreshold: int = 0
|
|
self.visibleAppThreshold: int = 0
|
|
self.foregroundAppThreshold: int = 0
|
|
|
|
def getAvailMem(self) -> int:
|
|
return self.availMem
|
|
|
|
def getTotalMem(self) -> int:
|
|
return self.totalMem
|
|
|
|
def getThreshold(self) -> int:
|
|
return self.threshold
|
|
|
|
def isLowMemory(self) -> bool:
|
|
return self.lowMemory
|
|
|
|
def getHiddenAppThreshold(self) -> int:
|
|
return self.hiddenAppThreshold
|
|
|
|
def getSecondaryServerThreshold(self) -> int:
|
|
return self.secondaryServerThreshold
|
|
|
|
def getVisibleAppThreshold(self) -> int:
|
|
return self.visibleAppThreshold
|
|
|
|
def getForegroundAppThreshold(self) -> int:
|
|
return self.foregroundAppThreshold
|
|
|
|
def toString(self) -> str:
|
|
avail_mb = self.availMem / (1024 * 1024)
|
|
total_mb = self.totalMem / (1024 * 1024)
|
|
return (f"MemoryInfo(avail={avail_mb:.0f}MB, "
|
|
f"total={total_mb:.0f}MB, "
|
|
f"lowMemory={self.lowMemory})")
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._tasks: Dict[int, ActivityManager.RecentTaskInfo] = {}
|
|
self._processes: Dict[int, ActivityManager.RunningAppProcessInfo] = {}
|
|
self._services: Dict[int, ActivityManager.RunningServiceInfo] = {}
|
|
|
|
def getRecentTasks(self, maxNum: int, flags: int) -> List[RecentTaskInfo]:
|
|
return list(self._tasks.values())[:maxNum]
|
|
|
|
def getRunningTasks(self, maxNum: int) -> List[RunningTaskInfo]:
|
|
return []
|
|
|
|
def getRunningServices(self, maxNum: int) -> List[RunningServiceInfo]:
|
|
return list(self._services.values())[:maxNum]
|
|
|
|
def getRunningAppProcesses(self) -> List[RunningAppProcessInfo]:
|
|
if _USE_LINUX:
|
|
return LinuxProcess.list_processes()
|
|
return list(self._processes.values())
|
|
|
|
def getMemoryInfo(self, outInfo: MemoryInfo):
|
|
if _USE_LINUX:
|
|
mem = LinuxPower.get_memory_info()
|
|
outInfo.availMem = mem.get("available", 0)
|
|
outInfo.totalMem = mem.get("total", 0)
|
|
outInfo.threshold = int(mem.get("total", 0) * 0.1)
|
|
outInfo.lowMemory = mem.get("percent", 0) > 90.0
|
|
return outInfo
|
|
import psutil
|
|
try:
|
|
import psutil
|
|
mem = psutil.virtual_memory()
|
|
outInfo.availMem = mem.available
|
|
outInfo.totalMem = mem.total
|
|
outInfo.threshold = int(mem.total * 0.1)
|
|
outInfo.lowMemory = mem.percent > 90.0
|
|
except ImportError:
|
|
outInfo.totalMem = 8 * 1024 * 1024 * 1024
|
|
outInfo.availMem = 4 * 1024 * 1024 * 1024
|
|
outInfo.threshold = outInfo.totalMem // 10
|
|
|
|
def getMyMemoryState(self, outInfo: RunningAppProcessInfo):
|
|
outInfo.uid = os.getuid()
|
|
outInfo.pid = os.getpid()
|
|
outInfo.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
|
|
|
|
def isLowRamDevice(self) -> bool:
|
|
return False
|
|
|
|
def clearApplicationUserData(self) -> bool:
|
|
return False
|
|
|
|
def killBackgroundProcesses(self, packageName: str):
|
|
pass
|
|
|
|
def restartPackage(self, packageName: str):
|
|
pass
|
|
|
|
def getProcessMemoryInfo(self, pids: List[int]) -> List[Any]:
|
|
return []
|
|
|
|
def toString(self) -> str:
|
|
return f"ActivityManager(tasks={len(self._tasks)}, processes={len(self._processes)})"
|
|
|
|
def equals(self, other: Any) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return id(self) & 0x7FFFFFFF |