简体   繁体   English

如何在 UI 线程上运行生物识别提示并合并回原始线程?

[英]how to run biometric prompt on UI thread and merge back to original thread?

I'm trying to use biometric authentication.我正在尝试使用生物识别身份验证。 However my setup is complex, basically I'm trying to keep the function sync because it is invoked from C++:但是我的设置很复杂,基本上我试图保持 function 同步,因为它是从 C++ 调用的:

User interaction -> C++ function -> Java JNI function -> Biometric Authenticate <- needs to go back用户交互 -> C++ function -> Java JNI function -> 生物识别 <- 需要 go 返回

Skipping the C++ code, it calls via JNI the following function:跳过 C++ 代码,它通过 JNI 调用以下 function:

public String getSeed() throws ExecutionException, InterruptedException {
    Context reactContext = this.getReactApplicationContext();
    Activity act = this.getCurrentActivity();

    act.runOnUiThread(new Runnable() {
      @Override
      public void run() {
        Executor executor = ContextCompat.getMainExecutor(reactContext);
        BiometricPrompt.AuthenticationCallback authenticationCallback = new WalletCoreAuthenticationCallback();
        BiometricPrompt.PromptInfo info = BiometricUtils.createBiometricPromptInfo("ROPO", "ROPO", "ROPO");
        BiometricPrompt prompt = new BiometricPrompt((FragmentActivity) act, executor, authenticationCallback);
        prompt.authenticate(info);
      }
    });

    // Here I need a Handler.merge or something similar to pause the execution while the user authenticates and then I retrieve the answer.

    try {
        return keyStore.getPlainText(getReactApplicationContext(), SEED_KEY);
    } catch (FileNotFoundException fnfe) {
        Log.w(Constants.TAG, "Could not get seed (file not found)");
        return null;
    } catch (Exception e) {
        Log.w(Constants.TAG, "Could not get seed");
        return null;
    }
  }

The idea is: if the user fails to authenticate I do not fetch the sensitive information (keyStore.getPlainText).这个想法是:如果用户未能通过身份验证,我不会获取敏感信息 (keyStore.getPlainText)。

The problem however lies in the fact that the BiometricPrompt needs to be called from the main (UI) thread.然而,问题在于需要从主 (UI) 线程调用 BiometricPrompt。 I'm an Android noob, so far that was the best I could come up with, it in effect prompts the user for authentication, but I do not know how to pause/join the main java function call, until the user has authenticated.我是 Android noob,到目前为止这是我能想到的最好的,它实际上提示用户进行身份验证,但我不知道如何暂停/加入主要的 java function 调用,直到用户通过身份验证。

Is this even possible?这可能吗?

Found one way to make it work that is simple enough, using a Mutex.找到了一种使用 Mutex 使其足够简单的方法。

Each call to the parent Java creates a mutex (I also added one field to the WalletCoreAuthenticationCallback object to hold the response).每次调用父 Java 都会创建一个互斥体(我还在WalletCoreAuthenticationCallback object 中添加了一个字段来保存响应)。 Then I release the mutex on inside the calls, and just check for the stored response.然后我释放调用内部的互斥量,并检查存储的响应。

    final Semaphore mutex = new Semaphore(0);
    // This object now internally saves the response of the authentication callback
    WalletCoreAuthenticationCallback authenticationCallback = new WalletCoreAuthenticationCallback(mutex);

    act.runOnUiThread(new Runnable() {
      @Override
      public void run() {
        Executor executor = ContextCompat.getMainExecutor(reactContext);
        BiometricPrompt.PromptInfo info = BiometricUtils.createBiometricPromptInfo("ROPO", "ROPO", "ROPO");
        BiometricPrompt prompt = new BiometricPrompt((FragmentActivity) act, executor, authenticationCallback);
        prompt.authenticate(info);
      }
    });

    try {
      mutex.acquire();
    } catch (InterruptedException e) {
      Log.e(Constants.TAG, "INterruped mutex exception");
    }

    if(!authenticationCallback.isAuthenticated) {
      return null;
    }

This however has one side-effect, basically locking the calling thread, I'm calling this from a React Native application, which basically means it freezes the app.然而,这有一个副作用,基本上锁定了调用线程,我是从 React Native 应用程序调用它的,这基本上意味着它冻结了应用程序。 However since Auth is such a vital step, it's ok to freeze the app since the user cannot continue without authentication anyways.然而,由于 Auth 是一个如此重要的步骤,因此可以冻结应用程序,因为用户无论如何都无法在没有身份验证的情况下继续。

If anybody has a more elegant solution, happy to check it out.如果有人有更优雅的解决方案,很乐意查看。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM