diff options
| author | 2024-08-27 21:04:28 +0000 | |
|---|---|---|
| committer | 2024-08-27 21:04:28 +0000 | |
| commit | 45bdbb5d339c959e529f42289a10c8f30200441a (patch) | |
| tree | eb13523dcab2d59e7cc3516e5874090c979fd66d | |
| parent | 028f67ad6c9b2e2c79156722469325400b1b583e (diff) | |
| parent | a064ebe529bf9fd5a0da186ef8a857428aec1588 (diff) | |
Merge "Add StatusBarDisableFlagsInteractor to disable home/recents on keyguard/bouncer." into main
2 files changed, 159 insertions, 0 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionCoreStartable.kt index 31b0bf7fe425..d9c48fa7e581 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionCoreStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionCoreStartable.kt @@ -28,6 +28,7 @@ constructor( private val interactors: Set<TransitionInteractor>, private val auditLogger: KeyguardTransitionAuditLogger, private val bootInteractor: KeyguardTransitionBootInteractor, + private val statusBarDisableFlagsInteractor: StatusBarDisableFlagsInteractor, ) : CoreStartable { override fun start() { @@ -53,6 +54,7 @@ constructor( } auditLogger.start() bootInteractor.start() + statusBarDisableFlagsInteractor.start() } companion object { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StatusBarDisableFlagsInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StatusBarDisableFlagsInteractor.kt new file mode 100644 index 000000000000..47818cbfd2f2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StatusBarDisableFlagsInteractor.kt @@ -0,0 +1,157 @@ +/* + * 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.keyguard.domain.interactor + +import android.annotation.SuppressLint +import android.app.StatusBarManager +import android.content.Context +import android.os.Binder +import android.os.IBinder +import android.os.RemoteException +import android.provider.DeviceConfig +import com.android.internal.config.sysui.SystemUiDeviceConfigFlags +import com.android.internal.statusbar.IStatusBarService +import com.android.systemui.CoreStartable +import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor +import com.android.systemui.authentication.shared.model.AuthenticationMethodModel +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.deviceconfig.domain.interactor.DeviceConfigInteractor +import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor +import com.android.systemui.keyguard.KeyguardWmStateRefactor +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.navigation.domain.interactor.NavigationInteractor +import com.android.systemui.power.domain.interactor.PowerInteractor +import com.android.systemui.power.shared.model.WakeSleepReason +import com.android.systemui.power.shared.model.WakefulnessModel +import com.android.systemui.user.domain.interactor.SelectedUserInteractor +import javax.inject.Inject +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * Logic around StatusBarService#disableForUser, which is used to disable the home and recents + * button in certain device states. + * + * TODO(b/362313975): Remove post-Flexiglass, this duplicates StatusBarStartable logic. + */ +@SysUISingleton +class StatusBarDisableFlagsInteractor +@Inject +constructor( + @Application private val scope: CoroutineScope, + @Application private val applicationContext: Context, + @Background private val backgroundDispatcher: CoroutineDispatcher, + private val deviceEntryFaceAuthInteractor: DeviceEntryFaceAuthInteractor, + private val statusBarService: IStatusBarService, + keyguardTransitionInteractor: KeyguardTransitionInteractor, + selectedUserInteractor: SelectedUserInteractor, + deviceConfigInteractor: DeviceConfigInteractor, + navigationInteractor: NavigationInteractor, + authenticationInteractor: AuthenticationInteractor, + powerInteractor: PowerInteractor, +) : CoreStartable { + + private val disableToken: IBinder = Binder() + + private val disableFlagsForUserId = + combine( + selectedUserInteractor.selectedUser, + keyguardTransitionInteractor.startedKeyguardState, + deviceConfigInteractor.property( + namespace = DeviceConfig.NAMESPACE_SYSTEMUI, + name = SystemUiDeviceConfigFlags.NAV_BAR_HANDLE_SHOW_OVER_LOCKSCREEN, + default = true, + ), + navigationInteractor.isGesturalMode, + authenticationInteractor.authenticationMethod, + powerInteractor.detailedWakefulness, + ) { values -> + val selectedUserId = values[0] as Int + val startedState = values[1] as KeyguardState + val isShowHomeOverLockscreen = values[2] as Boolean + val isGesturalMode = values[3] as Boolean + val authenticationMethod = values[4] as AuthenticationMethodModel + val wakefulnessModel = values[5] as WakefulnessModel + val isOccluded = startedState == KeyguardState.OCCLUDED + + val hideHomeAndRecentsForBouncer = + startedState == KeyguardState.PRIMARY_BOUNCER || + startedState == KeyguardState.ALTERNATE_BOUNCER + val isKeyguardShowing = startedState != KeyguardState.GONE + val isPowerGestureIntercepted = + with(wakefulnessModel) { + isAwake() && + powerButtonLaunchGestureTriggered && + lastSleepReason == WakeSleepReason.POWER_BUTTON + } + + var flags = StatusBarManager.DISABLE_NONE + + if (hideHomeAndRecentsForBouncer || (isKeyguardShowing && !isOccluded)) { + if (!isShowHomeOverLockscreen || !isGesturalMode) { + flags = flags or StatusBarManager.DISABLE_HOME + } + flags = flags or StatusBarManager.DISABLE_RECENT + } + + if ( + isPowerGestureIntercepted && + isOccluded && + authenticationMethod.isSecure && + deviceEntryFaceAuthInteractor.isFaceAuthEnabledAndEnrolled() + ) { + flags = flags or StatusBarManager.DISABLE_RECENT + } + + selectedUserId to flags + } + .distinctUntilChanged() + + @SuppressLint("WrongConstant", "NonInjectedService") + override fun start() { + if (!KeyguardWmStateRefactor.isEnabled) { + return + } + + scope.launch { + disableFlagsForUserId.collect { (selectedUserId, flags) -> + if (applicationContext.getSystemService(Context.STATUS_BAR_SERVICE) == null) { + return@collect + } + + withContext(backgroundDispatcher) { + try { + statusBarService.disableForUser( + flags, + disableToken, + applicationContext.packageName, + selectedUserId, + ) + } catch (e: RemoteException) { + e.printStackTrace() + } + } + } + } + } +} |