Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8f09c19 authored by Grace Cheng's avatar Grace Cheng
Browse files

Add new view controller for secure lock device biometric view

Adds new viewcontroller for secure lock device biometric view (for
legacy keyguard / pre-flexiglass implementation)

Flag: android.security.secure_lock_device
Bug: 401645997
Bug: 427071518
Test: manual
Change-Id: Iaaf9a7bc85d5041ec43ccfc35740eb740329a3cb
parent 6d1104f0
Loading
Loading
Loading
Loading
+29 −3
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.keyguard;

import static android.security.Flags.secureLockDevice;

import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -42,6 +44,9 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.log.BouncerLogger;
import com.android.systemui.res.R;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.securelockdevice.domain.interactor.SecureLockDeviceInteractor;
import com.android.systemui.securelockdevice.ui.viewmodel.SecureLockDeviceBiometricAuthContentViewModel;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
import com.android.systemui.util.ViewController;
@@ -58,6 +63,7 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
    private final KeyguardSecurityCallback mKeyguardSecurityCallback;
    private final EmergencyButtonController mEmergencyButtonController;
    private boolean mPaused;
    @Nullable
    protected KeyguardMessageAreaController<BouncerKeyguardMessageArea> mMessageAreaController;

    // The following is used to ignore callbacks from SecurityViews that are no longer current
@@ -82,7 +88,9 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
        mFeatureFlags = featureFlags;
        mSelectedUserInteractor = selectedUserInteractor;
        mBouncerHapticPlayer = bouncerHapticPlayer;
        if (messageAreaControllerFactory != null) {
        if (messageAreaControllerFactory != null
                && !(this instanceof KeyguardSecureLockDeviceBiometricAuthViewController)
        ) {
            try {
                BouncerKeyguardMessageArea kma = view.requireViewById(R.id.bouncer_message_area);
                mMessageAreaController = messageAreaControllerFactory.create(kma);
@@ -103,6 +111,7 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
    @Override
    @CallSuper
    protected void onViewAttached() {
        if (mMessageAreaController == null) return;
        updateMessageAreaVisibility();
        if (TextUtils.isEmpty(mMessageAreaController.getMessage())
                && getInitialMessageResId() != 0) {
@@ -143,6 +152,7 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>

    @Override
    public void reset() {
        if (mMessageAreaController == null) return;
        mMessageAreaController.setMessage("", false);
    }

@@ -203,6 +213,8 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>

    /** Factory for a {@link KeyguardInputViewController}. */
    public static class Factory {
        private final SecureLockDeviceBiometricAuthContentViewModel.Factory
                mSecureLockDeviceViewModelFactory;
        private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
        private final LockPatternUtils mLockPatternUtils;
        private final LatencyTracker mLatencyTracker;
@@ -219,6 +231,7 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
        private final SelectedUserInteractor mSelectedUserInteractor;
        private final UiEventLogger mUiEventLogger;
        private final KeyguardKeyboardInteractor mKeyguardKeyboardInteractor;
        private final SecureLockDeviceInteractor mSecureLockDeviceInteractor;
        private final BouncerHapticPlayer mBouncerHapticPlayer;
        private final UserActivityNotifier mUserActivityNotifier;
        private final InputManager mInputManager;
@@ -241,7 +254,11 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
                BouncerHapticPlayer bouncerHapticPlayer,
                UserActivityNotifier userActivityNotifier,
                InputManager inputManager,
                LockPatternCheckerWrapper lockPatternCheckerWrapper) {
                LockPatternCheckerWrapper lockPatternCheckerWrapper,
                SecureLockDeviceInteractor secureLockDeviceInteractor,
                SecureLockDeviceBiometricAuthContentViewModel.Factory
                        secureLockDeviceViewModelFactory
        ) {
            mKeyguardUpdateMonitor = keyguardUpdateMonitor;
            mLockPatternUtils = lockPatternUtils;
            mLatencyTracker = latencyTracker;
@@ -262,6 +279,8 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
            mUserActivityNotifier = userActivityNotifier;
            mInputManager = inputManager;
            mLockPatternCheckerWrapper = lockPatternCheckerWrapper;
            mSecureLockDeviceInteractor = secureLockDeviceInteractor;
            mSecureLockDeviceViewModelFactory = secureLockDeviceViewModelFactory;
        }

        /** Create a new {@link KeyguardInputViewController}. */
@@ -270,7 +289,14 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
            EmergencyButtonController emergencyButtonController =
                    mEmergencyButtonControllerFactory.create(
                            keyguardInputView.findViewById(R.id.emergency_call_button));

            if (secureLockDevice() && !SceneContainerFlag.isEnabled()
                    && keyguardInputView instanceof KeyguardSecureLockDeviceBiometricAuthView) {
                return new KeyguardSecureLockDeviceBiometricAuthViewController(
                        (KeyguardSecureLockDeviceBiometricAuthView) keyguardInputView,
                        mSecureLockDeviceViewModelFactory, mSelectedUserInteractor,
                        securityMode, keyguardSecurityCallback, emergencyButtonController,
                        mMessageAreaControllerFactory, mFeatureFlags, mBouncerHapticPlayer);
            }
            if (keyguardInputView instanceof KeyguardPatternView) {
                return new KeyguardPatternViewController((KeyguardPatternView) keyguardInputView,
                        mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
+108 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.keyguard

import android.content.res.ColorStateList
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.lifecycle.lifecycleScope
import com.android.systemui.bouncer.ui.helper.BouncerHapticPlayer
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.securelockdevice.ui.SecureLockDeviceContent
import com.android.systemui.securelockdevice.ui.viewmodel.SecureLockDeviceBiometricAuthContentViewModel
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import kotlinx.coroutines.launch

/**
 * Controller for the biometric auth view in the legacy keyguard implementation of secure lock
 * device.
 */
class KeyguardSecureLockDeviceBiometricAuthViewController(
    private val view: KeyguardSecureLockDeviceBiometricAuthView,
    secureLockDeviceViewModelFactory: SecureLockDeviceBiometricAuthContentViewModel.Factory,
    selectedUserInteractor: SelectedUserInteractor,
    securityMode: KeyguardSecurityModel.SecurityMode?,
    keyguardSecurityCallback: KeyguardSecurityCallback?,
    mEmergencyButtonController: EmergencyButtonController,
    messageAreaControllerFactory: KeyguardMessageAreaController.Factory?,
    featureFlags: FeatureFlags,
    bouncerHapticPlayer: BouncerHapticPlayer?,
) :
    KeyguardInputViewController<KeyguardSecureLockDeviceBiometricAuthView>(
        view,
        securityMode,
        keyguardSecurityCallback,
        mEmergencyButtonController,
        messageAreaControllerFactory,
        featureFlags,
        selectedUserInteractor,
        bouncerHapticPlayer,
    ) {

    private val secureLockDeviceViewModel: SecureLockDeviceBiometricAuthContentViewModel =
        secureLockDeviceViewModelFactory.create()

    public override fun onInit() {
        if (SceneContainerFlag.isEnabled) {
            return
        }

        super.onInit()

        val composeView =
            ComposeView(context).apply {
                id = R.id.secure_lock_device_biometric_auth_content
                setContent {
                    SecureLockDeviceContent(
                        secureLockDeviceViewModel = secureLockDeviceViewModel,
                        modifier = Modifier.fillMaxSize(),
                    )
                }
            }
        view.repeatWhenAttached {
            lifecycleScope.launch {
                view.addView(composeView)
                secureLockDeviceViewModel.activate()
            }
        }
    }

    override fun updateMessageAreaVisibility() {}

    override fun showMessage(
        message: CharSequence?,
        colorState: ColorStateList?,
        animated: Boolean,
    ) {}

    override fun needsInput(): Boolean = false

    override fun startAppearAnimation() {
        secureLockDeviceViewModel.startAppearAnimation()
        super.startAppearAnimation()
    }

    override fun startDisappearAnimation(finishRunnable: Runnable?): Boolean {
        secureLockDeviceViewModel.setDisappearAnimationFinishedRunnable(finishRunnable)
        return true
    }

    override fun getInitialMessageResId(): Int = 0
}