Dismiss the BiometricPrompt upon Intent.ACTION_CLOSE_SYSTEM_DIALOGS

Test: BiometricPromptDemo, play with gesture nav and traditional nav
Test: atest com.android.systemui.biometrics

Change-Id: I64525b73bc9707a6760eea8e16a9e98f28b3a52f
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 516de70..6b0d3c8 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -23,7 +23,10 @@
 import android.app.ActivityTaskManager;
 import android.app.IActivityTaskManager;
 import android.app.TaskStackListener;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.hardware.biometrics.Authenticator;
@@ -85,6 +88,28 @@
         }
     }
 
+    @VisibleForTesting
+    final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (mCurrentDialog != null
+                    && Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
+                Log.w(TAG, "ACTION_CLOSE_SYSTEM_DIALOGS received");
+                mCurrentDialog.dismissWithoutCallback(true /* animate */);
+                mCurrentDialog = null;
+
+                try {
+                    if (mReceiver != null) {
+                        mReceiver.onDialogDismissed(BiometricPrompt.DISMISSED_REASON_USER_CANCEL);
+                        mReceiver = null;
+                    }
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Remote exception", e);
+                }
+            }
+        }
+    };
+
     private final Runnable mTaskStackChangedRunnable = () -> {
         if (mCurrentDialog != null) {
             try {
@@ -204,6 +229,11 @@
         super(context);
         mCommandQueue = commandQueue;
         mInjector = injector;
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+
+        context.registerReceiver(mBroadcastReceiver, filter);
     }
 
     @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index c215a43..486fa12 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -35,6 +35,7 @@
 import android.app.IActivityTaskManager;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.hardware.biometrics.Authenticator;
@@ -403,6 +404,19 @@
         mAuthController.onDeviceCredentialPressed();
     }
 
+    @Test
+    public void testActionCloseSystemDialogs_dismissesDialogIfShowing() throws Exception {
+        showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+        mAuthController.mBroadcastReceiver.onReceive(mContext, intent);
+        waitForIdleSync();
+
+        assertNull(mAuthController.mCurrentDialog);
+        assertNull(mAuthController.mReceiver);
+        verify(mDialog1).dismissWithoutCallback(true /* animate */);
+        verify(mReceiver).onDialogDismissed(eq(BiometricPrompt.DISMISSED_REASON_USER_CANCEL));
+    }
+
     // Helpers
 
     private void showDialog(int authenticators, int biometricModality) {