public void build()

in aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/MobileInstallBuildStep.java [130:259]


  public void build(BlazeContext context, BlazeAndroidDeviceSelector.DeviceSession deviceSession) {
    BlazeProjectData projectData =
        BlazeProjectDataManager.getInstance(project).getBlazeProjectData();

    if (projectData == null) {
      IssueOutput.error("Missing project data. Please sync and try again.").submit(context);
      return;
    }

    DeviceFutures deviceFutures = deviceSession.deviceFutures;
    if (deviceFutures == null) {
      IssueOutput.error("Error fetching devices!").submit(context);
      return;
    }

    context.output(new StatusOutput("Waiting for target device..."));
    IDevice device = resolveDevice(context, deviceFutures);
    if (device == null) {
      return;
    }

    BlazeCommand.Builder command =
        BlazeCommand.builder(
            Blaze.getBuildSystemProvider(project).getBinaryPath(project),
            BlazeCommandName.MOBILE_INSTALL);

    if (passAdbArgWithSerialToMi.getValue()) {
      // Redundant, but we need this to get around bug in bazel.
      // https://github.com/bazelbuild/bazel/issues/4922
      command.addBlazeFlags(
          BlazeFlags.ADB_ARG + "-s ", BlazeFlags.ADB_ARG + device.getSerialNumber());
    }

    if (!StudioDeployerExperiment.isEnabled()) {
      MobileInstallAdbLocationProvider.getAdbLocationForMobileInstall(project)
          .ifPresent((location) -> command.addBlazeFlags(BlazeFlags.ADB, location));
    }

    WorkspaceRoot workspaceRoot = WorkspaceRoot.fromProject(project);
    final String deployInfoSuffix = getDeployInfoSuffix(Blaze.getBuildSystem(project));

    try (BuildResultHelper buildResultHelper =
            BuildResultHelperProvider.createForLocalBuild(project);
        AdbTunnelConfigurator tunnelConfig = getTunnelConfigurator(context)) {
      tunnelConfig.setupConnection(context);

      if (!StudioDeployerExperiment.isEnabled()) {
        String deviceFlag = device.getSerialNumber();
        if (tunnelConfig.isActive()) {
          deviceFlag += ":tcp:" + tunnelConfig.getAdbServerPort();
        } else {
          InetSocketAddress adbAddr = AndroidDebugBridge.getSocketAddress();
          if (adbAddr == null) {
            IssueOutput.warn(
                    "Can't get ADB server port, please ensure ADB server is running. Will fallback"
                        + " to the default adb server.")
                .submit(context);
          } else {
            deviceFlag += ":tcp:" + adbAddr.getPort();
          }
        }
        command.addBlazeFlags(BlazeFlags.DEVICE, deviceFlag);
      }

      command
          .addTargets(label)
          .addBlazeFlags(blazeFlags)
          .addBlazeFlags(buildResultHelper.getBuildFlags())
          .addExeFlags(exeFlags)
          // MI launches apps by default. Defer app launch to BlazeAndroidLaunchTasksProvider.
          .addExeFlags("--nolaunch_app");

      if (StudioDeployerExperiment.isEnabled()) {
        command.addExeFlags("--nodeploy");
      }

      SaveUtil.saveAllFiles();
      context.output(new StatusOutput("Invoking mobile-install..."));
      ExternalTask task =
          ExternalTask.builder(workspaceRoot)
              .addBlazeCommand(command.build())
              .context(context)
              .stdout(LineProcessingOutputStream.of(new PrintOutputLineProcessor(context)))
              .stderr(
                  LineProcessingOutputStream.of(
                      BlazeConsoleLineProcessorProvider.getAllStderrLineProcessors(context)))
              .build();

      Stopwatch s = Stopwatch.createStarted();
      int exitCode = task.run();
      logBuildTime(launchId, StudioDeployerExperiment.isEnabled(), s.elapsed(), exitCode);

      if (exitCode != 0) {
        IssueOutput.error("Blaze build failed. See Blaze Console for details.").submit(context);
        return;
      }

      ListenableFuture<Void> unusedFuture =
          FileCaches.refresh(
              project, context, BlazeBuildOutputs.noOutputs(BuildResult.fromExitCode(exitCode)));

      context.output(new StatusOutput("Reading deployment information..."));
      String executionRoot =
          ExecRootUtil.getExecutionRoot(buildResultHelper, project, blazeFlags, context);
      if (executionRoot == null) {
        IssueOutput.error("Could not locate execroot!").submit(context);
        return;
      }

      AndroidDeployInfo deployInfoProto =
          deployInfoHelper.readDeployInfoProtoForTarget(
              label, buildResultHelper, fileName -> fileName.endsWith(deployInfoSuffix));
      deployInfo =
          deployInfoHelper.extractDeployInfoAndInvalidateManifests(
              project, new File(executionRoot), deployInfoProto);

      String msg;
      if (StudioDeployerExperiment.isEnabled()) {
        msg = "mobile-install build completed, deploying split apks...";
      } else {
        msg = "Done.";
      }
      context.output(new StatusOutput(msg));
    } catch (GetArtifactsException e) {
      IssueOutput.error("Could not read BEP output: " + e.getMessage()).submit(context);
    } catch (GetDeployInfoException e) {
      IssueOutput.error("Could not read apk deploy info from build: " + e.getMessage())
          .submit(context);
    }
  }