/**
  * Returns the {@code PrivateKey} for the requested alias, or null if no there is no result.
  *
  * <p>This method may block while waiting for a connection to another process, and must never be
  * called from the main thread.
  *
  * @param alias The alias of the desired private key, typically returned via {@link
  *     KeyChainAliasCallback#alias}.
  * @throws KeyChainException if the alias was valid but there was some problem accessing it.
  * @throws IllegalStateException if called from the main thread.
  */
 @Nullable
 @WorkerThread
 public static PrivateKey getPrivateKey(@NonNull Context context, @NonNull String alias)
     throws KeyChainException, InterruptedException {
   if (alias == null) {
     throw new NullPointerException("alias == null");
   }
   KeyChainConnection keyChainConnection = bind(context);
   try {
     final IKeyChainService keyChainService = keyChainConnection.getService();
     final String keyId = keyChainService.requestPrivateKey(alias);
     if (keyId == null) {
       throw new KeyChainException("keystore had a problem");
     }
     return AndroidKeyStoreProvider.loadAndroidKeyStorePrivateKeyFromKeystore(
         KeyStore.getInstance(), keyId);
   } catch (RemoteException e) {
     throw new KeyChainException(e);
   } catch (RuntimeException e) {
     // only certain RuntimeExceptions can be propagated across the IKeyChainService call
     throw new KeyChainException(e);
   } catch (UnrecoverableKeyException e) {
     throw new KeyChainException(e);
   } finally {
     keyChainConnection.close();
   }
 }