| /* |
| * 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.launch; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.debug.core.ILaunch; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
| import org.eclipse.debug.core.ILaunchManager; |
| import org.eclipse.debug.ui.DebugUITools; |
| import org.eclipse.debug.ui.IDebugUIConstants; |
| import org.eclipse.debug.ui.ILaunchGroup; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.sequoyah.device.framework.model.IInstance; |
| import org.eclipse.sequoyah.device.framework.model.handler.ServiceHandler; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.console.ConsolePlugin; |
| import org.eclipse.ui.console.IConsole; |
| |
| import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener; |
| import com.android.ddmlib.Client; |
| import com.android.ddmlib.ClientData; |
| import com.android.ide.eclipse.adt.AdtPlugin; |
| import com.android.ide.eclipse.adt.internal.launch.AndroidLaunch; |
| import com.android.ide.eclipse.adt.internal.launch.AndroidLaunchController; |
| import com.android.ide.eclipse.adt.internal.launch.LaunchConfigDelegate; |
| import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs; |
| import com.android.ide.eclipse.adt.internal.sdk.Sdk; |
| import com.android.ide.eclipse.adt.io.IFolderWrapper; |
| import com.android.sdklib.xml.AndroidManifestParser; |
| import com.android.sdklib.xml.ManifestData; |
| import com.android.sdklib.xml.ManifestData.Activity; |
| import com.motorola.studio.android.adt.DDMSFacade; |
| import com.motorola.studio.android.adt.SdkUtils; |
| import com.motorola.studio.android.adt.StudioAndroidEventManager; |
| import com.motorola.studio.android.common.log.StudioLogger; |
| import com.motorola.studio.android.common.preferences.DialogWithToggleUtils; |
| import com.motorola.studio.android.emulator.EmulatorPlugin; |
| import com.motorola.studio.android.emulator.core.devfrm.DeviceFrameworkManager; |
| import com.motorola.studio.android.emulator.core.model.IAndroidEmulatorInstance; |
| import com.motorola.studio.android.launch.i18n.LaunchNLS; |
| import com.motorola.studio.android.launch.ui.StartedInstancesDialog; |
| |
| /** |
| * DESCRIPTION: This class is responsible to execute the launch process <br> |
| * RESPONSIBILITY: Perform application launch on a device. <br> |
| * COLABORATORS: none <br> |
| */ |
| @SuppressWarnings("restriction") |
| public class StudioAndroidConfigurationDelegate extends LaunchConfigDelegate |
| { |
| |
| private static final String ERRONEOUS_LAUNCH_CONFIGURATION = "erroneous.launch.config.dialog"; |
| |
| private static final String NO_COMPATIBLE_DEVICE = "no.compatible.device.dialog"; |
| |
| IAndroidEmulatorInstance compatibleInstance = null; |
| |
| IAndroidEmulatorInstance initialEmulatorInstance = null; |
| |
| public List<Client> waitingDebugger = new ArrayList<Client>(); |
| |
| private class RunAsClientListener implements IClientChangeListener |
| { |
| /** |
| * |
| */ |
| private final IAndroidEmulatorInstance instance; |
| |
| /** |
| * |
| */ |
| private final String appToLaunch; |
| |
| /** |
| * |
| * @param instance |
| */ |
| RunAsClientListener(IAndroidEmulatorInstance instance, String appToLaunch) |
| { |
| this.instance = instance; |
| this.appToLaunch = appToLaunch; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see com.android.ddmlib.AndroidDebugBridge.IClientChangeListener#clientChanged(com.android.ddmlib.Client, int) |
| */ |
| public void clientChanged(Client client, int changeMask) |
| { |
| if ((changeMask & Client.CHANGE_NAME) == Client.CHANGE_NAME) |
| { |
| String applicationName = client.getClientData().getClientDescription(); |
| if (applicationName != null) |
| { |
| IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore(); |
| String home = store.getString(AdtPrefs.PREFS_HOME_PACKAGE); |
| if (home.equals(applicationName)) |
| { |
| String serialNumber = client.getDevice().getSerialNumber(); |
| String avdName = DDMSFacade.getNameBySerialNumber(serialNumber); |
| if ((instance != null) && instance.getName().equals(avdName)) |
| { |
| StudioLogger.info(StudioAndroidConfigurationDelegate.class, |
| "Delegating launch session to ADT... "); |
| |
| synchronized (StudioAndroidConfigurationDelegate.this) |
| { |
| StudioAndroidConfigurationDelegate.this.notify(); |
| } |
| } |
| } |
| |
| Client removeClient = null; |
| for (Client waiting : waitingDebugger) |
| { |
| int pid = waiting.getClientData().getPid(); |
| if (pid == client.getClientData().getPid()) |
| { |
| client.getDebuggerListenPort(); |
| synchronized (StudioAndroidConfigurationDelegate.this) |
| { |
| StudioAndroidConfigurationDelegate.this.notify(); |
| } |
| removeClient = waiting; |
| break; |
| } |
| } |
| |
| if (removeClient != null) |
| { |
| waitingDebugger.remove(removeClient); |
| } |
| } |
| } |
| |
| if ((changeMask & Client.CHANGE_DEBUGGER_STATUS) == Client.CHANGE_DEBUGGER_STATUS) |
| { |
| ClientData clientData = client.getClientData(); |
| String applicationName = clientData.getClientDescription(); |
| if (clientData.getDebuggerConnectionStatus() == ClientData.DebuggerStatus.DEFAULT) |
| { |
| if (((appToLaunch != null) && (applicationName != null)) |
| && applicationName.equals(appToLaunch.substring(0, |
| appToLaunch.lastIndexOf(".")))) |
| { |
| client.getDebuggerListenPort(); |
| synchronized (StudioAndroidConfigurationDelegate.this) |
| { |
| StudioAndroidConfigurationDelegate.this.notify(); |
| } |
| } |
| else if (appToLaunch != null) |
| { |
| waitingDebugger.add(client); |
| } |
| } |
| } |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.debug.core.model.LaunchConfigurationDelegate#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| @Override |
| public boolean preLaunchCheck(ILaunchConfiguration configuration, String mode, |
| IProgressMonitor monitor) throws CoreException |
| { |
| initialEmulatorInstance = null; |
| boolean isOk = super.preLaunchCheck(configuration, mode, monitor); |
| |
| if (isOk) |
| { |
| final String instanceName = |
| configuration.getAttribute( |
| ILaunchConfigurationConstants.ATTR_DEVICE_INSTANCE_NAME, (String) null); |
| |
| // we found an instance |
| if ((instanceName != null) && (instanceName.length() > 0)) |
| { |
| IAndroidEmulatorInstance instance = |
| DeviceFrameworkManager.getInstance().getInstanceByName(instanceName); |
| if (instance == null) |
| { |
| String serialNumber = LaunchUtils.getSerialNumberForInstance(instanceName); |
| if (!DDMSFacade.isDeviceOnline(serialNumber)) |
| { |
| isOk = false; |
| handleErrorDuringLaunch(configuration, mode, instanceName); |
| } |
| } |
| else |
| { |
| if (!instance.isAvailable()) |
| { |
| isOk = false; |
| handleErrorDuringLaunch(configuration, mode, instanceName); |
| } |
| |
| if (!instance.isStarted()) |
| { |
| initialEmulatorInstance = instance; |
| //updates the compatible instance with user response |
| isOk = checkForCompatibleRunningInstances(configuration); |
| } |
| } |
| } |
| else |
| { |
| isOk = false; |
| handleErrorDuringLaunch(configuration, mode, null); |
| } |
| } |
| // validate if the project isn't a library project |
| if (isOk) |
| { |
| String projectName = |
| configuration.getAttribute(ILaunchConfigurationConstants.ATTR_PROJECT_NAME, |
| (String) null); |
| if (projectName != null) |
| { |
| IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); |
| if ((project != null) && SdkUtils.isLibraryProject(project)) |
| { |
| handleProjectError(configuration, project, mode); |
| isOk = false; |
| } |
| } |
| } |
| |
| return isOk; |
| } |
| |
| private void handleProjectError(final ILaunchConfiguration config, final IProject project, |
| final String mode) |
| { |
| PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() |
| { |
| |
| public void run() |
| { |
| Shell shell = LaunchUtils.getActiveWorkbenchShell(); |
| |
| String message = LaunchNLS.UI_LaunchConfigurationTab_ERR_PROJECT_IS_LIBRARY; |
| |
| String prefKey = ERRONEOUS_LAUNCH_CONFIGURATION; |
| |
| DialogWithToggleUtils.showInformation(prefKey, |
| LaunchNLS.ERR_LaunchConfigurationShortcut_MsgTitle, message); |
| |
| StructuredSelection struturedSelection; |
| |
| String groupId = IDebugUIConstants.ID_RUN_LAUNCH_GROUP; |
| |
| ILaunchGroup group = DebugUITools.getLaunchGroup(config, mode); |
| groupId = group.getIdentifier(); |
| struturedSelection = new StructuredSelection(config); |
| |
| DebugUITools.openLaunchConfigurationDialogOnGroup(shell, struturedSelection, |
| groupId); |
| } |
| }); |
| } |
| |
| private void handleErrorDuringLaunch(final ILaunchConfiguration config, final String mode, |
| final String instanceName) |
| { |
| PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() |
| { |
| |
| public void run() |
| { |
| Shell shell = LaunchUtils.getActiveWorkbenchShell(); |
| |
| String message = |
| instanceName != null ? NLS.bind( |
| LaunchNLS.ERR_LaunchDelegate_InvalidDeviceInstance, instanceName) |
| : NLS.bind(LaunchNLS.ERR_LaunchDelegate_No_Compatible_Device, |
| config.getName()); |
| |
| String prefKey = |
| instanceName != null ? ERRONEOUS_LAUNCH_CONFIGURATION |
| : NO_COMPATIBLE_DEVICE; |
| |
| DialogWithToggleUtils.showInformation(prefKey, |
| LaunchNLS.ERR_LaunchConfigurationShortcut_MsgTitle, message); |
| |
| StructuredSelection struturedSelection; |
| |
| String groupId = IDebugUIConstants.ID_RUN_LAUNCH_GROUP; |
| |
| ILaunchGroup group = DebugUITools.getLaunchGroup(config, mode); |
| groupId = group.getIdentifier(); |
| struturedSelection = new StructuredSelection(config); |
| |
| DebugUITools.openLaunchConfigurationDialogOnGroup(shell, struturedSelection, |
| groupId); |
| } |
| }); |
| } |
| |
| /** |
| * Launches an Android application based on the given launch configuration. |
| */ |
| @Override |
| public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, |
| IProgressMonitor monitor) throws CoreException |
| |
| { |
| //use a working copy because it can be changed and these changes should not be propagated to the original copy |
| ILaunchConfigurationWorkingCopy configurationWorkingCopy = configuration.getWorkingCopy(); |
| |
| StudioLogger.info(StudioAndroidConfigurationDelegate.class, |
| "Launch Android Application using Studio for Android wizard. Configuration: " |
| + configurationWorkingCopy + " mode:" + mode + " launch: " + launch); |
| try |
| { |
| |
| String projectName = |
| configurationWorkingCopy.getAttribute( |
| ILaunchConfigurationConstants.ATTR_PROJECT_NAME, (String) null); |
| int launchAction = |
| configurationWorkingCopy.getAttribute( |
| ILaunchConfigurationConstants.ATTR_LAUNCH_ACTION, |
| ILaunchConfigurationConstants.ATTR_LAUNCH_ACTION_DEFAULT); |
| |
| String instanceName = |
| configurationWorkingCopy.getAttribute( |
| ILaunchConfigurationConstants.ATTR_DEVICE_INSTANCE_NAME, (String) null); |
| |
| if ((projectName != null) && (instanceName != null)) |
| { |
| IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); |
| if (project == null) |
| { |
| IStatus status = |
| new Status(Status.ERROR, LaunchPlugin.PLUGIN_ID, |
| "Could not retrieve project: " + projectName); |
| throw new CoreException(status); |
| } |
| |
| String appToLaunch = null; |
| if (launchAction == ILaunchConfigurationConstants.ATTR_LAUNCH_ACTION_DEFAULT) |
| { |
| ManifestData manifestParser = |
| AndroidManifestParser.parse(new IFolderWrapper(project)); |
| Activity launcherActivity = manifestParser.getLauncherActivity(); |
| String activityName = null; |
| if (launcherActivity != null) |
| { |
| activityName = launcherActivity.getName(); |
| } |
| |
| // if there's no default activity. Then there's nothing to be launched. |
| if (activityName != null) |
| { |
| appToLaunch = activityName; |
| } |
| } |
| // case for a specific activity |
| else if (launchAction == ILaunchConfigurationConstants.ATTR_LAUNCH_ACTION_ACTIVITY) |
| { |
| appToLaunch = |
| configurationWorkingCopy.getAttribute( |
| ILaunchConfigurationConstants.ATTR_ACTIVITY, (String) null); |
| |
| if ((appToLaunch == null) || "".equals(appToLaunch)) |
| { |
| IStatus status = |
| new Status( |
| Status.ERROR, |
| LaunchPlugin.PLUGIN_ID, |
| "Activity field cannot be empty. Specify an activity or use the default activity on launch configuration."); |
| throw new CoreException(status); |
| } |
| } |
| // for the do nothing case there is nothing to do |
| |
| IAndroidEmulatorInstance emuInstance = |
| DeviceFrameworkManager.getInstance().getInstanceByName(instanceName); |
| |
| RunAsClientListener list = null; |
| |
| //if initialEmulatorInstance is not null it means that it was offline and user has interacted with StartedInstancesDialog. |
| //The emuInstance variable should be overrided by the initialEmulatorInstance because the emuInstance can be the new |
| //user choice (in case he has selected the check box in dialog asking to update the run configuration) |
| if (initialEmulatorInstance != null) |
| { |
| emuInstance = initialEmulatorInstance; |
| } |
| |
| try |
| { |
| if (appToLaunch != null) |
| { |
| list = new RunAsClientListener(emuInstance, appToLaunch); |
| StudioAndroidEventManager.asyncAddClientChangeListener(list); |
| } |
| |
| // The instance from the launch configuration is an emulator (because the query returned |
| // something different from null) and is not started. |
| if ((emuInstance != null) && (!emuInstance.isStarted())) |
| { |
| if (compatibleInstance != null) |
| { |
| emuInstance = compatibleInstance; |
| instanceName = emuInstance.getName(); |
| configurationWorkingCopy.setAttribute( |
| ILaunchConfigurationConstants.ATTR_DEVICE_INSTANCE_NAME, |
| emuInstance.getName()); |
| configurationWorkingCopy.setAttribute( |
| ILaunchConfigurationConstants.ATTR_ADT_DEVICE_INSTANCE_NAME, |
| emuInstance.getName()); |
| } |
| else |
| { |
| startEmuInstance(emuInstance); |
| } |
| } |
| |
| StudioLogger.info(StudioAndroidConfigurationDelegate.class, |
| "AVD where the application will be executed: " + instanceName); |
| |
| |
| String serialNumber = LaunchUtils.getSerialNumberForInstance(instanceName); |
| if (serialNumber == null) |
| { |
| IStatus status = |
| new Status(Status.ERROR, LaunchPlugin.PLUGIN_ID, |
| "Could not retrieve AVD instance: " + instanceName); |
| throw new CoreException(status); |
| } |
| |
| bringConsoleView(); |
| |
| // Determining if it is an emulator or handset and creating the description |
| //to be used for usage data collection |
| String descriptionToLog = ""; |
| if (emuInstance != null) |
| { |
| descriptionToLog = StudioLogger.VALUE_EMULATOR; |
| } |
| else |
| { |
| if ((serialNumber != null) && (!serialNumber.equals(""))) |
| { |
| descriptionToLog = StudioLogger.VALUE_HANDSET; |
| } |
| } |
| |
| if (!descriptionToLog.equals("")) |
| { |
| descriptionToLog = |
| StudioLogger.KEY_DEVICE_TYPE + descriptionToLog |
| + StudioLogger.SEPARATOR; |
| } |
| |
| descriptionToLog = descriptionToLog + StudioLogger.KEY_USE_VDL; |
| |
| descriptionToLog = descriptionToLog + StudioLogger.VALUE_NO; |
| super.launch(configurationWorkingCopy, mode, launch, monitor); |
| |
| // Collecting usage data for statistical purposes |
| try |
| { |
| String prjTarget = ""; |
| if (project != null) |
| { |
| prjTarget = Sdk.getCurrent().getTarget(project).getName(); |
| } |
| |
| if (!descriptionToLog.equals("")) |
| { |
| descriptionToLog = descriptionToLog + StudioLogger.SEPARATOR; |
| } |
| |
| descriptionToLog = |
| descriptionToLog + StudioLogger.KEY_PRJ_TARGET + prjTarget; |
| |
| if (emuInstance != null) |
| { |
| String emuTarget = emuInstance.getTarget(); |
| descriptionToLog = descriptionToLog + StudioLogger.SEPARATOR; |
| descriptionToLog = |
| descriptionToLog + StudioLogger.KEY_TARGET + emuTarget; |
| } |
| |
| StudioLogger.collectUsageData(mode, StudioLogger.KIND_APP_MANAGEMENT, |
| descriptionToLog, LaunchPlugin.PLUGIN_ID, LaunchPlugin.getDefault() |
| .getBundle().getVersion().toString()); |
| } |
| catch (Throwable e) |
| { |
| //Do nothing, but error on the log should never prevent app from working |
| } |
| |
| } |
| finally |
| { |
| if (list != null) |
| { |
| StudioAndroidEventManager.asyncRemoveClientChangeListener(list); |
| } |
| StudioAndroidEventManager.asyncAddClientChangeListener(AndroidLaunchController |
| .getInstance()); |
| } |
| } |
| else |
| { |
| throw new CoreException(new Status(IStatus.ERROR, LaunchPlugin.PLUGIN_ID, |
| "Missing parameters for launch")); |
| } |
| } |
| catch (CoreException e) |
| { |
| AndroidLaunch androidLaunch = (AndroidLaunch) launch; |
| androidLaunch.stopLaunch(); |
| StudioLogger.error(StudioAndroidConfigurationDelegate.class, "Error while lauching " |
| + configurationWorkingCopy.getName(), e); |
| throw e; |
| } |
| catch (Exception e) |
| { |
| StudioLogger.error(LaunchUtils.class, |
| "An error occurred trying to parse AndroidManifest", e); |
| } |
| finally |
| { |
| if (mode.equals(ILaunchManager.RUN_MODE)) |
| { |
| AndroidLaunch androidLaunch = (AndroidLaunch) launch; |
| androidLaunch.stopLaunch(); |
| } |
| } |
| } |
| |
| /** |
| * @param project |
| * @param emuInstance |
| * @throws CoreException |
| */ |
| private boolean checkForCompatibleRunningInstances(ILaunchConfiguration configuration) |
| throws CoreException |
| { |
| IProject project = null; |
| compatibleInstance = null; |
| |
| final String projectName = |
| configuration.getAttribute(ILaunchConfigurationConstants.ATTR_PROJECT_NAME, |
| (String) null); |
| |
| project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); |
| if (project == null) |
| { |
| IStatus status = |
| new Status(Status.ERROR, LaunchPlugin.PLUGIN_ID, "Could not retrieve project: " |
| + projectName); |
| throw new CoreException(status); |
| } |
| |
| //Check if there is a compatible instance running to launch the app |
| Collection<IAndroidEmulatorInstance> startedInstances = |
| DeviceFrameworkManager.getInstance().getAllStartedInstances(); |
| |
| final Collection<IAndroidEmulatorInstance> compatibleStartedInstances = |
| new HashSet<IAndroidEmulatorInstance>(); |
| |
| boolean continueLaunch = true; |
| |
| for (IAndroidEmulatorInstance i : startedInstances) |
| { |
| IStatus resultStatus = LaunchUtils.isCompatible(project, i.getName()); |
| if ((resultStatus.getSeverity() == Status.OK) |
| || (resultStatus.getSeverity() == Status.WARNING)) |
| { |
| compatibleStartedInstances.add(i); |
| } |
| } |
| if (compatibleStartedInstances.size() > 0) |
| { |
| //show a dialog with compatible running instances so the user can |
| //choose one to run the app, or he can choose to run the preferred AVD |
| |
| StartedInstancesDialogProxy proxy = |
| new StartedInstancesDialogProxy(compatibleStartedInstances, configuration, |
| project); |
| PlatformUI.getWorkbench().getDisplay().syncExec(proxy); |
| |
| compatibleInstance = proxy.getSelectedInstance(); |
| continueLaunch = proxy.continueLaunch(); |
| } |
| return continueLaunch; |
| } |
| |
| private class StartedInstancesDialogProxy implements Runnable |
| { |
| private IAndroidEmulatorInstance selectedInstance = null; |
| |
| private boolean continueLaunch = true; |
| |
| private final ILaunchConfiguration configuration; |
| |
| Collection<IAndroidEmulatorInstance> compatibleStartedInstances = null; |
| |
| IProject project = null; |
| |
| /** |
| * |
| */ |
| public StartedInstancesDialogProxy( |
| Collection<IAndroidEmulatorInstance> compatibleStartedInstances, |
| ILaunchConfiguration configuration, IProject project) |
| { |
| this.compatibleStartedInstances = compatibleStartedInstances; |
| this.configuration = configuration; |
| this.project = project; |
| } |
| |
| public void run() |
| { |
| Shell aShell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); |
| Shell shell = new Shell(aShell); |
| StartedInstancesDialog dialog; |
| try |
| { |
| dialog = |
| new StartedInstancesDialog(shell, compatibleStartedInstances, |
| configuration, project); |
| dialog.setBlockOnOpen(true); |
| dialog.open(); |
| |
| selectedInstance = null; |
| if (dialog.getReturnCode() == IDialogConstants.OK_ID) |
| { |
| selectedInstance = dialog.getSelectedInstance(); |
| } |
| else if (dialog.getReturnCode() == IDialogConstants.ABORT_ID) |
| { |
| continueLaunch = false; |
| } |
| } |
| catch (CoreException e) |
| { |
| StudioLogger.error(StudioAndroidConfigurationDelegate.class, |
| "It was not possible to open Started Instance Dialog", e); |
| } |
| } |
| |
| public IAndroidEmulatorInstance getSelectedInstance() |
| { |
| return selectedInstance; |
| } |
| |
| public boolean continueLaunch() |
| { |
| return continueLaunch; |
| } |
| } |
| |
| /** |
| * Bring Console View to the front and activate the appropriate stream |
| * |
| */ |
| private void bringConsoleView() |
| { |
| IConsole activeConsole = null; |
| |
| IConsole[] consoles = ConsolePlugin.getDefault().getConsoleManager().getConsoles(); |
| for (IConsole console : consoles) |
| { |
| if (console.getName().equals(ILaunchConfigurationConstants.ANDROID_CONSOLE_ID)) |
| { |
| activeConsole = console; |
| } |
| } |
| |
| // Bring Console View to the front |
| if (activeConsole != null) |
| { |
| ConsolePlugin.getDefault().getConsoleManager().showConsoleView(activeConsole); |
| } |
| |
| } |
| |
| /** |
| * |
| * @param instance |
| * @throws CoreException |
| */ |
| private void startEmuInstance(IAndroidEmulatorInstance instance) throws CoreException |
| { |
| StudioLogger.info(StudioAndroidConfigurationDelegate.class, |
| "Needs to Start the AVD instance before launching... "); |
| |
| ServiceHandler startHandler = EmulatorPlugin.getStartServiceHandler(); |
| IStatus status = startHandler.run((IInstance) instance, null, new NullProgressMonitor()); |
| |
| StudioLogger.info(StudioAndroidConfigurationDelegate.class, |
| "Status of the launch service: " + status); |
| |
| if (status.getSeverity() == Status.ERROR) |
| { |
| throw new CoreException(status); |
| } |
| else if (status.getSeverity() == Status.CANCEL) |
| { |
| StudioLogger.info(StudioAndroidConfigurationDelegate.class, |
| "Abort launch session because the AVD start was canceled. "); |
| return; |
| } |
| |
| if (!instance.isStarted()) |
| { |
| status = |
| new Status(Status.ERROR, LaunchPlugin.PLUGIN_ID, |
| "The Android Virtual Device is not started: " + instance.getName()); |
| throw new CoreException(status); |
| } |
| |
| synchronized (this) |
| { |
| try |
| { |
| wait(); |
| } |
| catch (InterruptedException e) |
| { |
| StudioLogger.info("Could not wait: ", e.getMessage()); |
| } |
| } |
| } |
| } |