Merge "Add initial plugin for contextual auth prototypes to support BP and bouncer." into main
diff --git a/packages/SystemUI/aconfig/biometrics_framework.aconfig b/packages/SystemUI/aconfig/biometrics_framework.aconfig
index 10d7352..e3f5378 100644
--- a/packages/SystemUI/aconfig/biometrics_framework.aconfig
+++ b/packages/SystemUI/aconfig/biometrics_framework.aconfig
@@ -12,3 +12,10 @@
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "cont_auth_plugin"
+ namespace: "biometrics_framework"
+ description: "Plugin and related API hooks for contextual auth plugins"
+ bug: "373600589"
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index 91f9cce..b8d4bb4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -667,6 +667,7 @@
faceProps,
wakefulnessLifecycle,
userManager,
+ null /* authContextPlugins */,
lockPatternUtils,
interactionJankMonitor,
{ promptSelectorInteractor },
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java
index 2dcbdc8..2817f55 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -117,6 +117,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
import java.util.Random;
@RunWith(AndroidJUnit4.class)
@@ -1187,7 +1188,8 @@
TestableAuthController(Context context) {
super(context, null /* applicationCoroutineScope */,
mExecution, mCommandQueue, mActivityTaskManager, mWindowManager,
- mFingerprintManager, mFaceManager, () -> mUdfpsController, mDisplayManager,
+ mFingerprintManager, mFaceManager, Optional.empty(),
+ () -> mUdfpsController, mDisplayManager,
mWakefulnessLifecycle, mUserManager, mLockPatternUtils, () -> mUdfpsLogger,
() -> mLogContextInteractor, () -> mPromptSelectionInteractor,
() -> mCredentialViewModel, () -> mPromptViewModel, mInteractionJankMonitor,
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/AuthContextPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/AuthContextPlugin.kt
new file mode 100644
index 0000000..773c2a2
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/AuthContextPlugin.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.plugins
+
+import android.os.IBinder
+import android.view.View
+import com.android.systemui.plugins.annotations.ProvidesInterface
+
+/**
+ * Plugin for experimental "Contextual Auth" features.
+ *
+ * These plugins will get raw access to low-level events about the user's environment, such as
+ * moving in/out of trusted locations, connection status of trusted devices, auth attempts, etc.
+ * They will also receive callbacks related to system events & transitions to enable prototypes on
+ * sensitive surfaces like lock screen and BiometricPrompt.
+ *
+ * Note to rebuild the plugin jar run: m PluginDummyLib
+ */
+@ProvidesInterface(action = AuthContextPlugin.ACTION, version = AuthContextPlugin.VERSION)
+interface AuthContextPlugin : Plugin {
+
+ /**
+ * Called in the background when the plugin is enabled.
+ *
+ * This is a good time to ask your friendly [saucier] to cook up something special. The
+ * [Plugin.onCreate] can also be used for initialization.
+ */
+ fun activated(saucier: Saucier)
+
+ /**
+ * Called when a [SensitiveSurface] is first shown.
+ *
+ * This may be called repeatedly if the state of the surface changes after it is shown. For
+ * example, [SensitiveSurface.BiometricPrompt.isCredential] will change if the user falls back
+ * to a credential-based auth method.
+ */
+ fun onShowingSensitiveSurface(surface: SensitiveSurface)
+
+ /**
+ * Called when a [SensitiveSurface] sensitive surface is hidden.
+ *
+ * This method may still be called without [onShowingSensitiveSurface] in cases of rapid
+ * dismissal and plugins implementations should typically be idempotent.
+ */
+ fun onHidingSensitiveSurface(surface: SensitiveSurface)
+
+ companion object {
+ /** Plugin action. */
+ const val ACTION = "com.android.systemui.action.PLUGIN_AUTH_CONTEXT"
+ /** Plugin version. */
+ const val VERSION = 1
+ }
+
+ /** Information about a sensitive surface in the framework, which the Plugin may augment. */
+ sealed interface SensitiveSurface {
+
+ /** Information about the BiometricPrompt that is being shown to the user. */
+ data class BiometricPrompt(val view: View? = null, val isCredential: Boolean = false) :
+ SensitiveSurface
+
+ /** Information about bouncer. */
+ data class LockscreenBouncer(val view: View? = null) : SensitiveSurface
+ }
+
+ /** Ask for the special. */
+ interface Saucier {
+
+ /** What [flavor] would you like? */
+ fun getSauce(flavor: String): IBinder?
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index b491c94..f6b6655 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -64,6 +64,7 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.biometrics.AuthController.ScaleFactorProvider;
import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor;
+import com.android.systemui.biometrics.plugins.AuthContextPlugins;
import com.android.systemui.biometrics.shared.model.BiometricModalities;
import com.android.systemui.biometrics.shared.model.PromptKind;
import com.android.systemui.biometrics.ui.CredentialView;
@@ -132,6 +133,7 @@
private final int mEffectiveUserId;
private final IBinder mWindowToken = new Binder();
private final ViewCaptureAwareWindowManager mWindowManager;
+ @Nullable private final AuthContextPlugins mAuthContextPlugins;
private final Interpolator mLinearOutSlowIn;
private final LockPatternUtils mLockPatternUtils;
private final WakefulnessLifecycle mWakefulnessLifecycle;
@@ -289,6 +291,7 @@
@Nullable List<FaceSensorPropertiesInternal> faceProps,
@NonNull WakefulnessLifecycle wakefulnessLifecycle,
@NonNull UserManager userManager,
+ @Nullable AuthContextPlugins authContextPlugins,
@NonNull LockPatternUtils lockPatternUtils,
@NonNull InteractionJankMonitor jankMonitor,
@NonNull Provider<PromptSelectorInteractor> promptSelectorInteractorProvider,
@@ -306,6 +309,7 @@
WindowManager wm = getContext().getSystemService(WindowManager.class);
mWindowManager = new ViewCaptureAwareWindowManager(wm, lazyViewCapture,
enableViewCaptureTracing());
+ mAuthContextPlugins = authContextPlugins;
mWakefulnessLifecycle = wakefulnessLifecycle;
mApplicationCoroutineScope = applicationCoroutineScope;
@@ -446,7 +450,7 @@
final CredentialViewModel vm = mCredentialViewModelProvider.get();
vm.setAnimateContents(animateContents);
((CredentialView) mCredentialView).init(vm, this, mPanelController, animatePanel,
- mBiometricCallback);
+ mBiometricCallback, mAuthContextPlugins);
mLayout.addView(mCredentialView);
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index a5bd559..4faf6ff 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -21,6 +21,7 @@
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_REAR;
import static android.view.Display.INVALID_DISPLAY;
+import static com.android.systemui.Flags.contAuthPlugin;
import static com.android.systemui.util.ConvenienceExtensionsKt.toKotlinLazy;
import android.annotation.NonNull;
@@ -74,6 +75,7 @@
import com.android.systemui.CoreStartable;
import com.android.systemui.biometrics.domain.interactor.LogContextInteractor;
import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor;
+import com.android.systemui.biometrics.plugins.AuthContextPlugins;
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams;
import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel;
import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel;
@@ -108,6 +110,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import javax.inject.Inject;
@@ -139,6 +142,7 @@
private final ActivityTaskManager mActivityTaskManager;
@Nullable private final FingerprintManager mFingerprintManager;
@Nullable private final FaceManager mFaceManager;
+ @Nullable private final AuthContextPlugins mContextPlugins;
private final Provider<UdfpsController> mUdfpsControllerFactory;
private final CoroutineScope mApplicationCoroutineScope;
private Job mBiometricContextListenerJob = null;
@@ -717,6 +721,7 @@
@NonNull WindowManager windowManager,
@Nullable FingerprintManager fingerprintManager,
@Nullable FaceManager faceManager,
+ Optional<AuthContextPlugins> contextPlugins,
Provider<UdfpsController> udfpsControllerFactory,
@NonNull DisplayManager displayManager,
@NonNull WakefulnessLifecycle wakefulnessLifecycle,
@@ -744,6 +749,7 @@
mActivityTaskManager = activityTaskManager;
mFingerprintManager = fingerprintManager;
mFaceManager = faceManager;
+ mContextPlugins = contAuthPlugin() ? contextPlugins.orElse(null) : null;
mUdfpsControllerFactory = udfpsControllerFactory;
mUdfpsLogger = udfpsLogger;
mDisplayManager = displayManager;
@@ -858,6 +864,10 @@
mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
mOrientationListener.enable();
updateSensorLocations();
+
+ if (mContextPlugins != null) {
+ mContextPlugins.activate();
+ }
}
@Override
@@ -1350,7 +1360,7 @@
config.mSensorIds = sensorIds;
config.mScaleProvider = this::getScaleFactor;
return new AuthContainerView(config, mApplicationCoroutineScope, mFpProps, mFaceProps,
- wakefulnessLifecycle, userManager, lockPatternUtils,
+ wakefulnessLifecycle, userManager, mContextPlugins, lockPatternUtils,
mInteractionJankMonitor, mPromptSelectorInteractor, viewModel,
mCredentialViewModelProvider, bgExecutor, mVibratorHelper,
mLazyViewCapture, mMSDLPlayer);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
index e2a8a69..60ce177 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
@@ -36,6 +36,7 @@
import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepositoryImpl
import com.android.systemui.biometrics.data.repository.PromptRepository
import com.android.systemui.biometrics.data.repository.PromptRepositoryImpl
+import com.android.systemui.biometrics.plugins.AuthContextPlugins
import com.android.systemui.biometrics.udfps.BoundingBoxOverlapDetector
import com.android.systemui.biometrics.udfps.EllipseOverlapDetector
import com.android.systemui.biometrics.udfps.OverlapDetector
@@ -58,7 +59,7 @@
/** Dagger module for all things biometric. */
@Module
interface BiometricsModule {
- /** Starts AuthController. */
+ /** Starts AuthController. */
@Binds
@IntoMap
@ClassKey(AuthController::class)
@@ -103,8 +104,9 @@
@SysUISingleton
fun displayStateRepository(impl: DisplayStateRepositoryImpl): DisplayStateRepository
- @BindsOptionalOf
- fun deviceEntryUnlockTrackerViewBinder(): DeviceEntryUnlockTrackerViewBinder
+ @BindsOptionalOf fun authContextPlugins(): AuthContextPlugins
+
+ @BindsOptionalOf fun deviceEntryUnlockTrackerViewBinder(): DeviceEntryUnlockTrackerViewBinder
companion object {
/** Background [Executor] for HAL related operations. */
@@ -117,8 +119,7 @@
@Provides fun providesUdfpsUtils(): UdfpsUtils = UdfpsUtils()
- @Provides
- fun provideIconProvider(context: Context): IconProvider = IconProvider(context)
+ @Provides fun provideIconProvider(context: Context): IconProvider = IconProvider(context)
@Provides
@SysUISingleton
@@ -136,7 +137,7 @@
EllipseOverlapDetectorParams(
minOverlap = values[3],
targetSize = values[2],
- stepSize = values[4].toInt()
+ stepSize = values[4].toInt(),
)
)
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/plugins/AuthContextPlugins.kt b/packages/SystemUI/src/com/android/systemui/biometrics/plugins/AuthContextPlugins.kt
new file mode 100644
index 0000000..ca38e98
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/plugins/AuthContextPlugins.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.plugins
+
+import com.android.systemui.plugins.AuthContextPlugin
+import com.android.systemui.plugins.PluginManager
+
+/** Wrapper interface for registering & forwarding events to all available [AuthContextPlugin]s. */
+interface AuthContextPlugins {
+ /** Finds and actives all plugins via SysUI's [PluginManager] (should be called at startup). */
+ fun activate()
+
+ /**
+ * Interact with all registered plugins.
+ *
+ * The provided [block] will be repeated for each available plugin.
+ */
+ suspend fun use(block: (AuthContextPlugin) -> Unit)
+
+ /**
+ * Like [use] but when no existing coroutine context is available.
+ *
+ * The [block] will be run on SysUI's general background context and can, optionally, be
+ * confined to [runOnMain] (defaults to a background thread).
+ */
+ fun useInBackground(runOnMain: Boolean = false, block: (AuthContextPlugin) -> Unit)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt
index b28733f..dad140f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt
@@ -11,6 +11,7 @@
import android.widget.LinearLayout
import android.widget.TextView
import com.android.systemui.biometrics.AuthPanelController
+import com.android.systemui.biometrics.plugins.AuthContextPlugins
import com.android.systemui.biometrics.ui.binder.CredentialViewBinder
import com.android.systemui.biometrics.ui.binder.Spaghetti
import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel
@@ -33,6 +34,7 @@
panelViewController: AuthPanelController,
animatePanel: Boolean,
legacyCallback: Spaghetti.Callback,
+ plugins: AuthContextPlugins?,
) {
CredentialViewBinder.bind(
this,
@@ -40,7 +42,8 @@
viewModel,
panelViewController,
animatePanel,
- legacyCallback
+ legacyCallback,
+ plugins,
)
}
@@ -78,7 +81,7 @@
0,
statusBarInsets.top,
0,
- if (keyboardInsets.bottom == 0) navigationInsets.bottom else keyboardInsets.bottom
+ if (keyboardInsets.bottom == 0) navigationInsets.bottom else keyboardInsets.bottom,
)
return WindowInsets.CONSUMED
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPatternView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPatternView.kt
index d9d286f..e80a79b 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPatternView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPatternView.kt
@@ -8,6 +8,7 @@
import android.view.WindowInsets.Type
import android.widget.LinearLayout
import com.android.systemui.biometrics.AuthPanelController
+import com.android.systemui.biometrics.plugins.AuthContextPlugins
import com.android.systemui.biometrics.ui.binder.CredentialViewBinder
import com.android.systemui.biometrics.ui.binder.Spaghetti
import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel
@@ -23,6 +24,7 @@
panelViewController: AuthPanelController,
animatePanel: Boolean,
legacyCallback: Spaghetti.Callback,
+ plugins: AuthContextPlugins?,
) {
CredentialViewBinder.bind(
this,
@@ -30,7 +32,8 @@
viewModel,
panelViewController,
animatePanel,
- legacyCallback
+ legacyCallback,
+ plugins,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialView.kt
index e2f9895..f3e4917 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialView.kt
@@ -1,6 +1,7 @@
package com.android.systemui.biometrics.ui
import com.android.systemui.biometrics.AuthPanelController
+import com.android.systemui.biometrics.plugins.AuthContextPlugins
import com.android.systemui.biometrics.ui.binder.Spaghetti
import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel
@@ -29,5 +30,6 @@
panelViewController: AuthPanelController,
animatePanel: Boolean,
legacyCallback: Spaghetti.Callback,
+ plugins: AuthContextPlugins?,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt
index 39543e7..10b1211 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt
@@ -9,18 +9,21 @@
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.app.animation.Interpolators
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.biometrics.AuthPanelController
+import com.android.systemui.biometrics.plugins.AuthContextPlugins
import com.android.systemui.biometrics.ui.CredentialPasswordView
import com.android.systemui.biometrics.ui.CredentialPatternView
import com.android.systemui.biometrics.ui.CredentialView
import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.plugins.AuthContextPlugin
import com.android.systemui.res.R
import kotlinx.coroutines.Job
+import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.onEach
-import com.android.app.tracing.coroutines.launchTraced as launch
private const val ANIMATE_CREDENTIAL_INITIAL_DURATION_MS = 150
@@ -42,6 +45,7 @@
panelViewController: AuthPanelController,
animatePanel: Boolean,
legacyCallback: Spaghetti.Callback,
+ plugins: AuthContextPlugins?,
maxErrorDuration: Long = 3_000L,
requestFocusForInput: Boolean = true,
) {
@@ -72,6 +76,10 @@
}
repeatOnLifecycle(Lifecycle.State.STARTED) {
+ if (plugins != null) {
+ launch { plugins.notifyShowingBPCredential(view) }
+ }
+
// show prompt metadata
launch {
viewModel.header.collect { header ->
@@ -136,6 +144,12 @@
host.onCredentialAttemptsRemaining(info.remaining!!, info.message)
}
}
+
+ try {
+ awaitCancellation()
+ } catch (_: Throwable) {
+ plugins?.notifyHidingBPCredential()
+ }
}
}
@@ -172,3 +186,15 @@
text = if (gone) "" else value
}
get() = text?.toString()
+
+private suspend fun AuthContextPlugins.notifyShowingBPCredential(view: View) = use { plugin ->
+ plugin.onShowingSensitiveSurface(
+ AuthContextPlugin.SensitiveSurface.BiometricPrompt(view = view, isCredential = true)
+ )
+}
+
+private fun AuthContextPlugins.notifyHidingBPCredential() = useInBackground { plugin ->
+ plugin.onHidingSensitiveSurface(
+ AuthContextPlugin.SensitiveSurface.BiometricPrompt(isCredential = true)
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
index 12f06bb..8a4cc63 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
@@ -3,6 +3,8 @@
import android.view.ViewGroup
import com.android.keyguard.KeyguardMessageAreaController
import com.android.keyguard.dagger.KeyguardBouncerComponent
+import com.android.systemui.Flags.contAuthPlugin
+import com.android.systemui.biometrics.plugins.AuthContextPlugins
import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
@@ -17,6 +19,7 @@
import com.android.systemui.log.BouncerLogger
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import dagger.Lazy
+import java.util.Optional
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -60,6 +63,7 @@
constructor(
private val legacyBouncerDependencies: Lazy<LegacyBouncerDependencies>,
private val composeBouncerDependencies: Lazy<ComposeBouncerDependencies>,
+ private val contextPlugins: Optional<AuthContextPlugins>,
) {
fun bind(view: ViewGroup) {
if (ComposeBouncerFlags.isOnlyComposeBouncerEnabled()) {
@@ -85,6 +89,7 @@
deps.bouncerMessageInteractor,
deps.bouncerLogger,
deps.selectedUserInteractor,
+ if (contAuthPlugin()) contextPlugins.orElse(null) else null,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/KeyguardBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/KeyguardBouncerViewBinder.kt
index 71eda0c..434a9ce 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/KeyguardBouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/KeyguardBouncerViewBinder.kt
@@ -22,11 +22,13 @@
import android.window.OnBackAnimationCallback
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.keyguard.KeyguardMessageAreaController
import com.android.keyguard.KeyguardSecurityContainerController
import com.android.keyguard.KeyguardSecurityModel
import com.android.keyguard.KeyguardSecurityView
import com.android.keyguard.dagger.KeyguardBouncerComponent
+import com.android.systemui.biometrics.plugins.AuthContextPlugins
import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor
import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE
import com.android.systemui.bouncer.ui.BouncerViewDelegate
@@ -35,10 +37,10 @@
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.log.BouncerLogger
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.AuthContextPlugin
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.filter
-import com.android.app.tracing.coroutines.launchTraced as launch
/** Binds the bouncer container to its view model. */
object KeyguardBouncerViewBinder {
@@ -52,6 +54,7 @@
bouncerMessageInteractor: BouncerMessageInteractor,
bouncerLogger: BouncerLogger,
selectedUserInteractor: SelectedUserInteractor,
+ plugins: AuthContextPlugins?,
) {
// Builds the KeyguardSecurityContainerController from bouncer view group.
val securityContainerController: KeyguardSecurityContainerController =
@@ -94,7 +97,7 @@
override fun setDismissAction(
onDismissAction: ActivityStarter.OnDismissAction?,
- cancelAction: Runnable?
+ cancelAction: Runnable?,
) {
securityContainerController.setOnDismissAction(onDismissAction, cancelAction)
}
@@ -138,7 +141,7 @@
it.bindMessageView(
bouncerMessageInteractor,
messageAreaControllerFactory,
- bouncerLogger
+ bouncerLogger,
)
}
} else {
@@ -149,6 +152,13 @@
securityContainerController.reset()
securityContainerController.onPause()
}
+ plugins?.apply {
+ if (isShowing) {
+ notifyBouncerShowing(view)
+ } else {
+ notifyBouncerGone()
+ }
+ }
}
}
@@ -209,7 +219,7 @@
securityContainerController.showMessage(
it.message,
it.colorStateList,
- /* animated= */ true
+ /* animated= */ true,
)
viewModel.onMessageShown()
}
@@ -233,8 +243,19 @@
awaitCancellation()
} finally {
viewModel.setBouncerViewDelegate(null)
+ plugins?.notifyBouncerGone()
}
}
}
}
}
+
+private suspend fun AuthContextPlugins.notifyBouncerShowing(view: View) = use { plugin ->
+ plugin.onShowingSensitiveSurface(
+ AuthContextPlugin.SensitiveSurface.LockscreenBouncer(view = view)
+ )
+}
+
+private fun AuthContextPlugins.notifyBouncerGone() = useInBackground { plugin ->
+ plugin.onHidingSensitiveSurface(AuthContextPlugin.SensitiveSurface.LockscreenBouncer())
+}