@SuppressWarnings("UnusedException")
    private KeysetManager readMasterkeyDecryptAndParseKeyset(byte[] serializedKeyset)
        throws GeneralSecurityException, IOException {
      // We expect that the keyset is encrypted. Try to get masterAead.
      try {
        masterAead = new AndroidKeystoreKmsClient().getAead(masterKeyUri);
      } catch (GeneralSecurityException | ProviderException keystoreException) {
        // Getting masterAead failed. Attempt to read the keyset in cleartext.
        try {
          KeysetManager manager = readKeysetInCleartext(serializedKeyset);
          Log.w(TAG, "cannot use Android Keystore, it'll be disabled", keystoreException);
          return manager;
        } catch (IOException unused) {
          // Keyset is encrypted, throw error about master key encryption
          throw keystoreException;
        }
      }
      // Got masterAead successfully.
      try {
        // Decrypt and parse the keyset using masterAead.
        return KeysetManager.withKeysetHandle(
            KeysetHandle.read(BinaryKeysetReader.withBytes(serializedKeyset), masterAead));
      } catch (IOException | GeneralSecurityException ex) {
        // Attempt to read the keyset in cleartext.
        // This edge case may happen when either
        //   - the keyset was generated on a pre M phone which was upgraded to M or newer, or
        //   - the keyset was generated with Keystore being disabled, then Keystore is enabled.
        // By ignoring the security failure here, an adversary with write access to private
        // preferences can replace an encrypted keyset (that it cannot read or write) with a
        // cleartext value that it controls. This does not introduce new security risks because to
        // overwrite the encrypted keyset in private preferences of an app, said adversaries
        // must have the same privilege as the app, thus they can call Android Keystore to read or
        // write the encrypted keyset in the first place.
        try {
          return readKeysetInCleartext(serializedKeyset);
        } catch (IOException unused) {
          // Parsing failed because the keyset is encrypted but we were not able to decrypt it.
          throw ex;
        }
      }
    }
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