org.eclipse.andmore.android.remote.ui.wireless.runnables.SwitchFromUSBAndConnectToWirelessRunnable.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.andmore.android.remote.ui.wireless.runnables.SwitchFromUSBAndConnectToWirelessRunnable.java

Source

/*
 * 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 org.eclipse.andmore.android.remote.ui.wireless.runnables;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

import org.eclipse.andmore.android.AndroidPlugin;
import org.eclipse.andmore.android.DDMSFacade;
import org.eclipse.andmore.android.common.log.AndmoreLogger;
import org.eclipse.andmore.android.remote.i18n.RemoteDeviceNLS;
import org.eclipse.andmore.android.remote.instance.RemoteDeviceInstance;
import org.eclipse.andmore.android.remote.ui.wireless.WirelessWizard;
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;

/**
 * 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)
     */
    @Override
    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(),
                                "org.eclipse.andmore.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) {
        AndmoreLogger.error(this.getClass(), exception.getMessage(), exception);
        return new Status(IStatus.ERROR, AndroidPlugin.PLUGIN_ID, exception.getMessage());
    }
}