public synchronized AndroidKeysetManager build() throws GeneralSecurityException, IOException {
      if (keysetName == null) {
        throw new IllegalArgumentException("keysetName cannot be null");
      }
      if (keyTemplateProto != null && keyTemplate == null) {
        keyTemplate =
            KeyTemplate.createFrom(TinkProtoParametersFormat.parse(keyTemplateProto.toByteArray()));
      }
      // readKeysetFromPrefs(), readOrGenerateNewMasterKey() and generateNewKeyset() involve shared
      // pref filesystem operations. To control access to this global state in multi-threaded
      // contexts we need to ensure mutual exclusion of these functions.
      synchronized (lock) {
        byte[] serializedKeyset = readKeysetFromPrefs(context, keysetName, prefFileName);
        if (serializedKeyset == null) {
          if (masterKeyUri != null) {
            masterAead = readOrGenerateNewMasterKey();
          }
          this.keysetManager = generateKeysetAndWriteToPrefs();
        } else {
          if (masterKeyUri == null || !isAtLeastM()) {
            this.keysetManager = readKeysetInCleartext(serializedKeyset);
          } else {
            this.keysetManager = readMasterkeyDecryptAndParseKeyset(serializedKeyset);
          }
        }
        return new AndroidKeysetManager(this);
      }
    }
Builds and returns a new {@link AndroidKeysetManager} with the specified options.

@throws IOException If a keyset is found but unusable.
@throws KeystoreException If a master key is found but unusable.
@throws GeneralSecurityException If cannot read an existing keyset or generate a new one.
java_src/src/main/java/com/google/crypto/tink/integration/android/AndroidKeysetManager.java