pymobiledevice3 5.0.4__py3-none-any.whl → 7.0.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- misc/understanding_idevice_protocol_layers.md +10 -5
- pymobiledevice3/__main__.py +171 -46
- pymobiledevice3/_version.py +2 -2
- pymobiledevice3/bonjour.py +22 -21
- pymobiledevice3/cli/activation.py +24 -22
- pymobiledevice3/cli/afc.py +49 -41
- pymobiledevice3/cli/amfi.py +13 -18
- pymobiledevice3/cli/apps.py +71 -65
- pymobiledevice3/cli/backup.py +134 -93
- pymobiledevice3/cli/bonjour.py +31 -29
- pymobiledevice3/cli/cli_common.py +175 -232
- pymobiledevice3/cli/companion_proxy.py +12 -12
- pymobiledevice3/cli/crash.py +95 -52
- pymobiledevice3/cli/developer/__init__.py +62 -0
- pymobiledevice3/cli/developer/accessibility/__init__.py +65 -0
- pymobiledevice3/cli/developer/accessibility/settings.py +43 -0
- pymobiledevice3/cli/developer/arbitration.py +50 -0
- pymobiledevice3/cli/developer/condition.py +33 -0
- pymobiledevice3/cli/developer/core_device.py +294 -0
- pymobiledevice3/cli/developer/debugserver.py +244 -0
- pymobiledevice3/cli/developer/dvt/__init__.py +438 -0
- pymobiledevice3/cli/developer/dvt/core_profile_session.py +295 -0
- pymobiledevice3/cli/developer/dvt/simulate_location.py +56 -0
- pymobiledevice3/cli/developer/dvt/sysmon/__init__.py +69 -0
- pymobiledevice3/cli/developer/dvt/sysmon/process.py +188 -0
- pymobiledevice3/cli/developer/fetch_symbols.py +108 -0
- pymobiledevice3/cli/developer/simulate_location.py +51 -0
- pymobiledevice3/cli/diagnostics/__init__.py +75 -0
- pymobiledevice3/cli/diagnostics/battery.py +47 -0
- pymobiledevice3/cli/idam.py +42 -0
- pymobiledevice3/cli/lockdown.py +70 -75
- pymobiledevice3/cli/mounter.py +99 -57
- pymobiledevice3/cli/notification.py +38 -26
- pymobiledevice3/cli/pcap.py +36 -20
- pymobiledevice3/cli/power_assertion.py +15 -16
- pymobiledevice3/cli/processes.py +11 -17
- pymobiledevice3/cli/profile.py +120 -75
- pymobiledevice3/cli/provision.py +27 -26
- pymobiledevice3/cli/remote.py +109 -100
- pymobiledevice3/cli/restore.py +134 -129
- pymobiledevice3/cli/springboard.py +50 -50
- pymobiledevice3/cli/syslog.py +145 -65
- pymobiledevice3/cli/usbmux.py +66 -27
- pymobiledevice3/cli/version.py +2 -5
- pymobiledevice3/cli/webinspector.py +232 -156
- pymobiledevice3/exceptions.py +6 -2
- pymobiledevice3/lockdown.py +5 -1
- pymobiledevice3/lockdown_service_provider.py +5 -0
- pymobiledevice3/remote/remote_service_discovery.py +18 -10
- pymobiledevice3/restore/device.py +28 -4
- pymobiledevice3/restore/restore.py +2 -2
- pymobiledevice3/service_connection.py +15 -12
- pymobiledevice3/services/afc.py +731 -220
- pymobiledevice3/services/device_link.py +45 -31
- pymobiledevice3/services/idam.py +20 -0
- pymobiledevice3/services/lockdown_service.py +12 -9
- pymobiledevice3/services/mobile_config.py +1 -0
- pymobiledevice3/services/mobilebackup2.py +6 -3
- pymobiledevice3/services/os_trace.py +97 -55
- pymobiledevice3/services/remote_fetch_symbols.py +13 -8
- pymobiledevice3/services/screenshot.py +2 -2
- pymobiledevice3/services/web_protocol/alert.py +8 -8
- pymobiledevice3/services/web_protocol/automation_session.py +87 -79
- pymobiledevice3/services/web_protocol/cdp_screencast.py +2 -1
- pymobiledevice3/services/web_protocol/driver.py +71 -70
- pymobiledevice3/services/web_protocol/element.py +58 -56
- pymobiledevice3/services/web_protocol/selenium_api.py +47 -47
- pymobiledevice3/services/web_protocol/session_protocol.py +3 -2
- pymobiledevice3/services/web_protocol/switch_to.py +23 -19
- pymobiledevice3/services/webinspector.py +42 -67
- {pymobiledevice3-5.0.4.dist-info → pymobiledevice3-7.0.6.dist-info}/METADATA +5 -3
- {pymobiledevice3-5.0.4.dist-info → pymobiledevice3-7.0.6.dist-info}/RECORD +76 -61
- pymobiledevice3/cli/completions.py +0 -50
- pymobiledevice3/cli/developer.py +0 -1539
- pymobiledevice3/cli/diagnostics.py +0 -110
- {pymobiledevice3-5.0.4.dist-info → pymobiledevice3-7.0.6.dist-info}/WHEEL +0 -0
- {pymobiledevice3-5.0.4.dist-info → pymobiledevice3-7.0.6.dist-info}/entry_points.txt +0 -0
- {pymobiledevice3-5.0.4.dist-info → pymobiledevice3-7.0.6.dist-info}/licenses/LICENSE +0 -0
- {pymobiledevice3-5.0.4.dist-info → pymobiledevice3-7.0.6.dist-info}/top_level.txt +0 -0
|
@@ -44,6 +44,10 @@ class RemoteServiceDiscoveryService(LockdownServiceProvider):
|
|
|
44
44
|
def product_version(self) -> str:
|
|
45
45
|
return self.peer_info["Properties"]["OSVersion"]
|
|
46
46
|
|
|
47
|
+
@property
|
|
48
|
+
def product_build_version(self) -> str:
|
|
49
|
+
return self.peer_info["Properties"]["BuildVersion"]
|
|
50
|
+
|
|
47
51
|
@property
|
|
48
52
|
def ecid(self) -> int:
|
|
49
53
|
return self.peer_info["Properties"]["UniqueChipID"]
|
|
@@ -101,6 +105,9 @@ class RemoteServiceDiscoveryService(LockdownServiceProvider):
|
|
|
101
105
|
raise PyMobileDevice3Exception(
|
|
102
106
|
f'Invalid response for RSDCheckIn: {response}. Expected "ServiceService"'
|
|
103
107
|
)
|
|
108
|
+
error = response.get("Error")
|
|
109
|
+
if error is not None:
|
|
110
|
+
raise StartServiceError(name, error)
|
|
104
111
|
except Exception:
|
|
105
112
|
service.close()
|
|
106
113
|
raise
|
|
@@ -162,17 +169,18 @@ class RemoteServiceDiscoveryService(LockdownServiceProvider):
|
|
|
162
169
|
|
|
163
170
|
async def get_remoted_devices(timeout: float = DEFAULT_BONJOUR_TIMEOUT) -> list[RSDDevice]:
|
|
164
171
|
result = []
|
|
165
|
-
for
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
172
|
+
for instance in await browse_remoted(timeout):
|
|
173
|
+
for address in instance.addresses:
|
|
174
|
+
with RemoteServiceDiscoveryService((address.full_ip, RSD_PORT)) as rsd:
|
|
175
|
+
properties = rsd.peer_info["Properties"]
|
|
176
|
+
result.append(
|
|
177
|
+
RSDDevice(
|
|
178
|
+
hostname=address.full_ip,
|
|
179
|
+
udid=properties["UniqueDeviceID"],
|
|
180
|
+
product_type=properties["ProductType"],
|
|
181
|
+
os_version=properties["OSVersion"],
|
|
182
|
+
)
|
|
174
183
|
)
|
|
175
|
-
)
|
|
176
184
|
return result
|
|
177
185
|
|
|
178
186
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from contextlib import suppress
|
|
2
2
|
from functools import cached_property
|
|
3
|
-
from typing import Optional
|
|
3
|
+
from typing import Optional, overload
|
|
4
4
|
|
|
5
5
|
from pymobiledevice3.exceptions import MissingValueError
|
|
6
6
|
from pymobiledevice3.irecv import IRecv
|
|
@@ -8,9 +8,15 @@ from pymobiledevice3.lockdown import LockdownClient
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class Device:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
@overload
|
|
12
|
+
def __init__(self, lockdown: LockdownClient, irecv: None = None) -> None: ...
|
|
13
|
+
|
|
14
|
+
@overload
|
|
15
|
+
def __init__(self, lockdown: None = None, *, irecv: IRecv) -> None: ...
|
|
16
|
+
|
|
17
|
+
def __init__(self, lockdown: Optional[LockdownClient] = None, irecv: Optional[IRecv] = None) -> None:
|
|
18
|
+
self._lockdown: Optional[LockdownClient] = lockdown
|
|
19
|
+
self._irecv: Optional[IRecv] = irecv
|
|
14
20
|
|
|
15
21
|
def __repr__(self) -> str:
|
|
16
22
|
return (
|
|
@@ -20,6 +26,24 @@ class Device:
|
|
|
20
26
|
f"image4-support: {self.is_image4_supported}>"
|
|
21
27
|
)
|
|
22
28
|
|
|
29
|
+
@cached_property
|
|
30
|
+
def is_lockdown(self) -> bool:
|
|
31
|
+
return self._lockdown is not None
|
|
32
|
+
|
|
33
|
+
@cached_property
|
|
34
|
+
def is_irecv(self) -> bool:
|
|
35
|
+
return self._irecv is not None
|
|
36
|
+
|
|
37
|
+
@cached_property
|
|
38
|
+
def lockdown(self) -> LockdownClient:
|
|
39
|
+
assert self._lockdown is not None
|
|
40
|
+
return self._lockdown
|
|
41
|
+
|
|
42
|
+
@cached_property
|
|
43
|
+
def irecv(self) -> IRecv:
|
|
44
|
+
assert self._irecv is not None
|
|
45
|
+
return self._irecv
|
|
46
|
+
|
|
23
47
|
@cached_property
|
|
24
48
|
def ecid(self):
|
|
25
49
|
if self.lockdown:
|
|
@@ -182,7 +182,7 @@ class Restore(BaseRestore):
|
|
|
182
182
|
self.logger.info("Sending BuildIdentityDict now...")
|
|
183
183
|
await service.aio_send_plist(req)
|
|
184
184
|
|
|
185
|
-
|
|
185
|
+
def extract_global_manifest(self) -> dict:
|
|
186
186
|
build_info = self.build_identity.get("Info")
|
|
187
187
|
if build_info is None:
|
|
188
188
|
raise PyMobileDevice3Exception('build identity does not contain an "Info" element')
|
|
@@ -881,7 +881,7 @@ class Restore(BaseRestore):
|
|
|
881
881
|
comp_name = "BMU,FirmwareMap"
|
|
882
882
|
|
|
883
883
|
if "DeviceGeneratedTags" in arguments:
|
|
884
|
-
response = self.get_device_generated_firmware_data(updater_name, info, arguments)
|
|
884
|
+
response = await self.get_device_generated_firmware_data(updater_name, info, arguments)
|
|
885
885
|
else:
|
|
886
886
|
# create Veridian request
|
|
887
887
|
request = TSSRequest()
|
|
@@ -8,7 +8,7 @@ import struct
|
|
|
8
8
|
import time
|
|
9
9
|
import xml
|
|
10
10
|
from enum import Enum
|
|
11
|
-
from typing import Any, Optional
|
|
11
|
+
from typing import Any, Optional, Union
|
|
12
12
|
|
|
13
13
|
import IPython
|
|
14
14
|
from pygments import formatters, highlight, lexers
|
|
@@ -192,7 +192,7 @@ class ServiceConnection:
|
|
|
192
192
|
except ssl.SSLEOFError as e:
|
|
193
193
|
raise ConnectionTerminatedError from e
|
|
194
194
|
|
|
195
|
-
def send_recv_plist(self, data: dict, endianity: str = ">", fmt: Enum = plistlib.FMT_XML) -> Any:
|
|
195
|
+
def send_recv_plist(self, data: Union[dict, list], endianity: str = ">", fmt: Enum = plistlib.FMT_XML) -> Any:
|
|
196
196
|
"""
|
|
197
197
|
Send a plist to the socket and receive a plist response.
|
|
198
198
|
|
|
@@ -282,29 +282,29 @@ class ServiceConnection:
|
|
|
282
282
|
msg = b"".join([hdr, data])
|
|
283
283
|
return self.sendall(msg)
|
|
284
284
|
|
|
285
|
-
def recv_plist(self, endianity: str = ">") -> dict:
|
|
285
|
+
def recv_plist(self, endianity: str = ">") -> Union[dict, list]:
|
|
286
286
|
"""
|
|
287
|
-
Receive a plist from the socket and parse it into a
|
|
287
|
+
Receive a plist from the socket and parse it into a native type.
|
|
288
288
|
|
|
289
289
|
:param endianity: The byte order ('>' for big-endian, '<' for little-endian).
|
|
290
|
-
:return: The received plist as a
|
|
290
|
+
:return: The received plist as a native type.
|
|
291
291
|
"""
|
|
292
292
|
return parse_plist(self.recv_prefixed(endianity=endianity))
|
|
293
293
|
|
|
294
294
|
async def aio_recv_plist(self, endianity: str = ">") -> dict:
|
|
295
295
|
"""
|
|
296
|
-
Asynchronously receive a plist from the socket and parse it into a
|
|
296
|
+
Asynchronously receive a plist from the socket and parse it into a native type.
|
|
297
297
|
|
|
298
298
|
:param endianity: The byte order ('>' for big-endian, '<' for little-endian).
|
|
299
|
-
:return: The received plist as a
|
|
299
|
+
:return: The received plist as a native type.
|
|
300
300
|
"""
|
|
301
301
|
return parse_plist(await self.aio_recv_prefixed(endianity))
|
|
302
302
|
|
|
303
|
-
def send_plist(self, d: dict, endianity: str = ">", fmt: Enum = plistlib.FMT_XML) -> None:
|
|
303
|
+
def send_plist(self, d: Union[dict, list], endianity: str = ">", fmt: Enum = plistlib.FMT_XML) -> None:
|
|
304
304
|
"""
|
|
305
|
-
Send a
|
|
305
|
+
Send a native type as a plist to the socket.
|
|
306
306
|
|
|
307
|
-
:param d: The
|
|
307
|
+
:param d: The native type to send.
|
|
308
308
|
:param endianity: The byte order ('>' for big-endian, '<' for little-endian).
|
|
309
309
|
:param fmt: The plist format (e.g., plistlib.FMT_XML).
|
|
310
310
|
"""
|
|
@@ -319,7 +319,7 @@ class ServiceConnection:
|
|
|
319
319
|
self.writer.write(payload)
|
|
320
320
|
await self.writer.drain()
|
|
321
321
|
|
|
322
|
-
async def aio_send_plist(self, d: dict, endianity: str = ">", fmt: Enum = plistlib.FMT_XML) -> None:
|
|
322
|
+
async def aio_send_plist(self, d: Union[dict, list], endianity: str = ">", fmt: Enum = plistlib.FMT_XML) -> None:
|
|
323
323
|
"""
|
|
324
324
|
Asynchronously send a dictionary as a plist to the socket.
|
|
325
325
|
|
|
@@ -357,7 +357,10 @@ class ServiceConnection:
|
|
|
357
357
|
:param certfile: The path to the certificate file.
|
|
358
358
|
:param keyfile: The path to the key file (optional).
|
|
359
359
|
"""
|
|
360
|
-
|
|
360
|
+
try:
|
|
361
|
+
self.socket = self.create_ssl_context(certfile, keyfile=keyfile).wrap_socket(self.socket)
|
|
362
|
+
except OSError as e:
|
|
363
|
+
raise ConnectionAbortedError() from e
|
|
361
364
|
|
|
362
365
|
async def aio_ssl_start(self, certfile: str, keyfile: Optional[str] = None) -> None:
|
|
363
366
|
"""
|