/**
   * Tries to open socket to Zygote process if not already open. If already open, does nothing. May
   * block and retry.
   */
  private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
    if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
      primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET, getNumTries(primaryZygoteState));
    }

    if (primaryZygoteState.matches(abi)) {
      return primaryZygoteState;
    }

    // TODO: Get rid of this. This is a temporary workaround until all the
    // compilation related pieces for the dual zygote stack are ready.
    // b/3647418.
    if (System.getenv("ANDROID_SOCKET_" + SECONDARY_ZYGOTE_SOCKET) == null) {
      Log.e(LOG_TAG, "Forcing app to primary zygote, secondary unavailable (ABI= " + abi + ")");
      // Should be :
      // throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
      return primaryZygoteState;
    }

    // The primary zygote didn't match. Try the secondary.
    if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
      secondaryZygoteState =
          ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET, getNumTries(secondaryZygoteState));
    }

    if (secondaryZygoteState.matches(abi)) {
      return secondaryZygoteState;
    }

    throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
  }
  /**
   * Sends an argument list to the zygote process, which starts a new child and returns the child's
   * pid. Please note: the present implementation replaces newlines in the argument list with
   * spaces.
   *
   * @throws ZygoteStartFailedEx if process start failed for any reason
   */
  private static ProcessStartResult zygoteSendArgsAndGetResult(
      ZygoteState zygoteState, ArrayList<String> args) throws ZygoteStartFailedEx {
    try {
      /**
       * See com.android.internal.os.ZygoteInit.readArgumentList() Presently the wire format to the
       * zygote process is: a) a count of arguments (argc, in essence) b) a number of
       * newline-separated argument strings equal to count
       *
       * <p>After the zygote process reads these it will write the pid of the child or -1 on
       * failure, followed by boolean to indicate whether a wrapper process was used.
       */
      final BufferedWriter writer = zygoteState.writer;
      final DataInputStream inputStream = zygoteState.inputStream;

      writer.write(Integer.toString(args.size()));
      writer.newLine();

      int sz = args.size();
      for (int i = 0; i < sz; i++) {
        String arg = args.get(i);
        if (arg.indexOf('\n') >= 0) {
          throw new ZygoteStartFailedEx("embedded newlines not allowed");
        }
        writer.write(arg);
        writer.newLine();
      }

      writer.flush();

      // Should there be a timeout on this?
      ProcessStartResult result = new ProcessStartResult();
      result.pid = inputStream.readInt();
      if (result.pid < 0) {
        throw new ZygoteStartFailedEx("fork() failed");
      }
      result.usingWrapper = inputStream.readBoolean();
      return result;
    } catch (IOException ex) {
      zygoteState.close();
      throw new ZygoteStartFailedEx(ex);
    }
  }
  /**
   * Tries to open socket to Zygote process if not already open. If already open, does nothing. May
   * block and retry.
   */
  private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
    if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
      primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET, getNumTries(primaryZygoteState));
    }

    if (primaryZygoteState.matches(abi)) {
      return primaryZygoteState;
    }

    // The primary zygote didn't match. Try the secondary.
    if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
      secondaryZygoteState =
          ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET, getNumTries(secondaryZygoteState));
    }

    if (secondaryZygoteState.matches(abi)) {
      return secondaryZygoteState;
    }

    throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
  }