/* | |
* Copyright (C) 2012 The Android Open Source Project | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package com.motorola.studio.android.remote.ui.wireless.runnables; | |
import java.io.IOException; | |
import java.lang.reflect.InvocationTargetException; | |
import java.util.List; | |
import org.eclipse.core.runtime.IProgressMonitor; | |
import org.eclipse.core.runtime.IStatus; | |
import org.eclipse.core.runtime.Status; | |
import org.eclipse.core.runtime.SubMonitor; | |
import org.eclipse.jface.operation.IRunnableWithProgress; | |
import org.eclipse.jface.wizard.Wizard; | |
import org.eclipse.sequoyah.device.common.utilities.exception.SequoyahException; | |
import org.eclipse.sequoyah.device.framework.DevicePlugin; | |
import org.eclipse.sequoyah.device.framework.factory.InstanceRegistry; | |
import org.eclipse.sequoyah.device.framework.manager.InstanceManager; | |
import org.eclipse.sequoyah.device.framework.model.IInstance; | |
import com.motorola.studio.android.AndroidPlugin; | |
import com.motorola.studio.android.adt.DDMSFacade; | |
import com.motorola.studio.android.common.log.StudioLogger; | |
import com.motorola.studio.android.remote.i18n.RemoteDeviceNLS; | |
import com.motorola.studio.android.remote.instance.RemoteDeviceInstance; | |
import com.motorola.studio.android.remote.ui.wireless.WirelessWizard; | |
/** | |
* Service which switches the device to TCP/IP, add it as a remote | |
* device to the Device Management and connect to it via the wireless | |
* network. | |
*/ | |
public class SwitchFromUSBAndConnectToWirelessRunnable implements IRunnableWithProgress | |
{ | |
private final WirelessWizard wirelessWizard; | |
/** | |
* Constructor which passes the {@link Wizard} page. | |
* | |
* @param wirelessWizard Wizard paged | |
*/ | |
public SwitchFromUSBAndConnectToWirelessRunnable(WirelessWizard wirelessWizard) | |
{ | |
this.wirelessWizard = wirelessWizard; | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor) | |
*/ | |
public void run(IProgressMonitor monitor) throws InvocationTargetException, | |
InterruptedException | |
{ | |
boolean isInstanceCreated = false; | |
SubMonitor subMonitor = SubMonitor.convert(monitor, 1000); | |
subMonitor | |
.beginTask( | |
RemoteDeviceNLS.SwitchFromUSBAndConnectToWirelessRunnable_MsgCreatingWirelessRemoteDevice, | |
1000); | |
RemoteDeviceInstance remoteDeviceInstance = null; | |
IStatus status = Status.OK_STATUS; | |
// get connection timeout | |
int connectionTimeout = | |
Integer.valueOf(this.wirelessWizard.getProperties().getProperty( | |
RemoteDeviceInstance.PROPERTY_TIMEOUT)); | |
try | |
{ | |
subMonitor.worked(100); | |
if (!subMonitor.isCanceled()) | |
{ | |
// switch device connection from USB to TCP/IP | |
try | |
{ | |
status = | |
DDMSFacade.switchUSBtoTcpIp(this.wirelessWizard.getInstance() | |
.getDeviceName(), this.wirelessWizard.getInstance() | |
.getSerialNumber(), this.wirelessWizard.getProperties() | |
.getProperty(RemoteDeviceInstance.PROPERTY_PORT), | |
connectionTimeout, subMonitor.newChild(300)); | |
} | |
catch (IOException se) | |
{ | |
// log error, adjust the status and throw the exception | |
status = handleStatusAndLogDuringException(se); | |
throw new InvocationTargetException(se, se.getMessage()); | |
} | |
} | |
remoteDeviceInstance = null; | |
if (!(status.getSeverity() == IStatus.ERROR) && !subMonitor.isCanceled()) | |
{ | |
subMonitor | |
.setTaskName(RemoteDeviceNLS.SwitchFromUSBAndConnectToWirelessRunnable_CreatingRemoteDeviceInstance); | |
// verify if there already is an instance created with the same name | |
List<IInstance> instanceByName = | |
InstanceRegistry.getInstance().getInstancesByName( | |
this.wirelessWizard.getDeviceName()); | |
if ((instanceByName != null) && (!instanceByName.isEmpty())) | |
{ | |
remoteDeviceInstance = (RemoteDeviceInstance) instanceByName.get(0); | |
} | |
else | |
{ | |
// create the new remote device instance | |
try | |
{ | |
remoteDeviceInstance = | |
(RemoteDeviceInstance) InstanceManager.createInstance( | |
this.wirelessWizard.getDeviceName(), //$NON-NLS-1$ | |
"com.motorola.studio.android.remote.androidRemoteDevice", //$NON-NLS-1$ | |
DevicePlugin.SEQUOYAH_STATUS_OFF, | |
this.wirelessWizard.getProperties()); | |
} | |
catch (SequoyahException se) | |
{ | |
// log error, adjust the status and throw the exception | |
status = handleStatusAndLogDuringException(se); | |
throw new InvocationTargetException(se, se.getMessage()); | |
} | |
if (!subMonitor.isCanceled()) | |
{ | |
// add instance to the DDMS and set the flag | |
InstanceRegistry.getInstance().addInstance(remoteDeviceInstance); | |
isInstanceCreated = true; | |
} | |
} | |
subMonitor.worked(300); | |
} | |
if (!subMonitor.isCanceled()) | |
{ | |
subMonitor | |
.setTaskName(RemoteDeviceNLS.SwitchFromUSBAndConnectToWirelessRunnable_ConnectingToWifiDevice); | |
int timeoutAux = (connectionTimeout > 60) ? connectionTimeout : 60; | |
long timeoutLimit = System.currentTimeMillis() + (timeoutAux * 1000); | |
// after the adb mode is switched to tcpip the handset takes a while to | |
// be available for connection, that is why this while exists | |
while ((!DDMSFacade.isDeviceOnline(remoteDeviceInstance.getSerialNumber())) | |
&& (System.currentTimeMillis() < timeoutLimit)) | |
{ | |
// connect the remote device via TCP/IP | |
try | |
{ | |
status = | |
DDMSFacade.connectTcpIp( | |
remoteDeviceInstance, | |
this.wirelessWizard.getProperties().getProperty( | |
RemoteDeviceInstance.PROPERTY_HOST), | |
this.wirelessWizard.getProperties().getProperty( | |
RemoteDeviceInstance.PROPERTY_PORT), | |
connectionTimeout, subMonitor.newChild(300)); | |
} | |
catch (IOException ioe) | |
{ | |
status = handleStatusAndLogDuringException(ioe); | |
throw new InvocationTargetException(ioe, ioe.getMessage()); | |
} | |
} | |
} | |
// in case the status has errors, throw InvocationTargetException | |
if ((status != null) && (status.getSeverity() == IStatus.ERROR) | |
&& (!subMonitor.isCanceled())) | |
{ | |
if (status.getException() != null) | |
{ | |
throw new InvocationTargetException(status.getException()); | |
} | |
else | |
{ | |
throw new InvocationTargetException( | |
new Exception( | |
RemoteDeviceNLS.SwitchFromUSBAndConnectToWirelessRunnable_MsgNotPossibleToConvertUSBToTCPIP)); | |
} | |
} | |
// treat the case where the monitor is canceled - throw InterruptedException as stated in this method | |
if (monitor.isCanceled()) | |
{ | |
throw new InterruptedException( | |
"The switching to TCP/IP connection mode was canceled by the user."); | |
} | |
} | |
finally | |
{ | |
// remove the device in case it exists and was added to the Device Management View | |
if ((remoteDeviceInstance != null) && (isInstanceCreated) | |
&& ((status.getSeverity() == IStatus.ERROR) || (subMonitor.isCanceled()))) | |
{ | |
InstanceRegistry.getInstance().removeInstance(remoteDeviceInstance); | |
} | |
} | |
} | |
/* | |
* Log the exception and get the error status. | |
* | |
* @param exception The exception to be treated. | |
* | |
* @return Returns the Error status. | |
*/ | |
private IStatus handleStatusAndLogDuringException(Exception exception) | |
{ | |
StudioLogger.error(this.getClass(), exception.getMessage(), exception); | |
return new Status(IStatus.ERROR, AndroidPlugin.PLUGIN_ID, exception.getMessage()); | |
} | |
} |