pymobiledevice3 5.0.1__py3-none-any.whl → 5.0.3__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.

Potentially problematic release.


This version of pymobiledevice3 might be problematic. Click here for more details.

Files changed (143) hide show
  1. misc/plist_sniffer.py +15 -15
  2. misc/remotexpc_sniffer.py +29 -28
  3. pymobiledevice3/__main__.py +128 -102
  4. pymobiledevice3/_version.py +2 -2
  5. pymobiledevice3/bonjour.py +36 -59
  6. pymobiledevice3/ca.py +32 -24
  7. pymobiledevice3/cli/activation.py +7 -7
  8. pymobiledevice3/cli/afc.py +19 -19
  9. pymobiledevice3/cli/amfi.py +4 -4
  10. pymobiledevice3/cli/apps.py +51 -39
  11. pymobiledevice3/cli/backup.py +58 -32
  12. pymobiledevice3/cli/bonjour.py +25 -18
  13. pymobiledevice3/cli/cli_common.py +112 -81
  14. pymobiledevice3/cli/companion_proxy.py +4 -4
  15. pymobiledevice3/cli/completions.py +10 -10
  16. pymobiledevice3/cli/crash.py +37 -31
  17. pymobiledevice3/cli/developer.py +602 -520
  18. pymobiledevice3/cli/diagnostics.py +38 -33
  19. pymobiledevice3/cli/lockdown.py +79 -74
  20. pymobiledevice3/cli/mounter.py +85 -68
  21. pymobiledevice3/cli/notification.py +10 -10
  22. pymobiledevice3/cli/pcap.py +19 -14
  23. pymobiledevice3/cli/power_assertion.py +12 -10
  24. pymobiledevice3/cli/processes.py +10 -10
  25. pymobiledevice3/cli/profile.py +88 -77
  26. pymobiledevice3/cli/provision.py +17 -17
  27. pymobiledevice3/cli/remote.py +186 -110
  28. pymobiledevice3/cli/restore.py +43 -40
  29. pymobiledevice3/cli/springboard.py +30 -28
  30. pymobiledevice3/cli/syslog.py +85 -58
  31. pymobiledevice3/cli/usbmux.py +21 -20
  32. pymobiledevice3/cli/version.py +3 -2
  33. pymobiledevice3/cli/webinspector.py +157 -79
  34. pymobiledevice3/common.py +1 -1
  35. pymobiledevice3/exceptions.py +154 -60
  36. pymobiledevice3/irecv.py +49 -53
  37. pymobiledevice3/irecv_devices.py +1489 -492
  38. pymobiledevice3/lockdown.py +396 -242
  39. pymobiledevice3/lockdown_service_provider.py +5 -7
  40. pymobiledevice3/osu/os_utils.py +18 -9
  41. pymobiledevice3/osu/posix_util.py +28 -15
  42. pymobiledevice3/osu/win_util.py +14 -8
  43. pymobiledevice3/pair_records.py +19 -19
  44. pymobiledevice3/remote/common.py +4 -4
  45. pymobiledevice3/remote/core_device/app_service.py +94 -67
  46. pymobiledevice3/remote/core_device/core_device_service.py +17 -14
  47. pymobiledevice3/remote/core_device/device_info.py +5 -5
  48. pymobiledevice3/remote/core_device/diagnostics_service.py +10 -8
  49. pymobiledevice3/remote/core_device/file_service.py +47 -33
  50. pymobiledevice3/remote/remote_service_discovery.py +53 -35
  51. pymobiledevice3/remote/remotexpc.py +64 -42
  52. pymobiledevice3/remote/tunnel_service.py +371 -293
  53. pymobiledevice3/remote/utils.py +12 -11
  54. pymobiledevice3/remote/xpc_message.py +145 -125
  55. pymobiledevice3/resources/dsc_uuid_map.py +19 -19
  56. pymobiledevice3/resources/firmware_notifications.py +16 -16
  57. pymobiledevice3/restore/asr.py +27 -27
  58. pymobiledevice3/restore/base_restore.py +90 -47
  59. pymobiledevice3/restore/consts.py +87 -66
  60. pymobiledevice3/restore/device.py +11 -11
  61. pymobiledevice3/restore/fdr.py +46 -46
  62. pymobiledevice3/restore/ftab.py +19 -19
  63. pymobiledevice3/restore/img4.py +130 -133
  64. pymobiledevice3/restore/mbn.py +35 -54
  65. pymobiledevice3/restore/recovery.py +125 -135
  66. pymobiledevice3/restore/restore.py +524 -523
  67. pymobiledevice3/restore/restore_options.py +122 -115
  68. pymobiledevice3/restore/restored_client.py +25 -22
  69. pymobiledevice3/restore/tss.py +378 -270
  70. pymobiledevice3/service_connection.py +50 -46
  71. pymobiledevice3/services/accessibilityaudit.py +137 -127
  72. pymobiledevice3/services/afc.py +350 -291
  73. pymobiledevice3/services/amfi.py +21 -18
  74. pymobiledevice3/services/companion.py +23 -19
  75. pymobiledevice3/services/crash_reports.py +60 -46
  76. pymobiledevice3/services/debugserver_applist.py +3 -3
  77. pymobiledevice3/services/device_arbitration.py +8 -8
  78. pymobiledevice3/services/device_link.py +56 -48
  79. pymobiledevice3/services/diagnostics.py +971 -968
  80. pymobiledevice3/services/dtfetchsymbols.py +8 -8
  81. pymobiledevice3/services/dvt/dvt_secure_socket_proxy.py +4 -4
  82. pymobiledevice3/services/dvt/dvt_testmanaged_proxy.py +4 -4
  83. pymobiledevice3/services/dvt/instruments/activity_trace_tap.py +85 -74
  84. pymobiledevice3/services/dvt/instruments/application_listing.py +2 -3
  85. pymobiledevice3/services/dvt/instruments/condition_inducer.py +7 -6
  86. pymobiledevice3/services/dvt/instruments/core_profile_session_tap.py +442 -421
  87. pymobiledevice3/services/dvt/instruments/device_info.py +11 -11
  88. pymobiledevice3/services/dvt/instruments/energy_monitor.py +1 -1
  89. pymobiledevice3/services/dvt/instruments/graphics.py +1 -1
  90. pymobiledevice3/services/dvt/instruments/location_simulation.py +1 -1
  91. pymobiledevice3/services/dvt/instruments/location_simulation_base.py +10 -10
  92. pymobiledevice3/services/dvt/instruments/network_monitor.py +17 -17
  93. pymobiledevice3/services/dvt/instruments/notifications.py +1 -1
  94. pymobiledevice3/services/dvt/instruments/process_control.py +25 -10
  95. pymobiledevice3/services/dvt/instruments/screenshot.py +2 -2
  96. pymobiledevice3/services/dvt/instruments/sysmontap.py +15 -15
  97. pymobiledevice3/services/dvt/testmanaged/xcuitest.py +42 -52
  98. pymobiledevice3/services/file_relay.py +10 -10
  99. pymobiledevice3/services/heartbeat.py +8 -7
  100. pymobiledevice3/services/house_arrest.py +12 -15
  101. pymobiledevice3/services/installation_proxy.py +119 -100
  102. pymobiledevice3/services/lockdown_service.py +12 -5
  103. pymobiledevice3/services/misagent.py +22 -19
  104. pymobiledevice3/services/mobile_activation.py +84 -72
  105. pymobiledevice3/services/mobile_config.py +330 -301
  106. pymobiledevice3/services/mobile_image_mounter.py +137 -116
  107. pymobiledevice3/services/mobilebackup2.py +188 -150
  108. pymobiledevice3/services/notification_proxy.py +11 -11
  109. pymobiledevice3/services/os_trace.py +69 -51
  110. pymobiledevice3/services/pcapd.py +306 -306
  111. pymobiledevice3/services/power_assertion.py +10 -9
  112. pymobiledevice3/services/preboard.py +4 -4
  113. pymobiledevice3/services/remote_fetch_symbols.py +16 -14
  114. pymobiledevice3/services/remote_server.py +176 -146
  115. pymobiledevice3/services/restore_service.py +16 -16
  116. pymobiledevice3/services/screenshot.py +13 -10
  117. pymobiledevice3/services/simulate_location.py +7 -7
  118. pymobiledevice3/services/springboard.py +15 -15
  119. pymobiledevice3/services/syslog.py +5 -5
  120. pymobiledevice3/services/web_protocol/alert.py +3 -3
  121. pymobiledevice3/services/web_protocol/automation_session.py +183 -179
  122. pymobiledevice3/services/web_protocol/cdp_screencast.py +44 -36
  123. pymobiledevice3/services/web_protocol/cdp_server.py +19 -19
  124. pymobiledevice3/services/web_protocol/cdp_target.py +411 -373
  125. pymobiledevice3/services/web_protocol/driver.py +47 -45
  126. pymobiledevice3/services/web_protocol/element.py +74 -63
  127. pymobiledevice3/services/web_protocol/inspector_session.py +106 -102
  128. pymobiledevice3/services/web_protocol/selenium_api.py +3 -3
  129. pymobiledevice3/services/web_protocol/session_protocol.py +15 -10
  130. pymobiledevice3/services/web_protocol/switch_to.py +11 -12
  131. pymobiledevice3/services/webinspector.py +129 -117
  132. pymobiledevice3/tcp_forwarder.py +35 -22
  133. pymobiledevice3/tunneld/api.py +20 -15
  134. pymobiledevice3/tunneld/server.py +212 -133
  135. pymobiledevice3/usbmux.py +183 -138
  136. pymobiledevice3/utils.py +14 -11
  137. {pymobiledevice3-5.0.1.dist-info → pymobiledevice3-5.0.3.dist-info}/METADATA +1 -1
  138. pymobiledevice3-5.0.3.dist-info/RECORD +173 -0
  139. pymobiledevice3-5.0.1.dist-info/RECORD +0 -173
  140. {pymobiledevice3-5.0.1.dist-info → pymobiledevice3-5.0.3.dist-info}/WHEEL +0 -0
  141. {pymobiledevice3-5.0.1.dist-info → pymobiledevice3-5.0.3.dist-info}/entry_points.txt +0 -0
  142. {pymobiledevice3-5.0.1.dist-info → pymobiledevice3-5.0.3.dist-info}/licenses/LICENSE +0 -0
  143. {pymobiledevice3-5.0.1.dist-info → pymobiledevice3-5.0.3.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,5 @@
1
1
  import asyncio
2
+ import contextlib
2
3
  from base64 import b64decode, b64encode
3
4
  from datetime import datetime
4
5
  from io import BytesIO
@@ -31,19 +32,19 @@ class ScreenCast:
31
32
 
32
33
  @property
33
34
  def scale(self) -> float:
34
- """ The amount screen pixels in one devtools pixel. """
35
+ """The amount screen pixels in one devtools pixel."""
35
36
  real_height = self.device_height * self.page_scale_factor
36
37
  real_width = self.device_width * self.page_scale_factor
37
38
  return min(self.max_height / real_height, self.max_width / real_width, 1) * self.page_scale_factor
38
39
 
39
40
  @property
40
41
  def scaled_width(self) -> int:
41
- """ Width of screenshot after scaling. """
42
+ """Width of screenshot after scaling."""
42
43
  return int(self.scale * self.device_width)
43
44
 
44
45
  @property
45
46
  def scaled_height(self) -> int:
46
- """ Height of screenshot after scaling. """
47
+ """Height of screenshot after scaling."""
47
48
  return int(self.scale * self.device_height)
48
49
 
49
50
  async def start(self, message_id: int):
@@ -53,26 +54,26 @@ class ScreenCast:
53
54
  """
54
55
  device_size = await self.target.evaluate_and_result(
55
56
  message_id,
56
- ('(window.innerWidth > 0 ? window.innerWidth : screen.width) + "," + '
57
- '(window.innerHeight > 0 ? window.innerHeight : screen.height) + "," + '
58
- 'window.devicePixelRatio')
57
+ (
58
+ '(window.innerWidth > 0 ? window.innerWidth : screen.width) + "," + '
59
+ '(window.innerHeight > 0 ? window.innerHeight : screen.height) + "," + '
60
+ "window.devicePixelRatio"
61
+ ),
59
62
  )
60
- self.device_width, self.device_height, self.page_scale_factor = list(map(int, device_size.split(',')))
63
+ self.device_width, self.device_height, self.page_scale_factor = list(map(int, device_size.split(",")))
61
64
  self._run = True
62
65
  self.recording_task = asyncio.create_task(self.recording_loop(message_id))
63
66
 
64
67
  async def stop(self):
65
- """ Stop sending screenshots to the devtools. """
68
+ """Stop sending screenshots to the devtools."""
66
69
  self._run = False
67
70
  self.recording_task.cancel()
68
- try:
71
+ with contextlib.suppress(asyncio.CancelledError):
69
72
  await self.recording_task
70
- except asyncio.CancelledError:
71
- pass
72
73
  self.recording_task = None
73
74
 
74
75
  def ack(self, frame_id: int):
75
- """ Handle acknowledgement for screencast frames. """
76
+ """Handle acknowledgement for screencast frames."""
76
77
  self.frames_acked.append(frame_id)
77
78
 
78
79
  def resize_jpeg(self, data: str) -> str:
@@ -83,9 +84,9 @@ class ScreenCast:
83
84
  """
84
85
  resized_img = Image.open(BytesIO(b64decode(data)))
85
86
  resized_img = resized_img.resize((self.scaled_width, self.scaled_height), Image.ANTIALIAS)
86
- resized_img = resized_img.convert('RGB')
87
+ resized_img = resized_img.convert("RGB")
87
88
  resized = BytesIO()
88
- resized_img.save(resized, format='jpeg', quality='maximum')
89
+ resized_img.save(resized, format="jpeg", quality="maximum")
89
90
  return b64encode(resized.getvalue()).decode()
90
91
 
91
92
  async def get_offsets(self, message_id: int):
@@ -96,12 +97,11 @@ class ScreenCast:
96
97
  :rtype: tuple
97
98
  """
98
99
  frame_size = await self.target.evaluate_and_result(
99
- message_id,
100
- 'window.document.body.offsetTop + "," + window.pageXOffset + "," + window.pageYOffset'
100
+ message_id, 'window.document.body.offsetTop + "," + window.pageXOffset + "," + window.pageYOffset'
101
101
  )
102
102
  if frame_size is None or not isinstance(frame_size, str):
103
103
  return 0, 0, 0
104
- return tuple(map(int, frame_size.split(',')))
104
+ return tuple(map(int, frame_size.split(",")))
105
105
 
106
106
  async def recording_loop(self, message_id):
107
107
  """
@@ -114,24 +114,32 @@ class ScreenCast:
114
114
  continue
115
115
  self.frame_id += 1
116
116
  offset_top, scroll_offset_x, scroll_offset_y = await self.get_offsets(message_id)
117
- event = await self.target.send_message_with_result(message_id, 'Page.snapshotRect', {
118
- 'x': 0, 'y': 0, 'width': self.device_width, 'height': self.device_height, 'coordinateSystem': 'Viewport'
119
- })
120
- data = event['result']['dataURL']
121
- data = data[data.find('base64,') + 7:]
117
+ event = await self.target.send_message_with_result(
118
+ message_id,
119
+ "Page.snapshotRect",
120
+ {
121
+ "x": 0,
122
+ "y": 0,
123
+ "width": self.device_width,
124
+ "height": self.device_height,
125
+ "coordinateSystem": "Viewport",
126
+ },
127
+ )
128
+ data = event["result"]["dataURL"]
129
+ data = data[data.find("base64,") + 7 :]
122
130
  await self.target.output_queue.put({
123
- 'method': 'Page.screencastFrame',
124
- 'params': {
125
- 'data': self.resize_jpeg(data),
126
- 'sessionId': self.frame_id - 1,
127
- 'metadata': {
128
- 'pageScaleFactor': self.page_scale_factor,
129
- 'offsetTop': offset_top,
130
- 'deviceWidth': self.scaled_width,
131
- 'deviceHeight': self.scaled_height,
132
- 'scrollOffsetX': scroll_offset_x,
133
- 'scrollOffsetY': scroll_offset_y,
134
- 'timestamp': datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%f'),
135
- }
136
- }
131
+ "method": "Page.screencastFrame",
132
+ "params": {
133
+ "data": self.resize_jpeg(data),
134
+ "sessionId": self.frame_id - 1,
135
+ "metadata": {
136
+ "pageScaleFactor": self.page_scale_factor,
137
+ "offsetTop": offset_top,
138
+ "deviceWidth": self.scaled_width,
139
+ "deviceHeight": self.scaled_height,
140
+ "scrollOffsetX": scroll_offset_x,
141
+ "scrollOffsetY": scroll_offset_y,
142
+ "timestamp": datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f"),
143
+ },
144
+ },
137
145
  })
@@ -19,7 +19,7 @@ async def lifespan(app: FastAPI):
19
19
  app = FastAPI(lifespan=lifespan)
20
20
 
21
21
 
22
- @app.get('/json{_:path}')
22
+ @app.get("/json{_:path}")
23
23
  async def available_targets(_: str):
24
24
  app.state.inspector.get_open_pages()
25
25
  targets = []
@@ -28,47 +28,47 @@ async def available_targets(_: str):
28
28
  if page.type_ not in (WirTypes.WEB, WirTypes.WEB_PAGE):
29
29
  continue
30
30
  targets.append({
31
- 'description': '',
32
- 'id': page_id,
33
- 'title': page.web_title,
34
- 'type': 'page',
35
- 'url': page.web_url,
36
- 'webSocketDebuggerUrl': f'ws://localhost:9222/devtools/page/{page_id}',
37
- 'devtoolsFrontendUrl': f'/devtools/inspector.html?ws://localhost:9222/devtools/page/{page_id}',
31
+ "description": "",
32
+ "id": page_id,
33
+ "title": page.web_title,
34
+ "type": "page",
35
+ "url": page.web_url,
36
+ "webSocketDebuggerUrl": f"ws://localhost:9222/devtools/page/{page_id}",
37
+ "devtoolsFrontendUrl": f"/devtools/inspector.html?ws://localhost:9222/devtools/page/{page_id}",
38
38
  })
39
39
  return targets
40
40
 
41
41
 
42
- @app.get('/json/version')
42
+ @app.get("/json/version")
43
43
  def version():
44
44
  return {
45
- 'Browser': 'Safari',
46
- 'Protocol-Version': '1.1',
47
- 'User-Agent': 'pymobiledevice3',
48
- 'V8-Version': '7.2.233',
49
- 'WebKit-Version': '537.36 (@cfede9db1d154de0468cb0538479f34c0755a0f4)',
50
- 'webSocketDebuggerUrl': f'ws://localhost:9222/devtools/browser/{app.state.inspector.connection_id}'
45
+ "Browser": "Safari",
46
+ "Protocol-Version": "1.1",
47
+ "User-Agent": "pymobiledevice3",
48
+ "V8-Version": "7.2.233",
49
+ "WebKit-Version": "537.36 (@cfede9db1d154de0468cb0538479f34c0755a0f4)",
50
+ "webSocketDebuggerUrl": f"ws://localhost:9222/devtools/browser/{app.state.inspector.connection_id}",
51
51
  }
52
52
 
53
53
 
54
54
  async def from_cdp(target: CdpTarget, websocket):
55
55
  async for message in websocket.iter_json():
56
- logger.debug(f'CDP INPUT: {message}')
56
+ logger.debug(f"CDP INPUT: {message}")
57
57
  await target.send(message)
58
58
 
59
59
 
60
60
  async def to_cdp(target: CdpTarget, websocket):
61
61
  while True:
62
62
  message = await target.receive()
63
- logger.debug(f'CDP OUTPUT: {message}')
63
+ logger.debug(f"CDP OUTPUT: {message}")
64
64
  await websocket.send_json(message)
65
65
 
66
66
 
67
- @app.websocket('/devtools/page/{page_id}')
67
+ @app.websocket("/devtools/page/{page_id}")
68
68
  async def page_debugger(websocket: WebSocket, page_id: str):
69
69
  application, page = app.state.inspector.find_page_id(page_id)
70
70
  session_id = str(uuid.uuid4()).upper()
71
- protocol = SessionProtocol(app.state.inspector, session_id, application, page, method_prefix='')
71
+ protocol = SessionProtocol(app.state.inspector, session_id, application, page, method_prefix="")
72
72
  target = await CdpTarget.create(protocol)
73
73
  await websocket.accept()
74
74
  await asyncio.gather(