blob: b28cc9a86746c4245a0336f62f66df1d57b28c58 [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.emulator.logic;
import static com.motorola.studio.android.common.log.StudioLogger.error;
import static com.motorola.studio.android.common.log.StudioLogger.info;
import java.io.IOException;
import java.util.Collection;
import java.util.LinkedList;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeListener;
import org.eclipse.core.runtime.jobs.IJobManager;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import com.motorola.studio.android.adt.DDMSFacade;
import com.motorola.studio.android.adt.ISerialNumbered;
import com.motorola.studio.android.common.exception.AndroidException;
import com.motorola.studio.android.emulator.EmulatorPlugin;
import com.motorola.studio.android.emulator.core.exception.InstanceStartException;
import com.motorola.studio.android.emulator.core.exception.StartCancelledException;
import com.motorola.studio.android.emulator.core.exception.StartTimeoutException;
import com.motorola.studio.android.emulator.core.model.IAndroidEmulatorInstance;
/**
* This class contains the logic to start the VNC server on the given Emulator.
*/
public final class StartVncServerLogic implements IAndroidLogic
{
public static final String VNC_SERVER_JOB_PREFIX = "VNC Server - ";
public static final Object VNC_SERVER_JOB_FAMILY = new Object();
/**
* Sequence of commands that must be executed on the emulator to start the VNC server
*/
private final Collection<String> remoteCommands = new LinkedList<String>();
/**
* Collection of listeners for the job executing the VNC server.
*/
private final Collection<IJobChangeListener> listeners = new LinkedList<IJobChangeListener>();
/**
* Executes the logic to start the vnc server.
*/
public void execute(final IAndroidLogicInstance instance, int timeout,
final IProgressMonitor monitor) throws InstanceStartException, StartTimeoutException,
StartCancelledException, IOException
{
cancelCurrentVncServerJobs(instance);
// Creates and starts a job that will keep running as long as the VNC server is up on that Emulator instance.
// add listeners that will receive notifications about the Job life-cycle.
VncServerJob vncServerJob = new VncServerJob(instance, getRemoteCommands());
for (IJobChangeListener vncServerListener : listeners)
{
vncServerJob.addJobChangeListener(vncServerListener);
}
vncServerJob.schedule();
}
/**
* Cancel any VncServerJob that is currently running the VNC server on the given emulator instance.
* @param instance, the emulator instances where VNC server execution must be canceled.
**/
public static void cancelCurrentVncServerJobs(IAndroidEmulatorInstance instance)
{
// stop the previous VNC Server job for this instance if any...
IJobManager manager = Job.getJobManager();
Job[] allVncJobs = manager.find(StartVncServerLogic.VNC_SERVER_JOB_FAMILY);
if (allVncJobs.length > 0)
{
for (Job job : allVncJobs)
{
if (job.getName().equals(
StartVncServerLogic.VNC_SERVER_JOB_PREFIX + instance.getName()))
{
info("Cancel execution of the VNC Server on " + instance);
job.cancel();
}
}
}
}
/**
* Add job listener to receive state-change notifications from the job that runs the VNC Server.
* @param vncServerListener job listener that willl receive state change notifications from the VNC Serever job.
*/
public void addVncServerJobListener(IJobChangeListener vncServerListener)
{
listeners.add(vncServerListener);
}
/**
* Add a command to be executed in the process of starting the VNC Server on the Emulator.
* @param remoteCommand
*/
public void addRemoteCommand(String remoteCommand)
{
remoteCommands.add(remoteCommand);
}
/**
* Get the list of commands to be executed on the Emulator in order to start the VNC Server.
* @return the sequence of commands that must be executed on the Emulator to start the VNC Server.
*/
public Collection<String> getRemoteCommands()
{
return remoteCommands;
}
}
/**
* Job that executes the VNC Server.
* It will keep running as long as the VNC Server process is running on the Emulator.
*/
class VncServerJob extends Job implements ISchedulingRule
{
private String serialNumber;
/**
* Sequence of commands that must be executed on the emulator to start the VNC server
*/
private final Collection<String> remoteCommands;
/**
* Creates a new job to execute the VNC server on the given emulator instance.
* @param instance, emulator instance where the VNC server will be started.
* @param remoteCommands, sequence of commands that must be executed on the given emulator instance to start the VNC Server.
* @throws InstanceStartException
*/
public VncServerJob(IAndroidLogicInstance instance, Collection<String> remoteCommands)
throws InstanceStartException
{
super(StartVncServerLogic.VNC_SERVER_JOB_PREFIX + instance.getName());
this.serialNumber = ((ISerialNumbered) instance).getSerialNumber();
try
{
AndroidLogicUtils.testDeviceStatus(serialNumber);
}
catch (AndroidException e)
{
throw new InstanceStartException(e.getMessage());
}
this.remoteCommands = remoteCommands;
setSystem(true);
setRule(this);
}
/**
* @see org.eclipse.core.runtime.jobs.Job#run(IProgressMonitor)
*/
@Override
public IStatus run(IProgressMonitor monitor)
{
IStatus status = Status.OK_STATUS;
try
{
info("Executing VNC Server on " + serialNumber);
AndroidLogicUtils.testDeviceStatus(serialNumber);
DDMSFacade.execRemoteApp(serialNumber, remoteCommands, monitor);
if (monitor.isCanceled())
{
status = Status.CANCEL_STATUS;
}
}
catch (Exception e)
{
String errorMessage = "Error while trying to run the VNC server on " + serialNumber;
error(errorMessage + " " + e.getMessage());
status = new Status(IStatus.CANCEL, EmulatorPlugin.PLUGIN_ID, errorMessage, e);
}
info("Finished the execution of the VNC Server on " + serialNumber + " with status "
+ status);
return status;
}
/**
* @see org.eclipse.core.runtime.jobs.Job#belongsTo(Object)
*/
@Override
public boolean belongsTo(Object family)
{
return StartVncServerLogic.VNC_SERVER_JOB_FAMILY.equals(family);
}
public boolean contains(ISchedulingRule rule)
{
boolean contains = false;
if (rule instanceof VncServerJob)
{
VncServerJob otherVncServerJob = (VncServerJob) rule;
contains = otherVncServerJob.serialNumber.equals(serialNumber);
}
return contains;
}
public boolean isConflicting(ISchedulingRule rule)
{
return contains(rule);
}
}