Allow Biometric TestApi to use virtual hal

Bug: 326227403
Test: adb shell device_config put biometrics_framework com.android.server.biometrics.use_vhal_for_testing true
Change-Id: I4dc95def492ef606e93259d68519261c6faef84e
diff --git a/Android.bp b/Android.bp
index 4f715f8..d6b303f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -97,7 +97,7 @@
         // AIDL sources from external directories
         ":android.frameworks.location.altitude-V2-java-source",
         ":android.hardware.biometrics.common-V4-java-source",
-        ":android.hardware.biometrics.fingerprint-V3-java-source",
+        ":android.hardware.biometrics.fingerprint-V5-java-source",
         ":android.hardware.biometrics.face-V4-java-source",
         ":android.hardware.gnss-V2-java-source",
         ":android.hardware.graphics.common-V3-java-source",
diff --git a/services/core/java/com/android/server/biometrics/biometrics.aconfig b/services/core/java/com/android/server/biometrics/biometrics.aconfig
index 7a9491e..92fd9cb 100644
--- a/services/core/java/com/android/server/biometrics/biometrics.aconfig
+++ b/services/core/java/com/android/server/biometrics/biometrics.aconfig
@@ -9,8 +9,8 @@
 }
 
 flag {
-    name: "de_hidl"
-    namespace: "biometrics_framework"
-    description: "feature flag for biometrics de-hidl"
-    bug: "287332354"
-}
\ No newline at end of file
+  name: "use_vhal_for_testing"
+  namespace: "biometrics_framework"
+  description: "This flag controls whether virtual HAL is used for testing instead of TestHal "
+  bug: "294254230"
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index beb3f2f..9c8d98d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -34,6 +34,7 @@
 import android.hardware.biometrics.ITestSessionCallback;
 import android.hardware.biometrics.SensorLocationInternal;
 import android.hardware.biometrics.fingerprint.IFingerprint;
+import android.hardware.biometrics.fingerprint.IVirtualHal;
 import android.hardware.biometrics.fingerprint.PointerContext;
 import android.hardware.biometrics.fingerprint.SensorProps;
 import android.hardware.fingerprint.Fingerprint;
@@ -59,6 +60,7 @@
 import com.android.server.biometrics.AuthenticationStatsBroadcastReceiver;
 import com.android.server.biometrics.AuthenticationStatsCollector;
 import com.android.server.biometrics.BiometricHandlerProvider;
+import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.Utils;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
@@ -133,6 +135,8 @@
     @Nullable private ISidefpsController mSidefpsController;
     private final AuthSessionCoordinator mAuthSessionCoordinator;
     @Nullable private AuthenticationStatsCollector mAuthenticationStatsCollector;
+    @Nullable private IVirtualHal mVhal;
+    @Nullable private String mHalInstanceNameCurrent;
 
     private final class BiometricTaskStackListener extends TaskStackListener {
         @Override
@@ -293,10 +297,29 @@
     @VisibleForTesting
     synchronized IFingerprint getHalInstance() {
         if (mTestHalEnabled) {
-            // Enabling the test HAL for a single sensor in a multi-sensor HAL currently enables
-            // the test HAL for all sensors under that HAL. This can be updated in the future if
-            // necessary.
-            return new TestHal();
+            if (Flags.useVhalForTesting()) {
+                if (!mHalInstanceNameCurrent.contains("virtual")) {
+                    Slog.i(getTag(), "Switching fingerprint hal from " + mHalInstanceName
+                            + " to virtual hal");
+                    mHalInstanceNameCurrent = "virtual";
+                    mDaemon = null;
+                }
+            } else {
+                // Enabling the test HAL for a single sensor in a multi-sensor HAL currently enables
+                // the test HAL for all sensors under that HAL. This can be updated in the future if
+                // necessary.
+                return new TestHal();
+            }
+        } else {
+            if (mHalInstanceNameCurrent == null) {
+                mHalInstanceNameCurrent = mHalInstanceName;
+            } else if (mHalInstanceNameCurrent.contains("virtual")
+                    && mHalInstanceNameCurrent != mHalInstanceName) {
+                Slog.i(getTag(), "Switching fingerprint from virtual hal " + "to "
+                        + mHalInstanceName);
+                mHalInstanceNameCurrent = mHalInstanceName;
+                mDaemon = null;
+            }
         }
 
         if (mDaemon != null) {
@@ -308,7 +331,7 @@
         mDaemon = IFingerprint.Stub.asInterface(
                 Binder.allowBlocking(
                         ServiceManager.waitForDeclaredService(
-                                IFingerprint.DESCRIPTOR + "/" + mHalInstanceName)));
+                                IFingerprint.DESCRIPTOR + "/" + mHalInstanceNameCurrent)));
         if (mDaemon == null) {
             Slog.e(getTag(), "Unable to get daemon");
             return null;
@@ -952,4 +975,26 @@
     public void sendFingerprintReEnrollNotification() {
         mAuthenticationStatsCollector.sendFingerprintReEnrollNotification();
     }
+
+    /**
+     * Return virtual hal AIDL interface if it is used for testing
+     *
+     */
+    public IVirtualHal getVhal() throws RemoteException {
+        if (mVhal == null && useVhalForTesting()) {
+            mVhal = IVirtualHal.Stub.asInterface(mDaemon.asBinder().getExtension());
+            if (mVhal == null) {
+                Slog.e(getTag(), "Unable to get virtual hal interface");
+            }
+        }
+
+        return mVhal;
+    }
+
+    /**
+     * Return true if vhal_for_testing feature is enabled and test is active
+     */
+    public boolean useVhalForTesting() {
+        return (Flags.useVhalForTesting() && mTestHalEnabled);
+    }
 }