public ExopackageInstaller(
      ExecutionContext context, AdbHelper adbHelper, InstallableApk apkRule) {
    this.adbHelper = adbHelper;
    this.projectFilesystem = apkRule.getProjectFilesystem();
    this.eventBus = context.getBuckEventBus();
    this.apkRule = apkRule;
    this.packageName = AdbHelper.tryToExtractPackageNameFromManifest(apkRule);
    this.dataRoot = Paths.get("/data/local/tmp/exopackage/").resolve(packageName);

    Preconditions.checkArgument(AdbHelper.PACKAGE_NAME_PATTERN.matcher(packageName).matches());

    Optional<ExopackageInfo> exopackageInfo = apkRule.getExopackageInfo();
    Preconditions.checkArgument(exopackageInfo.isPresent());
    this.exopackageInfo = exopackageInfo.get();
  }
  /** Installs the app specified in the constructor. This object should be discarded afterward. */
  public synchronized boolean install(boolean quiet) throws InterruptedException {
    InstallEvent.Started started = InstallEvent.started(apkRule.getBuildTarget());
    eventBus.post(started);

    boolean success =
        adbHelper.adbCall(
            new AdbHelper.AdbCallable() {
              @Override
              public boolean call(IDevice device) throws Exception {
                try {
                  return new SingleDeviceInstaller(device, nextAgentPort.getAndIncrement())
                      .doInstall();
                } catch (Exception e) {
                  throw new RuntimeException("Failed to install exopackage on " + device, e);
                }
              }

              @Override
              public String toString() {
                return "install exopackage";
              }
            },
            quiet);

    eventBus.post(
        InstallEvent.finished(
            started,
            success,
            Optional.<Long>absent(),
            Optional.of(AdbHelper.tryToExtractPackageNameFromManifest(apkRule))));
    return success;
  }
 private static AndroidBinary getUnderlyingApk(InstallableApk installable) {
   if (installable instanceof AndroidBinary) {
     return (AndroidBinary) installable;
   } else if (installable instanceof ApkGenrule) {
     return getUnderlyingApk(((ApkGenrule) installable).getInstallableApk());
   } else {
     throw new IllegalStateException(
         installable.getBuildTarget().getFullyQualifiedName()
             + " must be backed by either an android_binary() or an apk_genrule()");
   }
 }