blob: 7207ce6131bffaadb24388f654d3316b00ac6562 [file] [log] [blame]
/*
* 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());
}
}