blob: a1ef71c3ccb5f76910898e97e0ca2c0d9a7b15ae [file] [log] [blame]
/*
* Copyright (C) 2016 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.google.idea.blaze.android.run.runner;
import static org.jetbrains.android.actions.RunAndroidAvdManagerAction.getName;
import com.android.tools.idea.run.AndroidSessionInfo;
import com.android.tools.idea.run.DeviceFutures;
import com.android.tools.idea.run.editor.DeployTarget;
import com.android.tools.idea.run.editor.DeployTargetState;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import javax.annotation.Nullable;
import org.jetbrains.android.facet.AndroidFacet;
/** Selects a device. */
public interface BlazeAndroidDeviceSelector {
/** A device session */
class DeviceSession {
@Nullable public final DeployTarget deployTarget;
@Nullable public final DeviceFutures deviceFutures;
@Nullable public final AndroidSessionInfo sessionInfo;
public DeviceSession(
@Nullable DeployTarget deployTarget,
@Nullable DeviceFutures deviceFutures,
@Nullable AndroidSessionInfo sessionInfo) {
this.deployTarget = deployTarget;
this.deviceFutures = deviceFutures;
this.sessionInfo = sessionInfo;
}
}
DeviceSession getDevice(
Project project,
AndroidFacet facet,
BlazeAndroidRunConfigurationDeployTargetManager deployTargetManager,
Executor executor,
ExecutionEnvironment env,
AndroidSessionInfo info,
boolean debug,
int runConfigId)
throws ExecutionException;
/** Standard device selector */
class NormalDeviceSelector implements BlazeAndroidDeviceSelector {
private static final DialogWrapper.DoNotAskOption ourKillLaunchOption =
new KillLaunchDialogOption();
private static final Logger LOG = Logger.getInstance(NormalDeviceSelector.class);
static class KillLaunchDialogOption implements DialogWrapper.DoNotAskOption {
private boolean show;
@Override
public boolean isToBeShown() {
return !show;
}
@Override
public void setToBeShown(boolean toBeShown, int exitCode) {
show = !toBeShown;
}
@Override
public boolean canBeHidden() {
return true;
}
@Override
public boolean shouldSaveOptionsOnCancel() {
return true;
}
@Override
public String getDoNotShowMessage() {
return "Do not ask again";
}
}
@Override
public DeviceSession getDevice(
Project project,
AndroidFacet facet,
BlazeAndroidRunConfigurationDeployTargetManager deployTargetManager,
Executor executor,
ExecutionEnvironment env,
AndroidSessionInfo info,
boolean debug,
int runConfigId)
throws ExecutionException {
// If there is an existing session, then terminate those sessions
if (info != null) {
boolean continueLaunch = promptAndKillSession(executor, project, info);
if (!continueLaunch) {
return null;
}
}
DeployTarget deployTarget = deployTargetManager.getDeployTarget(executor, env, facet);
if (deployTarget == null) {
return null;
}
DeviceFutures deviceFutures = null;
DeployTargetState deployTargetState = deployTargetManager.getCurrentDeployTargetState();
if (!deployTarget.hasCustomRunProfileState(executor)) {
deviceFutures =
deployTarget.getDevices(
deployTargetState, facet, deployTargetManager.getDeviceCount(), debug, runConfigId);
}
return new DeviceSession(deployTarget, deviceFutures, info);
}
private boolean promptAndKillSession(
Executor executor, Project project, AndroidSessionInfo info) {
String previousExecutor = info.getExecutorId();
String currentExecutor = executor.getId();
if (ourKillLaunchOption.isToBeShown()) {
String msg, noText;
if (previousExecutor.equals(currentExecutor)) {
msg =
String.format(
"Restart App?\nThe app is already running. "
+ "Would you like to kill it and restart the session?");
noText = "Cancel";
} else {
msg =
String.format(
"To switch from %1$s to %2$s, the app has to restart. Continue?",
previousExecutor, currentExecutor);
noText = "Cancel " + currentExecutor;
}
String title = "Launching " + getName();
String yesText = "Restart " + getName();
if (Messages.NO
== Messages.showYesNoDialog(
project,
msg,
title,
yesText,
noText,
AllIcons.General.QuestionDialog,
ourKillLaunchOption)) {
return false;
}
}
LOG.info("Disconnecting existing session of the same launch configuration");
info.getProcessHandler().detachProcess();
return true;
}
}
}