/*
* Copyright (C) 2013 RoboVM AB
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/gpl-2.0.html>.
*/
package org.robovm.libimobiledevice;
import static org.robovm.libimobiledevice.binding.LibIMobileDeviceConstants.*;
import java.io.IOException;
import org.robovm.libimobiledevice.binding.LibIMobileDevice;
import org.robovm.libimobiledevice.binding.LockdowndClientRef;
import org.robovm.libimobiledevice.binding.LockdowndClientRefOut;
import org.robovm.libimobiledevice.binding.LockdowndError;
import org.robovm.libimobiledevice.binding.LockdowndServiceDescriptorStruct;
import org.robovm.libimobiledevice.binding.LockdowndServiceDescriptorStructOut;
import org.robovm.libimobiledevice.binding.PlistRef;
import org.robovm.libimobiledevice.binding.PlistRefOut;
import com.dd.plist.NSObject;
/**
* Handles device connection communication.
*/
public class LockdowndClient implements AutoCloseable {
protected LockdowndClientRef ref;
LockdowndClient(LockdowndClientRef ref) {
this.ref = ref;
}
/**
* Creates a new {@link LockdowndClient} for the specified {@link IDevice}.
*
* @param device the device to create a {@link LockdowndClient} for.
* @param label the label to use for communication. Usually the program
* name. Pass <code>null</code> to disable sending the label in
* requests to lockdownd.
* @param handshake <code>true</code> if initial handshake should be done.
*/
public LockdowndClient(IDevice device, String label, boolean handshake) {
if (device == null) {
throw new NullPointerException("device");
}
LockdowndClientRefOut refOut = new LockdowndClientRefOut();
try {
checkResult(handshake ?
LibIMobileDevice.lockdownd_client_new_with_handshake(device.getRef(), refOut, label) :
LibIMobileDevice.lockdownd_client_new(device.getRef(), refOut, label));
this.ref = refOut.getValue();
} finally {
refOut.delete();
}
}
protected LockdowndClientRef getRef() {
checkDisposed();
return ref;
}
/**
* Requests to start a service.
*
* @param identifier the name of the service to start.
* @return the service descriptor.
*/
public LockdowndServiceDescriptor startService(String identifier) {
if (identifier == null) {
throw new NullPointerException("identifier");
}
LockdowndServiceDescriptorStructOut serviceOut = new LockdowndServiceDescriptorStructOut();
try {
checkResult(LibIMobileDevice.lockdownd_start_service(getRef(), identifier, serviceOut));
return new LockdowndServiceDescriptor(serviceOut.getValue());
} finally {
LockdowndServiceDescriptorStruct d = serviceOut.getValue();
if (d != null) {
LibIMobileDevice.lockdownd_service_descriptor_free(d);
}
serviceOut.delete();
}
}
/**
* Retrieves a preferences plist using an optional domain and/or key name.
*
* @param domain the domain to query on or <code>null</code> for the global
* domain.
* @param key the key name to request or <code>null</code> to query for all
* keys.
* @return a plist node representing the result value node.
*/
public NSObject getValue(String domain, String key) throws IOException {
PlistRefOut plistOut = new PlistRefOut();
try {
checkResult(LibIMobileDevice.lockdownd_get_value(getRef(), domain, key, plistOut));
PlistRef plist = plistOut.getValue();
return PlistUtil.toJavaPlist(plist);
} finally {
plistOut.delete();
}
}
protected final void checkDisposed() {
if (ref == null) {
throw new LibIMobileDeviceException("Already disposed");
}
}
public synchronized void dispose() {
checkDisposed();
LibIMobileDevice.lockdownd_client_free(ref);
ref = null;
}
@Override
public void close() {
dispose();
}
private static void checkResult(LockdowndError result) {
switch (result) {
case LOCKDOWN_E_SUCCESS: return;
case LOCKDOWN_E_INVALID_ARG: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_INVALID_ARG");
case LOCKDOWN_E_INVALID_CONF: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_INVALID_CONF");
case LOCKDOWN_E_PLIST_ERROR: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_PLIST_ERROR");
case LOCKDOWN_E_PAIRING_FAILED: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_PAIRING_FAILED");
case LOCKDOWN_E_SSL_ERROR: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_SSL_ERROR");
case LOCKDOWN_E_DICT_ERROR: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_DICT_ERROR");
case LOCKDOWN_E_START_SERVICE_FAILED: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_START_SERVICE_FAILED");
case LOCKDOWN_E_NOT_ENOUGH_DATA: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_NOT_ENOUGH_DATA");
case LOCKDOWN_E_SET_VALUE_PROHIBITED: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_SET_VALUE_PROHIBITED");
case LOCKDOWN_E_GET_VALUE_PROHIBITED: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_GET_VALUE_PROHIBITED");
case LOCKDOWN_E_REMOVE_VALUE_PROHIBITED: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_REMOVE_VALUE_PROHIBITED");
case LOCKDOWN_E_MUX_ERROR: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_MUX_ERROR");
case LOCKDOWN_E_ACTIVATION_FAILED: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_ACTIVATION_FAILED");
case LOCKDOWN_E_PASSWORD_PROTECTED: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_PASSWORD_PROTECTED");
case LOCKDOWN_E_NO_RUNNING_SESSION: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_NO_RUNNING_SESSION");
case LOCKDOWN_E_INVALID_HOST_ID: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_INVALID_HOST_ID");
case LOCKDOWN_E_INVALID_SERVICE: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_INVALID_SERVICE");
case LOCKDOWN_E_INVALID_ACTIVATION_RECORD: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_INVALID_ACTIVATION_RECORD");
case LOCKDOWN_E_PAIRING_DIALOG_PENDING: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_PAIRING_DIALOG_PENDING");
case LOCKDOWN_E_USER_DENIED_PAIRING: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_USER_DENIED_PAIRING");
case LOCKDOWN_E_UNKNOWN_ERROR: throw new LibIMobileDeviceException(result.swigValue(), "LOCKDOWN_E_UNKNOWN_ERROR");
default: throw new LibIMobileDeviceException(result.swigValue());
}
}
}