新增模块覆盖: 系统层 (14): system, security, print, opengl, renderscript, transition, test, service_notification, service_controls, service_quicksettings, service_wallpaper, service_autofill, service_dreams, service_vr 应用层 (13): app_admin, app_backup, app_job, app_usage, app_role, app_people, appwidget, companion, credentials, mtp, sip, telecom, speech 硬件媒体层 (15): hardware_display, hardware_fingerprint, hardware_usb, hardware_input, media_audiofx, media_browse, media_session, media_tv, media_midi, media_projection, uwb, se, view_autofill, view_textclassifier, view_translation 总计 94 个模块,75,342 行代码
171 lines
6.5 KiB
Python
171 lines
6.5 KiB
Python
"""
|
|
Android media.projection 组件 — MediaProjectionManager, MediaProjection, MediaProjectionInfo 等
|
|
方法签名完全对齐 Android SDK
|
|
"""
|
|
|
|
from typing import Any, Callable, Dict, List, Optional
|
|
|
|
from .._core import Stub, AndroidOnlyError
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# MediaProjectionManager
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class MediaProjectionManager(Stub):
|
|
"""MediaProjectionManager — 媒体投影管理器"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._active_projections: Dict[int, "MediaProjection"] = {}
|
|
self._callbacks: Dict[int, Callable] = {}
|
|
|
|
def createScreenCaptureIntent(self) -> Any:
|
|
return "SCREEN_CAPTURE_INTENT"
|
|
|
|
def getMediaProjection(self, resultCode: int, data: Any) -> Optional["MediaProjection"]:
|
|
if resultCode == -1: # RESULT_OK
|
|
proj = MediaProjection()
|
|
self._active_projections[id(proj)] = proj
|
|
return proj
|
|
return None
|
|
|
|
def getActiveProjectionInfo(self) -> Optional["MediaProjectionInfo"]:
|
|
for proj in self._active_projections.values():
|
|
info = proj.getProjectionInfo()
|
|
if info:
|
|
return info
|
|
return None
|
|
|
|
def getDisplayProjection(self, displayId: int) -> Optional["MediaProjection"]:
|
|
return None
|
|
|
|
def addCallback(self, callback: Callable, handler: Any = None):
|
|
cid = id(callback)
|
|
self._callbacks[cid] = callback
|
|
|
|
def removeCallback(self, callback: Callable):
|
|
cid = id(callback)
|
|
self._callbacks.pop(cid, None)
|
|
|
|
def isMediaProjectionAllowed(self, packageName: str) -> bool:
|
|
return True
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# MediaProjection
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class MediaProjection(Stub):
|
|
"""MediaProjection — 媒体投影"""
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# Callback
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class Callback(Stub):
|
|
"""MediaProjection.Callback — 投影回调"""
|
|
|
|
def onStop(self):
|
|
pass
|
|
|
|
def onCapturedContentResize(self, width: int, height: int):
|
|
pass
|
|
|
|
def onCapturedContentVisibilityChanged(self, isVisible: bool):
|
|
pass
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._stopped = False
|
|
self._callbacks: List[MediaProjection.Callback] = []
|
|
self._projection_info = MediaProjectionInfo(
|
|
packageName="com.android.systemui",
|
|
uid=1000,
|
|
isVirtualDisplay=False
|
|
)
|
|
|
|
def createVirtualDisplay(self, name: str, width: int, height: int,
|
|
densityDpi: int, flags: int, surface: Any,
|
|
callback: Callable = None, handler: Any = None) -> Any:
|
|
from .hardware_display import VirtualDisplay
|
|
vd = VirtualDisplay(99, name, width, height, densityDpi, surface, flags)
|
|
return vd
|
|
|
|
def registerCallback(self, callback: Callback):
|
|
self._callbacks.append(callback)
|
|
|
|
def unregisterCallback(self, callback: Callback):
|
|
if callback in self._callbacks:
|
|
self._callbacks.remove(callback)
|
|
|
|
def stop(self):
|
|
self._stopped = True
|
|
for cb in self._callbacks:
|
|
cb.onStop()
|
|
|
|
def getProjectionInfo(self) -> "MediaProjectionInfo":
|
|
return self._projection_info
|
|
|
|
def getDisplay(self) -> Optional[Any]:
|
|
from .hardware_display import Display
|
|
return Display(displayId=0, name="Projection Display")
|
|
|
|
def applyTransparentRegionOverlay(self, region: Any):
|
|
pass
|
|
|
|
def removeTransparentRegionOverlay(self):
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return f"MediaProjection(stopped={self._stopped})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# MediaProjectionInfo
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class MediaProjectionInfo(Stub):
|
|
"""MediaProjectionInfo — 媒体投影信息"""
|
|
|
|
def __init__(self, packageName: str = "", uid: int = 0,
|
|
isVirtualDisplay: bool = False):
|
|
super().__init__()
|
|
self._package_name = packageName
|
|
self._uid = uid
|
|
self._is_virtual_display = isVirtualDisplay
|
|
|
|
def getProjectionType(self) -> int:
|
|
return 0
|
|
|
|
def getLaunchedFromPackage(self) -> str:
|
|
return self._package_name
|
|
|
|
def getLaunchedFromUid(self) -> int:
|
|
return self._uid
|
|
|
|
def isVirtualDisplay(self) -> bool:
|
|
return self._is_virtual_display
|
|
|
|
def equals(self, other: Any) -> bool:
|
|
if not isinstance(other, MediaProjectionInfo):
|
|
return False
|
|
return (self._package_name == other._package_name
|
|
and self._uid == other._uid)
|
|
|
|
def hashCode(self) -> int:
|
|
return hash((self._package_name, self._uid)) & 0x7FFFFFFF
|
|
|
|
def toString(self) -> str:
|
|
return f"MediaProjectionInfo(package={self._package_name}, uid={self._uid})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# __all__
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
__all__ = [
|
|
"MediaProjectionManager",
|
|
"MediaProjection",
|
|
"MediaProjectionInfo",
|
|
] |