use of com.android.sdklib.AndroidVersion in project android by JetBrains.
the class AndroidRunConfigurationBase method getState.
@Override
public RunProfileState getState(@NotNull final Executor executor, @NotNull ExecutionEnvironment env) throws ExecutionException {
validateBeforeRun(executor);
final Module module = getConfigurationModule().getModule();
assert module != null : "Enforced by fatal validation check in checkConfiguration.";
final AndroidFacet facet = AndroidFacet.getInstance(module);
assert facet != null : "Enforced by fatal validation check in checkConfiguration.";
Project project = env.getProject();
boolean forceColdswap = !InstantRunUtils.isInvokedViaHotswapAction(env);
boolean couldHaveHotswapped = false;
boolean debug = false;
if (executor instanceof DefaultDebugExecutor) {
if (!AndroidSdkUtils.activateDdmsIfNecessary(facet.getModule().getProject())) {
throw new ExecutionException("Unable to obtain debug bridge. Please check if there is a different tool using adb that is active.");
}
debug = true;
}
DeviceFutures deviceFutures = null;
AndroidSessionInfo info = AndroidSessionInfo.findOldSession(project, null, getUniqueID());
if (info != null && supportsInstantRun()) {
// if there is an existing previous session, then see if we can detect devices to fast deploy to
deviceFutures = getFastDeployDevices(executor, facet, info);
// that the ReRun is now a global action and doesn't really know much details about each run (and doing that seems like a hack too.)
if (InstantRunUtils.isReRun(env)) {
killSession(info);
info = null;
}
}
if (info != null && deviceFutures == null) {
// If we should not be fast deploying, but there is an existing session, then terminate those sessions. Otherwise, we might end up
// with 2 active sessions of the same launch, especially if we first think we can do a fast deploy, then end up doing a full launch
boolean continueLaunch = promptAndKillSession(executor, project, info);
if (!continueLaunch) {
return null;
}
} else if (info != null && forceColdswap) {
// the user could have invoked the hotswap action in this scenario, but they chose to force a coldswap (by pressing run)
couldHaveHotswapped = true;
// forcibly kill app in case of run action (which forces a cold swap)
// normally, installing the apk will force kill the app, but we need to forcibly kill it in the case that there were no changes
killSession(info);
}
// If we are not fast deploying, then figure out (prompting user if needed) where to deploy
if (deviceFutures == null) {
DeployTarget deployTarget = getDeployTarget(executor, env, debug, facet);
if (deployTarget == null) {
return null;
}
DeployTargetState deployTargetState = getDeployTargetContext().getCurrentDeployTargetState();
if (deployTarget.hasCustomRunProfileState(executor)) {
return deployTarget.getRunProfileState(executor, env, deployTargetState);
}
deviceFutures = deployTarget.getDevices(deployTargetState, facet, getDeviceCount(debug), debug, getUniqueID());
if (deviceFutures == null) {
// The user deliberately canceled, or some error was encountered and exposed by the chooser. Quietly exit.
return null;
}
}
if (deviceFutures.get().isEmpty()) {
throw new ExecutionException(AndroidBundle.message("deployment.target.not.found"));
}
ApplicationIdProvider applicationIdProvider = getApplicationIdProvider(facet);
InstantRunContext instantRunContext = null;
if (supportsInstantRun() && InstantRunSettings.isInstantRunEnabled()) {
InstantRunGradleSupport gradleSupport = canInstantRun(module, deviceFutures.getDevices());
if (gradleSupport == TARGET_PLATFORM_NOT_INSTALLED) {
AndroidVersion version = deviceFutures.getDevices().get(0).getVersion();
String message = AndroidBundle.message("instant.run.quickfix.missing.platform", SdkVersionInfo.getVersionWithCodename(version));
int result = Messages.showYesNoDialog(project, message, "Instant Run", // yes button
"Install and Continue", // no button
"Proceed without Instant Run", Messages.getQuestionIcon());
if (result == Messages.OK) {
// if ok, install platform and continue with instant run
ModelWizardDialog dialog = SdkQuickfixUtils.createDialogForPaths(project, ImmutableList.of(DetailsTypes.getPlatformPath(version)));
if (dialog == null) {
LOG.warn("Unable to get quick fix wizard to install missing platform required for instant run.");
} else if (dialog.showAndGet()) {
gradleSupport = SUPPORTED;
}
}
}
if (gradleSupport == SUPPORTED) {
if (!AndroidEnableAdbServiceAction.isAdbServiceEnabled()) {
throw new ExecutionException("Instant Run requires 'Tools | Android | Enable ADB integration' to be enabled.");
}
InstantRunUtils.setInstantRunEnabled(env, true);
instantRunContext = InstantRunGradleUtils.createGradleProjectContext(facet);
} else {
InstantRunManager.LOG.warn("Instant Run enabled, but not doing an instant run build since: " + gradleSupport);
String notificationText = gradleSupport.getUserNotification();
if (notificationText != null) {
InstantRunNotificationTask.showNotification(env.getProject(), null, notificationText);
}
}
} else {
String msg = "Not using instant run for this launch: ";
if (InstantRunSettings.isInstantRunEnabled()) {
msg += getType().getDisplayName() + " does not support instant run";
} else {
msg += "instant run is disabled";
}
InstantRunManager.LOG.info(msg);
}
// Store the chosen target on the execution environment so before-run tasks can access it.
AndroidRunConfigContext runConfigContext = new AndroidRunConfigContext();
env.putCopyableUserData(AndroidRunConfigContext.KEY, runConfigContext);
runConfigContext.setTargetDevices(deviceFutures);
runConfigContext.setSameExecutorAsPreviousSession(info != null && executor.getId().equals(info.getExecutorId()));
runConfigContext.setCleanRerun(InstantRunUtils.isCleanReRun(env));
runConfigContext.setForceColdSwap(forceColdswap, couldHaveHotswapped);
// Save the instant run context so that before-run task can access it
env.putCopyableUserData(InstantRunContext.KEY, instantRunContext);
if (debug) {
String error = canDebug(deviceFutures, facet, module.getName());
if (error != null) {
throw new ExecutionException(error);
}
}
LaunchOptions launchOptions = getLaunchOptions().setDebug(debug).build();
ProcessHandler processHandler = null;
if (info != null && info.getExecutorId().equals(executor.getId())) {
processHandler = info.getProcessHandler();
}
ApkProvider apkProvider = getApkProvider(facet, applicationIdProvider);
LaunchTasksProviderFactory providerFactory = new AndroidLaunchTasksProviderFactory(this, env, facet, applicationIdProvider, apkProvider, deviceFutures, launchOptions, processHandler, instantRunContext);
InstantRunStatsService.get(project).notifyBuildStarted();
return new AndroidRunState(env, getName(), module, applicationIdProvider, getConsoleProvider(), deviceFutures, providerFactory, processHandler);
}
use of com.android.sdklib.AndroidVersion in project android by JetBrains.
the class AndroidRunConfigurationBase method getFastDeployDevices.
@Nullable
private static DeviceFutures getFastDeployDevices(@NotNull Executor executor, @NotNull AndroidFacet facet, @NotNull AndroidSessionInfo info) {
if (!InstantRunSettings.isInstantRunEnabled()) {
InstantRunManager.LOG.info("Instant run not enabled in settings");
return null;
}
if (!info.getExecutorId().equals(executor.getId())) {
String msg = String.format("Cannot Instant Run since old executor (%1$s) doesn't match current executor (%2$s)", info.getExecutorId(), executor.getId());
InstantRunManager.LOG.info(msg);
return null;
}
List<IDevice> devices = info.getDevices();
if (devices == null || devices.isEmpty()) {
InstantRunManager.LOG.info("Cannot Instant Run since we could not locate the devices from the existing launch session");
return null;
}
if (devices.size() > 1) {
InstantRunManager.LOG.info("Last run was on > 1 device, not reusing devices and prompting again");
return null;
}
AndroidModuleModel model = AndroidModuleModel.get(facet);
AndroidVersion version = devices.get(0).getVersion();
InstantRunGradleSupport status = InstantRunGradleUtils.getIrSupportStatus(model, version);
if (status != SUPPORTED) {
InstantRunManager.LOG.info("Cannot Instant Run: " + status);
return null;
}
return DeviceFutures.forDevices(devices);
}
use of com.android.sdklib.AndroidVersion in project android by JetBrains.
the class AndroidFacet method addCompatibleAvds.
@NotNull
private AvdInfo[] addCompatibleAvds(@NotNull List<AvdInfo> to, @NotNull AvdInfo[] from) {
AndroidVersion minSdk = AndroidModuleInfo.get(this).getRuntimeMinSdkVersion();
AndroidPlatform platform = getConfiguration().getAndroidPlatform();
if (platform == null) {
LOG.error("Android Platform not set for module: " + getModule().getName());
return new AvdInfo[0];
}
for (AvdInfo avd : from) {
ISystemImage systemImage = avd.getSystemImage();
if (systemImage == null || LaunchCompatibility.canRunOnAvd(minSdk, platform.getTarget(), systemImage).isCompatible() != ThreeState.NO) {
to.add(avd);
}
}
return to.toArray(new AvdInfo[to.size()]);
}
use of com.android.sdklib.AndroidVersion in project android by JetBrains.
the class EclipseProject method initVersion.
private void initVersion(@NonNull Properties properties) {
//$NON-NLS-1$
String target = properties.getProperty("target");
if (target != null) {
myVersion = AndroidTargetHash.getPlatformVersion(target);
// getPlatformVersion does not handle API numbers correctly
if (myVersion != null && myVersion.isPreview()) {
// Update codename
AndroidVersion version = SdkVersionInfo.getVersion(myVersion.getCodename(), null);
if (version != null) {
myVersion = version;
}
} else {
int index = target.lastIndexOf(':');
if (index != -1) {
myVersion = SdkVersionInfo.getVersion(target.substring(index + 1), null);
myAddOn = target;
}
}
}
}
use of com.android.sdklib.AndroidVersion in project android by JetBrains.
the class RenderService method warnIfObsoleteLayoutLib.
private static void warnIfObsoleteLayoutLib(@NotNull final Module module, @NotNull RenderLogger logger, @Nullable final EditorDesignSurface surface, @NotNull IAndroidTarget target) {
if (!ourWarnAboutObsoleteLayoutLibVersions) {
return;
}
if (!LayoutLibraryLoader.USE_SDK_LAYOUTLIB) {
// We are using the version shipped with studio, it can never be obsolete. StudioEmbeddedRenderTarget does not implement getVersion.
ourWarnAboutObsoleteLayoutLibVersions = false;
return;
}
if (target instanceof CompatibilityRenderTarget) {
target = ((CompatibilityRenderTarget) target).getRenderTarget();
}
final AndroidVersion version = target.getVersion();
final int revision;
// are minimum revisions; if a later version is available, it will be installed.
switch(version.getFeatureLevel()) {
case 23:
revision = 2;
break;
case 22:
revision = 2;
break;
case 21:
revision = 2;
break;
case 20:
revision = 2;
break;
case 19:
revision = 4;
break;
case 18:
revision = 3;
break;
case 17:
revision = 3;
break;
case 16:
revision = 5;
break;
case 15:
revision = 5;
break;
case 14:
revision = 4;
break;
case 13:
revision = 1;
break;
case 12:
revision = 3;
break;
case 11:
revision = 2;
break;
case 10:
revision = 2;
break;
case 8:
revision = 3;
break;
default:
revision = -1;
break;
}
if (revision >= 0 && target.getRevision() < revision) {
RenderProblem.Html problem = RenderProblem.create(WARNING);
problem.tag("obsoleteLayoutlib");
HtmlBuilder builder = problem.getHtmlBuilder();
builder.add("Using an obsolete version of the " + target.getVersionName() + " layout library which contains many known bugs: ");
builder.addLink("Install Update", logger.getLinkManager().createRunnableLink(() -> {
// Don't warn again
//noinspection AssignmentToStaticFieldFromInstanceMethod
ourWarnAboutObsoleteLayoutLibVersions = false;
List<String> requested = Lists.newArrayList();
// The revision to install. Note that this will install a higher version than this if available;
// e.g. even if we ask for version 4, if revision 7 is available it will be installed, not revision 4.
requested.add(DetailsTypes.getPlatformPath(version));
ModelWizardDialog dialog = SdkQuickfixUtils.createDialogForPaths(module.getProject(), requested);
if (dialog != null && dialog.showAndGet()) {
if (surface != null) {
// Force the target to be recomputed; this will pick up the new revision object from the local sdk.
Configuration configuration = surface.getConfiguration();
if (configuration != null) {
configuration.getConfigurationManager().setTarget(null);
}
surface.requestRender();
// However, due to issue https://code.google.com/p/android/issues/detail?id=76096 it may not yet
// take effect.
Messages.showInfoMessage(module.getProject(), "Note: Due to a bug you may need to restart the IDE for the new layout library to fully take effect", "Restart Recommended");
}
}
}));
builder.addLink(", ", "Ignore For Now", null, logger.getLinkManager().createRunnableLink(() -> {
//noinspection AssignmentToStaticFieldFromInstanceMethod
ourWarnAboutObsoleteLayoutLibVersions = false;
if (surface != null) {
surface.requestRender();
}
}));
logger.addMessage(problem);
}
}
Aggregations