Skip to content

Commit 114cc0a

Browse files
committed
feat: Improve docs a bit
1 parent 0d88f68 commit 114cc0a

File tree

3 files changed

+88
-2
lines changed

3 files changed

+88
-2
lines changed

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
## Overview
2+
3+
This is a java interop library for [pymobiledevice3](https://github.com/doronz88/pymobiledevice3).
4+
It uses an IPC protocol, to communicate with a python3 daemon running in the background.
5+
All request/responses are implemented asyncronous.
6+
7+
## How to use
8+
9+
### The Daemon
10+
- Check if the Daemon is currently running with `DaemonHandler.isDaemonRunning()`.
11+
- If not, launch a new instance.
12+
- Create a python env fist `PyInstallation installation = PyInstallationHandler.install(new File(</path/to/install/dir>));`
13+
- You don't need to check for directory existence beforehand, the code is safe to use on every run.
14+
- You should version the pathes using `PyMobileDevice3IPC.PROTOCOL_VERSION`, to avoid version collisions.
15+
- Then launch the daemon with `DaemonHandler.startDaemon(installation);`
16+
- Connect to the Daemon using `PyMobileDevice3IPC ipc = new PyMobileDevice3IPC()`. This object should be closed if not used anymore.
17+
18+
19+
### The IPC
20+
You can now use the `PyMobileDevice3IPC` created. All IPC methods return a `CompletableFuture` and are non-blocking.
21+
The `DebugServer` methods require tunneld to be running. You can check the status with `PyMobileDevice3IPC#isTunneldRunning`.
22+
You can launch tunneld with `PyMobileDevice3IPC#ensureTunneldRunning`, however this will ask for elevated priviliges on macos.
23+
24+
## Debugging
25+
If you run into issues, you can:
26+
- check the log file under `~/AppData/Local/Temp/javapymobiledevice3/` on windows and `/tmp/javapymobiledevice3` on UNIX.
27+
- force shutdown a daemon using `PyMobileDevice3IPC#forceKillDaemon` and clear everything in the mentioned directories above.
28+
- Launch a Daemon with `java.pymobiledevice3.debug` set. This will redirect the daemon stdout to your console.

src/main/java/io/github/berstanio/pymobiledevice3/daemon/DaemonHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
public class DaemonHandler {
2525
public static final String BASE_PORT_NAME = "javapymobiledevice3-" + PyMobileDevice3IPC.PROTOCOL_VERSION;
26-
public static final File BASE_TEMP_DIR_WIN = Paths.get(System.getProperty("user.home"), "AppData", "Local", "Temp").toFile();
26+
public static final File BASE_TEMP_DIR_WIN = Paths.get(System.getProperty("user.home"), "AppData", "Local", "Temp", "javapymobiledevice3").toFile();
2727
public static final File BASE_TEMP_DIR_UNIX = new File("/tmp/javapymobiledevice3/");
2828
public static final File UNIX_PORT_PATH = new File(BASE_TEMP_DIR_UNIX, BASE_PORT_NAME + "--" + getUnixUserId() + ".port");
2929
public static final File WINDOWS_PORT_PATH = new File(BASE_TEMP_DIR_WIN, BASE_PORT_NAME + ".port");

src/main/java/io/github/berstanio/pymobiledevice3/ipc/PyMobileDevice3IPC.java

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,9 @@ private <U> CompletableFuture<U> createRequest(JSONObject request, BiConsumer<Co
154154
return future;
155155
}
156156

157-
157+
/**
158+
* @return A list of currently connected devices
159+
*/
158160
public CompletableFuture<DeviceInfo[]> listDevices() {
159161
JSONObject object = new JSONObject();
160162
object.put("command", "list_devices");
@@ -172,6 +174,9 @@ public CompletableFuture<DeviceInfo[]> listDevices() {
172174
});
173175
}
174176

177+
/**
178+
* @return A list of UDID of currently connected devices. Does not involve pairing.
179+
*/
175180
public CompletableFuture<String[]> listDevicesUDID() {
176181
JSONObject object = new JSONObject();
177182
object.put("command", "list_devices_udid");
@@ -187,6 +192,9 @@ public CompletableFuture<String[]> listDevicesUDID() {
187192
});
188193
}
189194

195+
/**
196+
* @return The first available device
197+
*/
190198
public CompletableFuture<DeviceInfo> getDevice()
191199
{
192200
return getDevice(null);
@@ -213,6 +221,8 @@ public CompletableFuture<DeviceInfo> getDevice(String uuid) {
213221
}
214222

215223
/**
224+
* Gets the bundle identifier for an app path
225+
*
216226
* @param appPath The path to the app bundle, to retrieve the identifier from
217227
* @return The bundle identifier. Fails exceptionally, if no bundle identifier can be found
218228
*/
@@ -251,6 +261,8 @@ public CompletableFuture<String> getInstalledPath(DeviceInfo info, String bundle
251261
}
252262

253263
/**
264+
* Installs an app onto the device
265+
*
254266
* @param deviceInfo The device to install to.
255267
* @param path .app bundle path
256268
* @param installMode The installation mode. INSTALL/UPGRADE
@@ -279,6 +291,11 @@ public CompletableFuture<String> installApp(DeviceInfo deviceInfo, File path, In
279291
});
280292
}
281293

294+
/**
295+
* Decodes a plist into an JSONObject
296+
* @param path The path to a plist
297+
* @return The decoded plist
298+
*/
282299
public CompletableFuture<JSONObject> decodePList(File path) {
283300
if (!path.exists() || path.isDirectory())
284301
throw new IllegalArgumentException("Path " + path.getAbsolutePath() + " does not point to file");
@@ -290,6 +307,11 @@ public CompletableFuture<JSONObject> decodePList(File path) {
290307
});
291308
}
292309

310+
/**
311+
* Auto mount developer disk image for the device
312+
*
313+
* @param info The device to mount the developer disk image
314+
*/
293315
public CompletableFuture<Void> autoMountImage(DeviceInfo info) {
294316
JSONObject object = new JSONObject();
295317
object.put("command", "auto_mount_image");
@@ -299,6 +321,13 @@ public CompletableFuture<Void> autoMountImage(DeviceInfo info) {
299321
});
300322
}
301323

324+
/**
325+
* Connect to the debugserver on the device. Needs tunneld running.
326+
*
327+
* @param info The device to connect to
328+
* @param port The local port to open. 0 for arbitrary port
329+
* @return The info about the connection
330+
*/
302331
public CompletableFuture<DebugServerConnection> debugServerConnect(DeviceInfo info, int port) {
303332
JSONObject object = new JSONObject();
304333
object.put("command", "debugserver_connect");
@@ -314,6 +343,11 @@ public CompletableFuture<DebugServerConnection> debugServerConnect(DeviceInfo in
314343
});
315344
}
316345

346+
/**
347+
* Closes a debug server connection.
348+
*
349+
* @param connection The connection to close
350+
*/
317351
public CompletableFuture<Void> debugServerClose(DebugServerConnection connection) {
318352
JSONObject object = new JSONObject();
319353
object.put("command", "debugserver_close");
@@ -323,6 +357,14 @@ public CompletableFuture<Void> debugServerClose(DebugServerConnection connection
323357
});
324358
}
325359

360+
/**
361+
* Opens a port forwarding to the target device.
362+
*
363+
* @param info The device to forward to
364+
* @param remotePort The port to open on the device
365+
* @param localPort The local port to forward. 0 for arbitrary port
366+
* @return The information about the created forwarding
367+
*/
326368
public CompletableFuture<USBMuxForwarder> usbMuxForwarderCreate(DeviceInfo info, int remotePort, int localPort) {
327369
JSONObject object = new JSONObject();
328370
object.put("command", "usbmux_forwarder_open");
@@ -336,6 +378,11 @@ public CompletableFuture<USBMuxForwarder> usbMuxForwarderCreate(DeviceInfo info,
336378
});
337379
}
338380

381+
/**
382+
* Closes a port forwarder.
383+
*
384+
* @param connection The connection to close
385+
*/
339386
public CompletableFuture<Void> usbMuxForwarderClose(USBMuxForwarder connection) {
340387
JSONObject object = new JSONObject();
341388
object.put("command", "usbmux_forwarder_close");
@@ -345,6 +392,9 @@ public CompletableFuture<Void> usbMuxForwarderClose(USBMuxForwarder connection)
345392
});
346393
}
347394

395+
/**
396+
* Stops the daemon. Don't use this, it's for debugging purposes.
397+
*/
348398
public CompletableFuture<Void> forceKillDaemon() {
349399
JSONObject object = new JSONObject();
350400
object.put("id", commandId.getAndIncrement());
@@ -354,6 +404,11 @@ public CompletableFuture<Void> forceKillDaemon() {
354404
return CompletableFuture.completedFuture(null);
355405
}
356406

407+
/**
408+
* Checks whether the tunneld service is running, needed for debugserver connection
409+
*
410+
* @return whether the tunneld service is running
411+
*/
357412
public CompletableFuture<Boolean> isTunneldRunning() {
358413
JSONObject object = new JSONObject();
359414
object.put("command", "is_tunneld_running");
@@ -362,6 +417,9 @@ public CompletableFuture<Boolean> isTunneldRunning() {
362417
});
363418
}
364419

420+
/**
421+
* Launches the tunneld service. Will request elevated priviliges on macos.
422+
*/
365423
public CompletableFuture<Void> ensureTunneldRunning() {
366424
JSONObject object = new JSONObject();
367425
object.put("command", "ensure_tunneld_running");

0 commit comments

Comments
 (0)