com.google.idea.blaze.android.run.test.BlazeAndroidTestRunContext.java Source code

Java tutorial

Introduction

Here is the source code for com.google.idea.blaze.android.run.test.BlazeAndroidTestRunContext.java

Source

/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * 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.test;

import com.android.ddmlib.IDevice;
import com.android.tools.idea.run.ApkInfo;
import com.android.tools.idea.run.ApkProvider;
import com.android.tools.idea.run.ApkProvisionException;
import com.android.tools.idea.run.ApplicationIdProvider;
import com.android.tools.idea.run.ConsolePrinter;
import com.android.tools.idea.run.ConsoleProvider;
import com.android.tools.idea.run.LaunchOptions;
import com.android.tools.idea.run.editor.AndroidDebugger;
import com.android.tools.idea.run.editor.AndroidDebuggerState;
import com.android.tools.idea.run.tasks.DebugConnectorTask;
import com.android.tools.idea.run.tasks.DeployApkTask;
import com.android.tools.idea.run.tasks.LaunchTask;
import com.android.tools.idea.run.tasks.LaunchTasksProvider;
import com.android.tools.idea.run.util.ProcessHandlerLaunchStatus;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.idea.blaze.android.compatibility.Compatibility;
import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo;
import com.google.idea.blaze.android.run.deployinfo.BlazeApkProvider;
import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector;
import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider;
import com.google.idea.blaze.android.run.runner.BlazeAndroidRunConfigurationDebuggerManager;
import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext;
import com.google.idea.blaze.android.run.runner.BlazeApkBuildStep;
import com.google.idea.blaze.android.run.runner.BlazeApkBuildStepNormalBuild;
import com.google.idea.blaze.android.run.test.smrunner.BlazeAndroidTestEventsHandler;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.common.experiments.BoolExperiment;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.project.Project;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.annotations.NotNull;

/** Run context for android_test. */
class BlazeAndroidTestRunContext implements BlazeAndroidRunContext {

    static final BoolExperiment smRunnerUiEnabled = new BoolExperiment("use.smrunner.ui.android", true);

    private final Project project;
    private final AndroidFacet facet;
    private final RunConfiguration runConfiguration;
    private final ExecutionEnvironment env;
    private final BlazeAndroidTestRunConfigurationState configState;
    private final Label label;
    private final ImmutableList<String> buildFlags;
    private final List<Runnable> launchTaskCompleteListeners = Lists.newArrayList();
    private final ConsoleProvider consoleProvider;
    private final BlazeApkBuildStepNormalBuild buildStep;
    private final ApplicationIdProvider applicationIdProvider;
    private final ApkProvider apkProvider;

    public BlazeAndroidTestRunContext(Project project, AndroidFacet facet, RunConfiguration runConfiguration,
            ExecutionEnvironment env, BlazeAndroidTestRunConfigurationState configState, Label label,
            ImmutableList<String> buildFlags) {
        this.project = project;
        this.facet = facet;
        this.runConfiguration = runConfiguration;
        this.env = env;
        this.label = label;
        this.configState = configState;
        this.buildStep = new BlazeApkBuildStepNormalBuild(project, label, buildFlags);
        this.applicationIdProvider = new BlazeAndroidTestApplicationIdProvider(project, buildStep.getDeployInfo());
        this.apkProvider = new BlazeApkProvider(project, buildStep.getDeployInfo());

        BlazeAndroidTestEventsHandler testEventsHandler = null;
        if (smRunnerUiEnabled.getValue() && !isDebugging(env.getExecutor())) {
            testEventsHandler = new BlazeAndroidTestEventsHandler();
            this.buildFlags = ImmutableList.<String>builder().addAll(testEventsHandler.getBlazeFlags())
                    .addAll(buildFlags).build();
        } else {
            this.buildFlags = buildFlags;
        }
        this.consoleProvider = new AndroidTestConsoleProvider(project, runConfiguration, configState,
                testEventsHandler);
    }

    private static boolean isDebugging(Executor executor) {
        return executor instanceof DefaultDebugExecutor;
    }

    @Override
    public void augmentEnvironment(ExecutionEnvironment env) {
    }

    @Override
    public BlazeAndroidDeviceSelector getDeviceSelector() {
        return new BlazeAndroidDeviceSelector.NormalDeviceSelector();
    }

    @Override
    public void augmentLaunchOptions(LaunchOptions.Builder options) {
        options.setDeploy(!configState.isRunThroughBlaze());
    }

    @Override
    public ConsoleProvider getConsoleProvider() {
        return consoleProvider;
    }

    @Override
    public ApplicationIdProvider getApplicationIdProvider() throws ExecutionException {
        return applicationIdProvider;
    }

    @Nullable
    @Override
    public BlazeApkBuildStep getBuildStep() {
        return buildStep;
    }

    @Override
    public LaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder, boolean isDebug,
            BlazeAndroidRunConfigurationDebuggerManager debuggerManager) throws ExecutionException {
        return new BlazeAndroidLaunchTasksProvider(project, this, applicationIdProvider, launchOptionsBuilder,
                isDebug, false, debuggerManager);
    }

    @Override
    public ImmutableList<LaunchTask> getDeployTasks(IDevice device, LaunchOptions launchOptions)
            throws ExecutionException {
        if (!configState.isRunThroughBlaze()) {
            BlazeAndroidDeployInfo deployInfo = Futures.get(buildStep.getDeployInfo(), ExecutionException.class);
            if (!deployInfo.getDataToDeploy().isEmpty()) {
                throw new ExecutionException(
                        "This test target has data dependencies (defined in the 'data' attribute).\n"
                                + "These can only be installed if the configuration is run through 'blaze test'.\n"
                                + "Check the \"Run through 'blaze test'\" checkbox on your "
                                + "run configuration and try again.");
            }
        }

        Collection<ApkInfo> apks;
        try {
            apks = apkProvider.getApks(device);
        } catch (ApkProvisionException e) {
            throw new ExecutionException(e);
        }
        return ImmutableList.of(new DeployApkTask(project, launchOptions, apks));
    }

    @Nullable
    @Override
    public LaunchTask getApplicationLaunchTask(LaunchOptions launchOptions, @Nullable Integer userId,
            AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState,
            ProcessHandlerLaunchStatus processHandlerLaunchStatus) throws ExecutionException {
        if (configState.isRunThroughBlaze()) {
            return new BlazeAndroidTestLaunchTask(project, label, buildFlags,
                    new BlazeAndroidTestFilter(configState.getTestingType(), configState.getClassName(),
                            configState.getMethodName(), configState.getPackageName()),
                    this, launchOptions.isDebug());
        }
        BlazeAndroidDeployInfo deployInfo = Futures.get(buildStep.getDeployInfo(), ExecutionException.class);
        return StockAndroidTestLaunchTask.getStockTestLaunchTask(configState, applicationIdProvider,
                launchOptions.isDebug(), deployInfo, processHandlerLaunchStatus);
    }

    @Override
    @SuppressWarnings("unchecked")
    public DebugConnectorTask getDebuggerTask(AndroidDebugger androidDebugger,
            AndroidDebuggerState androidDebuggerState, @NotNull Set<String> packageIds,
            boolean monitorRemoteProcess) throws ExecutionException {
        if (configState.isRunThroughBlaze()) {
            return new ConnectBlazeTestDebuggerTask(env.getProject(), androidDebugger, packageIds,
                    applicationIdProvider, this);
        }
        return Compatibility.getConnectDebuggerTask(androidDebugger, env, null, packageIds, facet,
                androidDebuggerState, runConfiguration.getType().getId(), monitorRemoteProcess);
    }

    void onLaunchTaskComplete() {
        for (Runnable runnable : launchTaskCompleteListeners) {
            runnable.run();
        }
    }

    void addLaunchTaskCompleteListener(Runnable runnable) {
        launchTaskCompleteListeners.add(runnable);
    }

    @Nullable
    @Override
    public Integer getUserId(IDevice device, ConsolePrinter consolePrinter) {
        return null;
    }
}