801 lines
31 KiB
Python
801 lines
31 KiB
Python
"""
|
|
Android PackageManager 组件 — PackageManager, PackageInfo, ApplicationInfo 等
|
|
方法签名完全对齐 Android SDK
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import sys
|
|
from typing import Any, Dict, List, Optional, Set
|
|
|
|
from .._core import (
|
|
Stub, AndroidOnlyError, android_context,
|
|
resolve_android_path, to_android_path,
|
|
_sdcard_root, _app_data_dir, _package_name,
|
|
)
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# 数据存储路径
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
_PACKAGE_DATA_DIR = os.path.join(_app_data_dir, "package_data")
|
|
os.makedirs(_PACKAGE_DATA_DIR, exist_ok=True)
|
|
|
|
_DEFAULT_PACKAGE_INFO_PATH = os.path.join(_PACKAGE_DATA_DIR, f"{_package_name}.json")
|
|
|
|
|
|
def _get_default_package_info() -> Dict[str, Any]:
|
|
"""获取默认包信息"""
|
|
return {
|
|
"packageName": _package_name,
|
|
"versionName": "1.0.0",
|
|
"versionCode": 1,
|
|
"applicationInfo": {
|
|
"name": _package_name,
|
|
"packageName": _package_name,
|
|
"className": f"{_package_name}.MainApplication",
|
|
"icon": 0,
|
|
"targetSdkVersion": 34,
|
|
"sourceDir": os.path.join(_app_data_dir, "base.apk"),
|
|
"dataDir": _app_data_dir,
|
|
"enabled": True,
|
|
"flags": 0,
|
|
"theme": 0,
|
|
"labelRes": 0,
|
|
"descriptionRes": 0,
|
|
"logo": 0,
|
|
"banner": 0,
|
|
"processName": _package_name,
|
|
"uid": 10001,
|
|
"manageSpaceActivityName": "",
|
|
"taskAffinity": "",
|
|
"permission": "",
|
|
},
|
|
"activities": [],
|
|
"services": [],
|
|
"receivers": [],
|
|
"providers": [],
|
|
"permissions": [],
|
|
"requestedPermissions": [
|
|
"android.permission.INTERNET",
|
|
"android.permission.ACCESS_NETWORK_STATE",
|
|
],
|
|
"features": {
|
|
"android.hardware.camera": True,
|
|
"android.hardware.wifi": True,
|
|
"android.hardware.bluetooth": True,
|
|
"android.hardware.location": True,
|
|
"android.hardware.sensor.accelerometer": True,
|
|
"android.hardware.sensor.gyroscope": True,
|
|
"android.hardware.touchscreen": True,
|
|
"android.hardware.microphone": True,
|
|
"android.hardware.nfc": False,
|
|
"android.hardware.telephony": True,
|
|
"android.software.picture_in_picture": True,
|
|
"android.hardware.usb.host": False,
|
|
}
|
|
}
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# PackageItemInfo (基类)
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class PackageItemInfo(Stub):
|
|
"""PackageItemInfo — 包条目信息基类"""
|
|
|
|
def __init__(self, data: Optional[Dict[str, Any]] = None):
|
|
super().__init__()
|
|
data = data or {}
|
|
self.name = data.get("name", "")
|
|
self.packageName = data.get("packageName", "")
|
|
self.labelRes = data.get("labelRes", 0)
|
|
self.nonLocalizedLabel = data.get("nonLocalizedLabel", None)
|
|
self.icon = data.get("icon", 0)
|
|
self.banner = data.get("banner", 0)
|
|
self.logo = data.get("logo", 0)
|
|
|
|
def loadLabel(self, pm: "PackageManager") -> str:
|
|
return self.nonLocalizedLabel or self.name.split(".")[-1] if self.name else ""
|
|
|
|
def loadIcon(self, pm: "PackageManager") -> Any:
|
|
return None
|
|
|
|
def loadLogo(self, pm: "PackageManager") -> Any:
|
|
return None
|
|
|
|
def loadBanner(self, pm: "PackageManager") -> Any:
|
|
return None
|
|
|
|
def toString(self) -> str:
|
|
return f"{self.__class__.__name__}({self.packageName}:{self.name})"
|
|
|
|
|
|
class ComponentInfo(PackageItemInfo):
|
|
"""ComponentInfo — 组件信息基类"""
|
|
|
|
def __init__(self, data: Optional[Dict[str, Any]] = None):
|
|
super().__init__(data)
|
|
data = data or {}
|
|
self.processName = data.get("processName", self.packageName)
|
|
self.splitName = data.get("splitName", None)
|
|
self.enabled = data.get("enabled", True)
|
|
self.exported = data.get("exported", False)
|
|
self.directBootAware = data.get("directBootAware", False)
|
|
|
|
def getComponentName(self) -> Any:
|
|
from .content import ComponentName
|
|
return ComponentName(self.packageName, self.name)
|
|
|
|
def isEnabled(self) -> bool:
|
|
return self.enabled
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# ApplicationInfo
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class ApplicationInfo(ComponentInfo):
|
|
"""ApplicationInfo — 应用信息"""
|
|
|
|
FLAG_SYSTEM = 1
|
|
FLAG_DEBUGGABLE = 2
|
|
FLAG_HAS_CODE = 4
|
|
FLAG_ALLOW_CLEAR_USER_DATA = 0x00400000
|
|
FLAG_ALLOW_BACKUP = 0x00008000
|
|
FLAG_EXTERNAL_STORAGE = 0x00100000
|
|
FLAG_LARGE_HEAP = 0x00100000
|
|
FLAG_MULTIPROCESS = 0x00010000
|
|
FLAG_TEST_ONLY = 0x00000100
|
|
FLAG_STOPPED = 0x00200000
|
|
FLAG_RESTART_ON_UPGRADE = 0x00000020
|
|
|
|
def __init__(self, data: Optional[Dict[str, Any]] = None):
|
|
super().__init__(data)
|
|
data = data or {}
|
|
self.taskAffinity = data.get("taskAffinity", "")
|
|
self.permission = data.get("permission", "")
|
|
self.processName = data.get("processName", self.packageName)
|
|
self.className = data.get("className", "")
|
|
self.descriptionRes = data.get("descriptionRes", 0)
|
|
self.theme = data.get("theme", 0)
|
|
self.flags = data.get("flags", 0)
|
|
self.sourceDir = data.get("sourceDir", "")
|
|
self.publicSourceDir = data.get("publicSourceDir", self.sourceDir)
|
|
self.dataDir = data.get("dataDir", "")
|
|
self.nativeLibraryDir = data.get("nativeLibraryDir", "")
|
|
self.metaData = data.get("metaData", None)
|
|
self.manageSpaceActivityName = data.get("manageSpaceActivityName", "")
|
|
self.targetSdkVersion = data.get("targetSdkVersion", 34)
|
|
self.uid = data.get("uid", 10001)
|
|
self.backupAgentName = data.get("backupAgentName", "")
|
|
self.enabled = data.get("enabled", True)
|
|
|
|
def loadDescription(self, pm: "PackageManager") -> Optional[str]:
|
|
return None
|
|
|
|
def toString(self) -> str:
|
|
return f"ApplicationInfo({self.packageName}, targetSdk={self.targetSdkVersion})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# ActivityInfo
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class ActivityInfo(ComponentInfo):
|
|
"""ActivityInfo — Activity 组件信息"""
|
|
|
|
CONFIG_MCC = 0x0001
|
|
CONFIG_MNC = 0x0002
|
|
CONFIG_LOCALE = 0x0004
|
|
CONFIG_TOUCHSCREEN = 0x0008
|
|
CONFIG_KEYBOARD = 0x0010
|
|
CONFIG_KEYBOARD_HIDDEN = 0x0020
|
|
CONFIG_NAVIGATION = 0x0040
|
|
CONFIG_ORIENTATION = 0x0080
|
|
CONFIG_SCREEN_LAYOUT = 0x0100
|
|
CONFIG_UI_MODE = 0x0200
|
|
CONFIG_SCREEN_SIZE = 0x0400
|
|
CONFIG_SMALLEST_SCREEN_SIZE = 0x0800
|
|
CONFIG_DENSITY = 0x1000
|
|
CONFIG_LAYOUT_DIRECTION = 0x2000
|
|
CONFIG_COLOR_MODE = 0x4000
|
|
|
|
LAUNCH_MULTIPLE = 0
|
|
LAUNCH_SINGLE_TOP = 1
|
|
LAUNCH_SINGLE_TASK = 2
|
|
LAUNCH_SINGLE_INSTANCE = 3
|
|
LAUNCH_SINGLE_INSTANCE_PER_TASK = 4
|
|
|
|
SCREEN_ORIENTATION_UNSPECIFIED = -1
|
|
SCREEN_ORIENTATION_LANDSCAPE = 0
|
|
SCREEN_ORIENTATION_PORTRAIT = 1
|
|
SCREEN_ORIENTATION_USER = 2
|
|
SCREEN_ORIENTATION_BEHIND = 3
|
|
SCREEN_ORIENTATION_SENSOR = 4
|
|
SCREEN_ORIENTATION_NOSENSOR = 5
|
|
SCREEN_ORIENTATION_SENSOR_LANDSCAPE = 6
|
|
SCREEN_ORIENTATION_SENSOR_PORTRAIT = 7
|
|
SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8
|
|
SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9
|
|
SCREEN_ORIENTATION_FULL_SENSOR = 10
|
|
SCREEN_ORIENTATION_USER_LANDSCAPE = 11
|
|
SCREEN_ORIENTATION_USER_PORTRAIT = 12
|
|
SCREEN_ORIENTATION_FULL_USER = 13
|
|
SCREEN_ORIENTATION_LOCKED = 14
|
|
|
|
def __init__(self, data: Optional[Dict[str, Any]] = None):
|
|
super().__init__(data)
|
|
data = data or {}
|
|
self.launchMode = data.get("launchMode", self.LAUNCH_MULTIPLE)
|
|
self.screenOrientation = data.get("screenOrientation", self.SCREEN_ORIENTATION_UNSPECIFIED)
|
|
self.configChanges = data.get("configChanges", 0)
|
|
self.softInputMode = data.get("softInputMode", 0)
|
|
self.theme = data.get("theme", 0)
|
|
self.parentActivityName = data.get("parentActivityName", "")
|
|
self.permission = data.get("permission", "")
|
|
self.taskAffinity = data.get("taskAffinity", "")
|
|
self.targetActivity = data.get("targetActivity", "")
|
|
|
|
def toString(self) -> str:
|
|
return f"ActivityInfo({self.name}, launchMode={self.launchMode})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# ServiceInfo
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class ServiceInfo(ComponentInfo):
|
|
"""ServiceInfo — Service 组件信息"""
|
|
|
|
FLAG_STOP_WITH_TASK = 0x01
|
|
FLAG_ISOLATED_PROCESS = 0x02
|
|
FLAG_EXTERNAL_SERVICE = 0x04
|
|
FLAG_SINGLE_USER = 0x40000000
|
|
FLAG_USE_APP_OP = 0x08
|
|
|
|
def __init__(self, data: Optional[Dict[str, Any]] = None):
|
|
super().__init__(data)
|
|
data = data or {}
|
|
self.flags = data.get("flags", 0)
|
|
self.permission = data.get("permission", "")
|
|
self.foregroundServiceType = data.get("foregroundServiceType", 0)
|
|
|
|
def toString(self) -> str:
|
|
return f"ServiceInfo({self.name})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# ProviderInfo
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class ProviderInfo(ComponentInfo):
|
|
"""ProviderInfo — ContentProvider 组件信息"""
|
|
|
|
def __init__(self, data: Optional[Dict[str, Any]] = None):
|
|
super().__init__(data)
|
|
data = data or {}
|
|
self.authority = data.get("authority", "")
|
|
self.readPermission = data.get("readPermission", "")
|
|
self.writePermission = data.get("writePermission", "")
|
|
self.grantUriPermissions = data.get("grantUriPermissions", False)
|
|
self.multiprocess = data.get("multiprocess", False)
|
|
self.initOrder = data.get("initOrder", 0)
|
|
self.flags = data.get("flags", 0)
|
|
|
|
def toString(self) -> str:
|
|
return f"ProviderInfo({self.name}, authority={self.authority})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# PermissionInfo
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class PermissionInfo(PackageItemInfo):
|
|
"""PermissionInfo — 权限信息"""
|
|
|
|
PROTECTION_NORMAL = 0
|
|
PROTECTION_DANGEROUS = 1
|
|
PROTECTION_SIGNATURE = 2
|
|
PROTECTION_SIGNATURE_OR_SYSTEM = 3
|
|
PROTECTION_INTERNAL = 4
|
|
|
|
FLAG_COSTS_MONEY = 0x01
|
|
FLAG_HARDWARE_RESTRICTED = 0x04
|
|
FLAG_IMMUTABLY_RESTRICTED = 0x08
|
|
FLAG_INSTALLED = 0x10
|
|
|
|
def __init__(self, data: Optional[Dict[str, Any]] = None):
|
|
super().__init__(data)
|
|
data = data or {}
|
|
self.group = data.get("group", "")
|
|
self.descriptionRes = data.get("descriptionRes", 0)
|
|
self.protectionLevel = data.get("protectionLevel", self.PROTECTION_NORMAL)
|
|
self.flags = data.get("flags", 0)
|
|
|
|
def loadDescription(self, pm: "PackageManager") -> Optional[str]:
|
|
return None
|
|
|
|
def toString(self) -> str:
|
|
return f"PermissionInfo({self.name}, protectionLevel={self.protectionLevel})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# ResolveInfo
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class ResolveInfo(Stub):
|
|
"""ResolveInfo — 解析意图的结果"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.activityInfo: Optional[ActivityInfo] = None
|
|
self.serviceInfo: Optional[ServiceInfo] = None
|
|
self.providerInfo: Optional[ProviderInfo] = None
|
|
self.filter: Optional[Any] = None
|
|
self.priority = 0
|
|
self.match = 0
|
|
self.preferredOrder = 0
|
|
self.isDefault = False
|
|
self.labelRes = 0
|
|
self.nonLocalizedLabel = None
|
|
self.icon = 0
|
|
self.resolvePackageName = ""
|
|
self.specificIndex = -1
|
|
self.system = False
|
|
|
|
def loadLabel(self, pm: "PackageManager") -> str:
|
|
if self.activityInfo:
|
|
return self.activityInfo.name.split(".")[-1]
|
|
if self.serviceInfo:
|
|
return self.serviceInfo.name.split(".")[-1]
|
|
return ""
|
|
|
|
def loadIcon(self, pm: "PackageManager"):
|
|
return None
|
|
|
|
def getIconResource(self) -> int:
|
|
return self.icon
|
|
|
|
def toString(self) -> str:
|
|
return f"ResolveInfo(priority={self.priority})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# PackageInfo
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class PackageInfo(Stub):
|
|
"""PackageInfo — 包信息"""
|
|
|
|
INSTALL_LOCATION_AUTO = 0
|
|
INSTALL_LOCATION_INTERNAL_ONLY = 1
|
|
INSTALL_LOCATION_PREFER_EXTERNAL = 2
|
|
REQUESTED_PERMISSION_REQUIRED = 0x00100000
|
|
REQUESTED_PERMISSION_GRANTED = 0x01000000
|
|
REQUESTED_PERMISSION_DENIED = 0x02000000
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.packageName = ""
|
|
self.versionName = ""
|
|
self.versionCode = 0
|
|
self.applicationInfo: Optional[ApplicationInfo] = None
|
|
self.activities: List[ActivityInfo] = []
|
|
self.services: List[ServiceInfo] = []
|
|
self.receivers: List[ActivityInfo] = []
|
|
self.providers: List[ProviderInfo] = []
|
|
self.permissions: List[PermissionInfo] = []
|
|
self.requestedPermissions: List[str] = []
|
|
self.requestedPermissionsFlags: List[int] = []
|
|
self.sharedUserId = ""
|
|
self.sharedUserLabel = 0
|
|
self.firstInstallTime = 0
|
|
self.lastUpdateTime = 0
|
|
self.gids: List[int] = []
|
|
self.installLocation = self.INSTALL_LOCATION_AUTO
|
|
self.configPreferences: List = []
|
|
self.featureGroups: List = []
|
|
self.packageName_ = ""
|
|
|
|
def toString(self) -> str:
|
|
return (f"PackageInfo({self.packageName} v{self.versionName} "
|
|
f"code={self.versionCode})")
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# Signature
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class Signature(Stub):
|
|
"""Signature — APK 签名"""
|
|
|
|
def __init__(self, signature: str = ""):
|
|
super().__init__()
|
|
self._signature = signature
|
|
|
|
def toCharsString(self) -> str:
|
|
return self._signature
|
|
|
|
def toByteArray(self) -> bytes:
|
|
return self._signature.encode("utf-8") if self._signature else b""
|
|
|
|
def equals(self, other) -> bool:
|
|
if isinstance(other, Signature):
|
|
return self._signature == other._signature
|
|
return False
|
|
|
|
def hashCode(self) -> int:
|
|
return hash(self._signature) & 0x7FFFFFFF
|
|
|
|
def toString(self) -> str:
|
|
return self._signature[:64] if len(self._signature) > 64 else self._signature
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# PackageStats
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class PackageStats(Stub):
|
|
"""PackageStats — 包存储统计"""
|
|
|
|
def __init__(self, package_name: str = ""):
|
|
super().__init__()
|
|
self.packageName = package_name
|
|
self.codeSize = 0
|
|
self.dataSize = 0
|
|
self.cacheSize = 0
|
|
self.externalCodeSize = 0
|
|
self.externalDataSize = 0
|
|
self.externalCacheSize = 0
|
|
self.externalMediaSize = 0
|
|
self.externalObbSize = 0
|
|
|
|
def toString(self) -> str:
|
|
return (f"PackageStats({self.packageName}, "
|
|
f"code={self.codeSize}, data={self.dataSize})")
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# PackageManager
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class PackageManager(Stub):
|
|
"""PackageManager — 包管理器"""
|
|
|
|
# Flag 常量
|
|
GET_ACTIVITIES = 1
|
|
GET_CONFIGURATIONS = 2
|
|
GET_GIDS = 4
|
|
GET_INSTRUMENTATION = 8
|
|
GET_INTENT_FILTERS = 16
|
|
GET_META_DATA = 128
|
|
GET_PERMISSIONS = 4096
|
|
GET_PROVIDERS = 8
|
|
GET_RECEIVERS = 4
|
|
GET_SERVICES = 2
|
|
GET_SHARED_LIBRARY_FILES = 32
|
|
GET_SIGNATURES = 64
|
|
GET_UNINSTALLED_PACKAGES = 512
|
|
GET_URI_PERMISSION_PATTERNS = 256
|
|
MATCH_ALL = 0x10000
|
|
MATCH_DISABLED_COMPONENTS = 0x200
|
|
MATCH_DISABLED_UNTIL_USED_COMPONENTS = 0x8000
|
|
MATCH_DEFAULT_ONLY = 0x10000
|
|
MATCH_SYSTEM_ONLY = 0x800000
|
|
MATCH_UNINSTALLED_PACKAGES = 0x2000000
|
|
PERMISSION_DENIED = -1
|
|
PERMISSION_GRANTED = 0
|
|
|
|
# 特性常量
|
|
FEATURE_CAMERA = "android.hardware.camera"
|
|
FEATURE_CAMERA_AUTOFOCUS = "android.hardware.camera.autofocus"
|
|
FEATURE_CAMERA_FLASH = "android.hardware.camera.flash"
|
|
FEATURE_CAMERA_FRONT = "android.hardware.camera.front"
|
|
FEATURE_LOCATION = "android.hardware.location"
|
|
FEATURE_LOCATION_GPS = "android.hardware.location.gps"
|
|
FEATURE_LOCATION_NETWORK = "android.hardware.location.network"
|
|
FEATURE_MICROPHONE = "android.hardware.microphone"
|
|
FEATURE_NFC = "android.hardware.nfc"
|
|
FEATURE_SENSOR_ACCELEROMETER = "android.hardware.sensor.accelerometer"
|
|
FEATURE_SENSOR_BAROMETER = "android.hardware.sensor.barometer"
|
|
FEATURE_SENSOR_COMPASS = "android.hardware.sensor.compass"
|
|
FEATURE_SENSOR_GYROSCOPE = "android.hardware.sensor.gyroscope"
|
|
FEATURE_SENSOR_LIGHT = "android.hardware.sensor.light"
|
|
FEATURE_SENSOR_PROXIMITY = "android.hardware.sensor.proximity"
|
|
FEATURE_TELEPHONY = "android.hardware.telephony"
|
|
FEATURE_TOUCHSCREEN = "android.hardware.touchscreen"
|
|
FEATURE_USB_HOST = "android.hardware.usb.host"
|
|
FEATURE_WIFI = "android.hardware.wifi"
|
|
FEATURE_BLUETOOTH = "android.hardware.bluetooth"
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._packages: Dict[str, Dict[str, Any]] = {}
|
|
self._load_packages()
|
|
|
|
def _load_packages(self):
|
|
"""从 JSON 文件加载包信息"""
|
|
try:
|
|
if os.path.exists(_DEFAULT_PACKAGE_INFO_PATH):
|
|
with open(_DEFAULT_PACKAGE_INFO_PATH, "r", encoding="utf-8") as f:
|
|
data = json.load(f)
|
|
if data.get("packageName"):
|
|
self._packages[data["packageName"]] = data
|
|
else:
|
|
# 创建默认信息
|
|
default_info = _get_default_package_info()
|
|
self._packages[_package_name] = default_info
|
|
os.makedirs(os.path.dirname(_DEFAULT_PACKAGE_INFO_PATH), exist_ok=True)
|
|
with open(_DEFAULT_PACKAGE_INFO_PATH, "w", encoding="utf-8") as f:
|
|
json.dump(default_info, f, indent=2, ensure_ascii=False)
|
|
except (json.JSONDecodeError, OSError):
|
|
self._packages[_package_name] = _get_default_package_info()
|
|
|
|
def _make_app_info(self, data: Dict) -> ApplicationInfo:
|
|
ai_data = data.get("applicationInfo", data)
|
|
return ApplicationInfo(ai_data)
|
|
|
|
def _make_activity_info(self, data: Dict) -> ActivityInfo:
|
|
return ActivityInfo(data)
|
|
|
|
def _make_service_info(self, data: Dict) -> ServiceInfo:
|
|
return ServiceInfo(data)
|
|
|
|
def _make_provider_info(self, data: Dict) -> ProviderInfo:
|
|
return ProviderInfo(data)
|
|
|
|
def getPackageInfo(self, package_name: str, flags: int) -> Optional[PackageInfo]:
|
|
if package_name not in self._packages:
|
|
return None
|
|
raw = self._packages[package_name]
|
|
pi = PackageInfo()
|
|
pi.packageName = raw.get("packageName", package_name)
|
|
pi.versionName = raw.get("versionName", "1.0.0")
|
|
pi.versionCode = raw.get("versionCode", 1)
|
|
pi.applicationInfo = self._make_app_info(raw)
|
|
|
|
if flags & self.GET_ACTIVITIES:
|
|
pi.activities = [self._make_activity_info(a) for a in raw.get("activities", [])]
|
|
if flags & self.GET_SERVICES:
|
|
pi.services = [self._make_service_info(s) for s in raw.get("services", [])]
|
|
if flags & self.GET_RECEIVERS:
|
|
pi.receivers = [self._make_activity_info(r) for r in raw.get("receivers", [])]
|
|
if flags & self.GET_PROVIDERS:
|
|
pi.providers = [self._make_provider_info(p) for p in raw.get("providers", [])]
|
|
if flags & self.GET_PERMISSIONS:
|
|
pi.permissions = [PermissionInfo(p) for p in raw.get("permissions", [])]
|
|
|
|
pi.requestedPermissions = raw.get("requestedPermissions", [])
|
|
return pi
|
|
|
|
def getApplicationInfo(self, package_name: str, flags: int) -> Optional[ApplicationInfo]:
|
|
if package_name not in self._packages:
|
|
return None
|
|
return self._make_app_info(self._packages[package_name])
|
|
|
|
def getActivityInfo(self, component: Any, flags: int) -> Optional[ActivityInfo]:
|
|
cn = component
|
|
pkg = getattr(cn, "getPackageName", lambda: "")()
|
|
cls = getattr(cn, "getClassName", lambda: "")()
|
|
if pkg in self._packages:
|
|
for a in self._packages[pkg].get("activities", []):
|
|
if a.get("name") == cls:
|
|
return ActivityInfo(a)
|
|
return ActivityInfo({"name": cls, "packageName": pkg})
|
|
|
|
def getServiceInfo(self, component: Any, flags: int) -> Optional[ServiceInfo]:
|
|
cn = component
|
|
pkg = getattr(cn, "getPackageName", lambda: "")()
|
|
cls = getattr(cn, "getClassName", lambda: "")()
|
|
if pkg in self._packages:
|
|
for s in self._packages[pkg].get("services", []):
|
|
if s.get("name") == cls:
|
|
return ServiceInfo(s)
|
|
return ServiceInfo({"name": cls, "packageName": pkg})
|
|
|
|
def getInstalledPackages(self, flags: int) -> List[PackageInfo]:
|
|
result = []
|
|
for pkg_name in self._packages:
|
|
pi = self.getPackageInfo(pkg_name, flags)
|
|
if pi:
|
|
result.append(pi)
|
|
return result
|
|
|
|
def getInstalledApplications(self, flags: int) -> List[ApplicationInfo]:
|
|
result = []
|
|
for pkg_name in self._packages:
|
|
ai = self.getApplicationInfo(pkg_name, flags)
|
|
if ai:
|
|
result.append(ai)
|
|
return result
|
|
|
|
def queryIntentActivities(self, intent: Any, flags: int) -> List[ResolveInfo]:
|
|
"""查询匹配 Intent 的 Activity 列表"""
|
|
results = []
|
|
action = getattr(intent, "getAction", lambda: None)()
|
|
for pkg_name, raw in self._packages.items():
|
|
for a in raw.get("activities", []):
|
|
ri = ResolveInfo()
|
|
ri.activityInfo = ActivityInfo(a)
|
|
ri.priority = 0
|
|
ri.match = 0
|
|
results.append(ri)
|
|
return results
|
|
|
|
def queryBroadcastReceivers(self, intent: Any, flags: int) -> List[ResolveInfo]:
|
|
results = []
|
|
for pkg_name, raw in self._packages.items():
|
|
for r in raw.get("receivers", []):
|
|
ri = ResolveInfo()
|
|
ri.activityInfo = ActivityInfo(r)
|
|
results.append(ri)
|
|
return results
|
|
|
|
def queryIntentServices(self, intent: Any, flags: int) -> List[ResolveInfo]:
|
|
results = []
|
|
for pkg_name, raw in self._packages.items():
|
|
for s in raw.get("services", []):
|
|
ri = ResolveInfo()
|
|
ri.serviceInfo = ServiceInfo(s)
|
|
results.append(ri)
|
|
return results
|
|
|
|
def queryIntentContentProviders(self, intent: Any, flags: int) -> List[ResolveInfo]:
|
|
results = []
|
|
for pkg_name, raw in self._packages.items():
|
|
for p in raw.get("providers", []):
|
|
ri = ResolveInfo()
|
|
ri.providerInfo = ProviderInfo(p)
|
|
results.append(ri)
|
|
return results
|
|
|
|
def resolveActivity(self, intent: Any, flags: int) -> Optional[ResolveInfo]:
|
|
activities = self.queryIntentActivities(intent, flags)
|
|
return activities[0] if activities else None
|
|
|
|
def resolveService(self, intent: Any, flags: int) -> Optional[ResolveInfo]:
|
|
services = self.queryIntentServices(intent, flags)
|
|
return services[0] if services else None
|
|
|
|
def checkPermission(self, permission: str, package_name: str) -> int:
|
|
if package_name in self._packages:
|
|
perms = self._packages[package_name].get("requestedPermissions", [])
|
|
if permission in perms:
|
|
return self.PERMISSION_GRANTED
|
|
return self.PERMISSION_DENIED if permission else self.PERMISSION_GRANTED
|
|
|
|
def getPermissionInfo(self, name: str, flags: int) -> Optional[PermissionInfo]:
|
|
return PermissionInfo({"name": name, "packageName": "android"})
|
|
|
|
def getDefaultActivityIcon(self) -> Any:
|
|
return None
|
|
|
|
def getApplicationLabel(self, info: ApplicationInfo) -> str:
|
|
return info.name.split(".")[-1] if info.name else ""
|
|
|
|
def getApplicationIcon(self, package_name: str) -> Any:
|
|
return None
|
|
|
|
def hasSystemFeature(self, feature: str) -> bool:
|
|
for pkg_name, raw in self._packages.items():
|
|
features = raw.get("features", {})
|
|
if feature in features:
|
|
return features[feature]
|
|
return False
|
|
|
|
def getLaunchIntentForPackage(self, package_name: str) -> Any:
|
|
from .app import Intent
|
|
if package_name in self._packages:
|
|
intent = Intent(Intent.ACTION_MAIN)
|
|
intent.setPackage(package_name)
|
|
return intent
|
|
return None
|
|
|
|
def getLeanbackLaunchIntentForPackage(self, package_name: str) -> Any:
|
|
return self.getLaunchIntentForPackage(package_name)
|
|
|
|
def getPackageSizeInfo(self, package_name: str, observer: Any):
|
|
pass
|
|
|
|
def getPackageGids(self, package_name: str) -> Optional[List[int]]:
|
|
return []
|
|
|
|
def getPackageUid(self, package_name: str, flags: int) -> int:
|
|
return 10001
|
|
|
|
def getNameForUid(self, uid: int) -> Optional[str]:
|
|
return _package_name
|
|
|
|
def getPackagesForUid(self, uid: int) -> Optional[List[str]]:
|
|
return [_package_name]
|
|
|
|
def getResourcesForActivity(self, component: Any) -> Any:
|
|
return None
|
|
|
|
def getResourcesForApplication(self, app_info: ApplicationInfo) -> Any:
|
|
return None
|
|
|
|
def isSafeMode(self) -> bool:
|
|
return False
|
|
|
|
def addPackageToPreferred(self, package_name: str):
|
|
pass
|
|
|
|
def removePackageFromPreferred(self, package_name: str):
|
|
pass
|
|
|
|
def getPreferredPackages(self, flags: int) -> List[PackageInfo]:
|
|
return []
|
|
|
|
def setApplicationEnabledSetting(self, package_name: str, new_state: int, flags: int):
|
|
pass
|
|
|
|
def getApplicationEnabledSetting(self, package_name: str) -> int:
|
|
return 0
|
|
|
|
def getComponentEnabledSetting(self, component_name: Any) -> int:
|
|
return 1
|
|
|
|
def setComponentEnabledSetting(self, component_name: Any, new_state: int, flags: int):
|
|
pass
|
|
|
|
def clearInstantAppCookie(self):
|
|
pass
|
|
|
|
def getInstantAppCookie(self) -> bytes:
|
|
return b""
|
|
|
|
def getInstantAppCookieMaxSize(self) -> int:
|
|
return 4096
|
|
|
|
def getMimeGroup(self, mime_group: str) -> List[str]:
|
|
return []
|
|
|
|
def isInstantApp(self) -> bool:
|
|
return False
|
|
|
|
def isInstantAppPackageName(self, package_name: str) -> bool:
|
|
return False
|
|
|
|
def getSyntheticAppDetailsActivityEnabled(self, package_name: str) -> int:
|
|
return 1
|
|
|
|
def setSyntheticAppDetailsActivityEnabled(self, package_name: str, enabled: int):
|
|
pass
|
|
|
|
def canRequestPackageInstalls(self) -> bool:
|
|
return True
|
|
|
|
def currentToCanonicalPackageNames(self, names: List[str]) -> List[str]:
|
|
return list(names)
|
|
|
|
def canonicalToCurrentPackageNames(self, names: List[str]) -> List[str]:
|
|
return list(names)
|
|
|
|
def getInstallerPackageName(self, package_name: str) -> Optional[str]:
|
|
return None
|
|
|
|
def toString(self) -> str:
|
|
return f"PackageManager(packages={len(self._packages)})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# __all__
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
__all__ = [
|
|
"PackageManager",
|
|
"PackageInfo",
|
|
"ApplicationInfo",
|
|
"ActivityInfo",
|
|
"ServiceInfo",
|
|
"ProviderInfo",
|
|
"PermissionInfo",
|
|
"ResolveInfo",
|
|
"PackageItemInfo",
|
|
"ComponentInfo",
|
|
"Signature",
|
|
"PackageStats",
|
|
] |