use of org.robovm.libimobiledevice.LockdowndServiceDescriptor in project robovm by robovm.
the class AppLauncher method installInternal.
private void installInternal() throws Exception {
try (LockdowndClient lockdowndClient = new LockdowndClient(device, getClass().getSimpleName(), true)) {
final LibIMobileDeviceException[] ex = new LibIMobileDeviceException[1];
final CountDownLatch countDownLatch = new CountDownLatch(1);
LockdowndServiceDescriptor instproxyService = lockdowndClient.startService(InstallationProxyClient.SERVICE_NAME);
try (InstallationProxyClient instClient = new InstallationProxyClient(device, instproxyService)) {
instClient.upgrade("/PublicStaging/" + localAppPath.getName(), new Options().packageType(localAppPath.isDirectory() ? PackageType.Developer : null), new StatusCallback() {
@Override
public void progress(String status, int percentComplete) {
if (installStatusCallback != null) {
installStatusCallback.progress(status, percentComplete);
} else {
log("[%3d%%] %s", 50 + percentComplete / 2, status);
}
}
@Override
public void success() {
try {
if (installStatusCallback != null) {
installStatusCallback.success();
} else {
log("[100%%] Installation complete");
}
} finally {
countDownLatch.countDown();
}
}
@Override
public void error(String message) {
try {
ex[0] = new LibIMobileDeviceException(message);
if (installStatusCallback != null) {
installStatusCallback.error(message);
} else {
log("Error: %s", message);
}
} finally {
countDownLatch.countDown();
}
}
});
countDownLatch.await();
}
if (ex[0] != null) {
throw ex[0];
}
}
}
use of org.robovm.libimobiledevice.LockdowndServiceDescriptor in project robovm by robovm.
the class AppLauncher method launchInternal.
private int launchInternal() throws Exception {
install();
int lockedRetriesLeft = launchOnLockedRetries;
while (true) {
IDeviceConnection conn = null;
String appPath = null;
try (LockdowndClient lockdowndClient = new LockdowndClient(device, getClass().getSimpleName(), true)) {
appPath = getAppPath(lockdowndClient, appId);
// E.g. 7.0.2
String productVersion = lockdowndClient.getValue(null, "ProductVersion").toString();
// E.g. 11B508
String buildVersion = lockdowndClient.getValue(null, "BuildVersion").toString();
if (appLauncherCallback != null) {
appLauncherCallback.setAppLaunchInfo(new AppLauncherInfo(device, appPath, productVersion, buildVersion));
}
LockdowndServiceDescriptor debugService = null;
try {
debugService = lockdowndClient.startService(DEBUG_SERVER_SERVICE_NAME);
} catch (LibIMobileDeviceException e) {
if (e.getErrorCode() == LockdowndError.LOCKDOWN_E_INVALID_SERVICE.swigValue()) {
// This happens when the developer image hasn't been mounted.
// Mount and try again.
mountDeveloperImage(lockdowndClient);
debugService = lockdowndClient.startService(DEBUG_SERVER_SERVICE_NAME);
} else {
throw e;
}
}
conn = device.connect(debugService.getPort());
log("Debug server port: " + debugService.getPort());
if (localPort != -1) {
String exe = ((NSDictionary) PropertyListParser.parse(new File(localAppPath, "Info.plist"))).objectForKey("CFBundleExecutable").toString();
log("launchios \"" + new File(localAppPath, exe).getAbsolutePath() + "\" \"" + appPath + "\" " + localPort);
StringBuilder argsString = new StringBuilder();
for (String arg : args) {
if (argsString.length() > 0) {
argsString.append(' ');
}
argsString.append(arg);
}
log("process launch -- " + argsString);
}
}
if (lockedRetriesLeft == launchOnLockedRetries) {
// First try
log("Remote app path: " + appPath);
log("Launching app...");
} else {
log("Launching app (retry %d of %d)...", (launchOnLockedRetries - lockedRetriesLeft), launchOnLockedRetries);
}
try {
// otherwise perform port forwarding and stdout piping
if (localPort == -1) {
return pipeStdOut(conn, appPath);
} else {
return forward(conn, appPath);
}
} catch (RuntimeException e) {
if (!e.getMessage().contains("Locked") || lockedRetriesLeft == 0) {
throw e;
}
lockedRetriesLeft--;
log("Device locked. Retrying launch in %d seconds...", secondsBetweenLaunchOnLockedRetries);
Thread.sleep(secondsBetweenLaunchOnLockedRetries * 1000);
} finally {
conn.dispose();
}
}
}
use of org.robovm.libimobiledevice.LockdowndServiceDescriptor in project robovm by robovm.
the class AppLauncher method getAppPath.
private String getAppPath(LockdowndClient lockdowndClient, String appId) throws IOException {
LockdowndServiceDescriptor instService = lockdowndClient.startService(InstallationProxyClient.SERVICE_NAME);
try (InstallationProxyClient instClient = new InstallationProxyClient(device, instService)) {
NSArray apps = instClient.browse();
for (int i = 0; i < apps.count(); i++) {
NSDictionary appInfo = (NSDictionary) apps.objectAtIndex(i);
NSString bundleId = (NSString) appInfo.objectForKey("CFBundleIdentifier");
if (bundleId != null && appId.equals(bundleId.toString())) {
NSString path = (NSString) appInfo.objectForKey("Path");
NSDictionary entitlements = (NSDictionary) appInfo.objectForKey("Entitlements");
if (entitlements == null || entitlements.objectForKey("get-task-allow") == null || !entitlements.objectForKey("get-task-allow").equals(new NSNumber(true))) {
throw new RuntimeException("App with id '" + appId + "' does not " + "have the 'get-task-allow' entitlement and cannot be debugged");
}
if (path == null) {
throw new RuntimeException("Path for app with id '" + appId + "' not found");
}
return path.toString();
}
}
throw new RuntimeException("No app with id '" + appId + "' found on device");
}
}
use of org.robovm.libimobiledevice.LockdowndServiceDescriptor in project robovm by robovm.
the class AppLauncher method mountDeveloperImage.
private void mountDeveloperImage(LockdowndClient lockdowndClient) throws Exception {
// Find the DeveloperDiskImage.dmg path that best matches the current device. Here's what
// the paths look like:
// Platforms/iPhoneOS.platform/DeviceSupport/5.0/DeveloperDiskImage.dmg
// Platforms/iPhoneOS.platform/DeviceSupport/6.0/DeveloperDiskImage.dmg
// Platforms/iPhoneOS.platform/DeviceSupport/6.1/DeveloperDiskImage.dmg
// Platforms/iPhoneOS.platform/DeviceSupport/7.0/DeveloperDiskImage.dmg
// Platforms/iPhoneOS.platform/DeviceSupport/7.0 (11A465)/DeveloperDiskImage.dmg
// Platforms/iPhoneOS.platform/DeviceSupport/7.0.3 (11B508)/DeveloperDiskImage.dmg
// E.g. 7.0.2
String productVersion = lockdowndClient.getValue(null, "ProductVersion").toString();
// E.g. 11B508
String buildVersion = lockdowndClient.getValue(null, "BuildVersion").toString();
File deviceSupport = new File(getXcodePath(), "Platforms/iPhoneOS.platform/DeviceSupport");
log("Looking up developer disk image for iOS version %s (%s) in %s", productVersion, buildVersion, deviceSupport);
File devImage = findDeveloperImage(deviceSupport, productVersion, buildVersion);
File devImageSig = new File(devImage.getParentFile(), devImage.getName() + ".signature");
byte[] devImageSigBytes = Files.readAllBytes(devImageSig.toPath());
LockdowndServiceDescriptor mimService = lockdowndClient.startService(MobileImageMounterClient.SERVICE_NAME);
try (MobileImageMounterClient mimClient = new MobileImageMounterClient(device, mimService)) {
log("Copying developer disk image %s to device", devImage);
int majorVersion = Integer.parseInt(getProductVersionParts(productVersion)[0]);
if (majorVersion >= 7) {
// Use new upload method
mimClient.uploadImage(devImage, null, devImageSigBytes);
} else {
LockdowndServiceDescriptor afcService = lockdowndClient.startService(AfcClient.SERVICE_NAME);
try (AfcClient afcClient = new AfcClient(device, afcService)) {
afcClient.makeDirectory("/PublicStaging");
afcClient.fileCopy(devImage, "/PublicStaging/staging.dimage");
}
}
log("Mounting developer disk image");
NSDictionary result = mimClient.mountImage("/PublicStaging/staging.dimage", devImageSigBytes, null);
NSString status = (NSString) result.objectForKey("Status");
if (status == null || !"Complete".equals(status.toString())) {
throw new IOException("Failed to mount " + devImage.getAbsolutePath() + " on the device.");
}
}
}
Aggregations