@Nullable
    private Aead readOrGenerateNewMasterKey() throws GeneralSecurityException {
      if (!isAtLeastM()) {
        Log.w(TAG, "Android Keystore requires at least Android M");
        return null;
      }

      AndroidKeystoreKmsClient client = new AndroidKeystoreKmsClient();

      boolean generated;
      try {
        // Note that this function does not use the keyStore instance set with withKeyStore.
        generated = AndroidKeystoreKmsClient.generateKeyIfNotExist(masterKeyUri);
      } catch (GeneralSecurityException | ProviderException ex) {
        Log.w(TAG, "cannot use Android Keystore, it'll be disabled", ex);
        return null;
      }

      try {
        return client.getAead(masterKeyUri);
      } catch (GeneralSecurityException | ProviderException ex) {
        // Throw the exception if the key exists but is unusable. We can't recover by generating a
        // new key because there might be existing encrypted data under the unusable key.
        // Users can provide a master key that is stored in StrongBox (see
        // https://developer.android.com/about/versions/pie/android-9.0#hardware-security-module),
        // which may throw a ProviderException if there's any problem with it.
        if (!generated) {
          throw new KeyStoreException(
              String.format("the master key %s exists but is unusable", masterKeyUri), ex);
        }
        // Otherwise swallow the exception if the key doesn't exist yet. We can recover by disabling
        // Keystore.
        Log.w(TAG, "cannot use Android Keystore, it'll be disabled", ex);
      }

      return null;
    }
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