summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Brad Hinegardner <bhinegardner@google.com> 2023-11-29 15:20:33 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-11-29 15:20:33 +0000
commit56ca2ed66bedaa99c46a5004bf4d4f7d3bef59e6 (patch)
tree0ebc8d93bee12f776bdae9a81cd8c7536ec90750
parent6fb6c6f8ade645da700728639c3f55a18edd2884 (diff)
parentde794f46643bdf52d97730db6358df3e26d7a9ee (diff)
Merge "Connect shortcuts to transitionInteractor and clean up KeyguardPreviewRenderer" into main
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt60
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt67
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingHostedToLockscreenTransitionViewModel.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModel.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt55
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt94
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt47
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingHostedTransitionViewModel.kt47
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModel.kt45
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt115
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt17
26 files changed, 560 insertions, 186 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
index bd73d60cda29..62a0b0ebc08c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
@@ -131,13 +131,16 @@ constructor(
when (toState) {
KeyguardState.DREAMING -> TO_DREAMING_DURATION
KeyguardState.AOD -> TO_AOD_DURATION
+ KeyguardState.LOCKSCREEN -> TO_LOCKSCREEN_DURATION
else -> DEFAULT_DURATION
}.inWholeMilliseconds
}
}
+
companion object {
private val DEFAULT_DURATION = 500.milliseconds
val TO_DREAMING_DURATION = 933.milliseconds
val TO_AOD_DURATION = 1300.milliseconds
+ val TO_LOCKSCREEN_DURATION = DEFAULT_DURATION
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index 152d2172ee4c..cbfd17ff7ae4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -380,6 +380,8 @@ constructor(
KeyguardState.DREAMING -> TO_DREAMING_DURATION
KeyguardState.OCCLUDED -> TO_OCCLUDED_DURATION
KeyguardState.AOD -> TO_AOD_DURATION
+ KeyguardState.DOZING -> TO_DOZING_DURATION
+ KeyguardState.DREAMING_LOCKSCREEN_HOSTED -> TO_DREAMING_HOSTED_DURATION
else -> DEFAULT_DURATION
}.inWholeMilliseconds
}
@@ -388,7 +390,9 @@ constructor(
companion object {
const val TAG = "FromLockscreenTransitionInteractor"
private val DEFAULT_DURATION = 400.milliseconds
+ val TO_DOZING_DURATION = 500.milliseconds
val TO_DREAMING_DURATION = 933.milliseconds
+ val TO_DREAMING_HOSTED_DURATION = 933.milliseconds
val TO_OCCLUDED_DURATION = 450.milliseconds
val TO_AOD_DURATION = 500.milliseconds
val TO_PRIMARY_BOUNCER_DURATION = DEFAULT_DURATION
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 706aba3c0505..f7d1543e4650 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -72,6 +72,10 @@ constructor(
val fromDreamingTransition: Flow<TransitionStep> =
repository.transitions.filter { step -> step.from == DREAMING }
+ /** LOCKSCREEN->(any) transition information. */
+ val fromLockscreenTransition: Flow<TransitionStep> =
+ repository.transitions.filter { step -> step.from == LOCKSCREEN }
+
/** (any)->Lockscreen transition information */
val anyStateToLockscreenTransition: Flow<TransitionStep> =
repository.transitions.filter { step -> step.to == LOCKSCREEN }
@@ -113,9 +117,16 @@ constructor(
val goneToDreamingLockscreenHostedTransition: Flow<TransitionStep> =
repository.transition(GONE, DREAMING_LOCKSCREEN_HOSTED)
+ /** GONE->LOCKSCREEN transition information. */
+ val goneToLockscreenTransition: Flow<TransitionStep> = repository.transition(GONE, LOCKSCREEN)
+
/** LOCKSCREEN->AOD transition information. */
val lockscreenToAodTransition: Flow<TransitionStep> = repository.transition(LOCKSCREEN, AOD)
+ /** LOCKSCREEN->DOZING transition information. */
+ val lockscreenToDozingTransition: Flow<TransitionStep> =
+ repository.transition(LOCKSCREEN, DOZING)
+
/** LOCKSCREEN->DREAMING transition information. */
val lockscreenToDreamingTransition: Flow<TransitionStep> =
repository.transition(LOCKSCREEN, DREAMING)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
index 99025acef70d..abd79ab793d5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
@@ -30,9 +30,7 @@ import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
-import com.android.app.animation.Interpolators
import com.android.settingslib.Utils
-import com.android.systemui.res.R
import com.android.systemui.animation.Expandable
import com.android.systemui.animation.view.LaunchableImageView
import com.android.systemui.common.shared.model.Icon
@@ -40,6 +38,7 @@ import com.android.systemui.common.ui.binder.IconViewBinder
import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordanceViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.res.R
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.util.doOnEnd
import kotlinx.coroutines.flow.Flow
@@ -48,9 +47,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
-/**
- * This is only for a SINGLE Quick affordance
- */
+/** This is only for a SINGLE Quick affordance */
object KeyguardQuickAffordanceViewBinder {
private const val EXIT_DOZE_BUTTON_REVEAL_ANIMATION_DURATION_MS = 250L
@@ -135,28 +132,12 @@ object KeyguardQuickAffordanceViewBinder {
vibratorHelper: VibratorHelper?,
) {
if (!viewModel.isVisible) {
- view.alpha = 1f
- view
- .animate()
- .alpha(0f)
- .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN)
- .setDuration(EXIT_DOZE_BUTTON_REVEAL_ANIMATION_DURATION_MS)
- .withEndAction { view.isInvisible = true }
- .start()
+ view.isInvisible = true
return
}
if (!view.isVisible) {
view.isVisible = true
- if (viewModel.animateReveal) {
- view.alpha = 0f
- view
- .animate()
- .alpha(1f)
- .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
- .setDuration(EXIT_DOZE_BUTTON_REVEAL_ANIMATION_DURATION_MS)
- .start()
- }
}
IconViewBinder.bind(viewModel.icon, view)
@@ -216,13 +197,14 @@ object KeyguardQuickAffordanceViewBinder {
view.isClickable = viewModel.isClickable
if (viewModel.isClickable) {
if (viewModel.useLongPress) {
- val onTouchListener = KeyguardQuickAffordanceOnTouchListener(
- view,
- viewModel,
- messageDisplayer,
- vibratorHelper,
- falsingManager,
- )
+ val onTouchListener =
+ KeyguardQuickAffordanceOnTouchListener(
+ view,
+ viewModel,
+ messageDisplayer,
+ vibratorHelper,
+ falsingManager,
+ )
view.setOnTouchListener(onTouchListener)
view.setOnClickListener {
messageDisplayer.invoke(R.string.keyguard_affordance_press_too_short)
@@ -241,9 +223,7 @@ object KeyguardQuickAffordanceViewBinder {
KeyguardBottomAreaVibrations.ShakeAnimationDuration.inWholeMilliseconds
shakeAnimator.interpolator =
CycleInterpolator(KeyguardBottomAreaVibrations.ShakeAnimationCycles)
- shakeAnimator.doOnEnd {
- view.translationX = 0f
- }
+ shakeAnimator.doOnEnd { view.translationX = 0f }
shakeAnimator.start()
vibratorHelper?.vibrate(KeyguardBottomAreaVibrations.Shake)
@@ -268,18 +248,18 @@ object KeyguardQuickAffordanceViewBinder {
alphaFlow: Flow<Float>,
) {
combine(viewModel.map { it.isDimmed }, alphaFlow) { isDimmed, alpha ->
- if (isDimmed) DIM_ALPHA else alpha
- }
+ if (isDimmed) DIM_ALPHA else alpha
+ }
.collect { view.alpha = it }
}
private fun loadFromResources(view: View): ConfigurationBasedDimensions {
return ConfigurationBasedDimensions(
buttonSizePx =
- Size(
- view.resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width),
- view.resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height),
- ),
+ Size(
+ view.resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width),
+ view.resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height),
+ ),
)
}
@@ -337,11 +317,9 @@ object KeyguardQuickAffordanceViewBinder {
}
override fun onLongClickUseDefaultHapticFeedback(view: View) = false
-
}
private data class ConfigurationBasedDimensions(
val buttonSizePx: Size,
)
-
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 9f46e22d645c..59c798bfca1e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -84,6 +84,7 @@ import dagger.assisted.AssistedInject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.runBlocking
/** Renders the preview of the lock screen. */
@@ -158,7 +159,6 @@ constructor(
init {
if (keyguardBottomAreaRefactor()) {
- keyguardRootViewModel.enablePreviewMode()
quickAffordancesCombinedViewModel.enablePreviewMode(
initiallySelectedSlotId =
bundle.getString(
@@ -338,26 +338,27 @@ constructor(
),
)
}
-
@OptIn(ExperimentalCoroutinesApi::class)
private fun setupKeyguardRootView(previewContext: Context, rootView: FrameLayout) {
val keyguardRootView = KeyguardRootView(previewContext, null)
- disposables.add(
- KeyguardRootViewBinder.bind(
- keyguardRootView,
- keyguardRootViewModel,
- configuration,
- featureFlags,
- occludingAppDeviceEntryMessageViewModel,
- chipbarCoordinator,
- screenOffAnimationController,
- shadeInteractor,
- null, // clock provider only needed for burn in
- null, // jank monitor not required for preview mode
- null, // device entry haptics not required for preview mode
- null, // device entry haptics not required for preview mode
+ if (!keyguardBottomAreaRefactor()) {
+ disposables.add(
+ KeyguardRootViewBinder.bind(
+ keyguardRootView,
+ keyguardRootViewModel,
+ configuration,
+ featureFlags,
+ occludingAppDeviceEntryMessageViewModel,
+ chipbarCoordinator,
+ screenOffAnimationController,
+ shadeInteractor,
+ null, // clock provider only needed for burn in
+ null, // jank monitor not required for preview mode
+ null, // device entry haptics not required preview mode
+ null, // device entry haptics not required for preview mode
+ )
)
- )
+ }
rootView.addView(
keyguardRootView,
FrameLayout.LayoutParams(
@@ -392,30 +393,30 @@ constructor(
}
private fun setupShortcuts(keyguardRootView: ConstraintLayout) {
- keyguardRootView.findViewById<LaunchableImageView?>(R.id.start_button)?.let {
+ keyguardRootView.findViewById<LaunchableImageView?>(R.id.start_button)?.let { imageView ->
shortcutsBindings.add(
KeyguardQuickAffordanceViewBinder.bind(
- it,
- quickAffordancesCombinedViewModel.startButton,
- keyguardRootViewModel.alpha,
- falsingManager,
- vibratorHelper,
- ) {
- indicationController.showTransientIndication(it)
+ view = imageView,
+ viewModel = quickAffordancesCombinedViewModel.startButton,
+ alpha = flowOf(1f),
+ falsingManager = falsingManager,
+ vibratorHelper = vibratorHelper,
+ ) { message ->
+ indicationController.showTransientIndication(message)
}
)
}
- keyguardRootView.findViewById<LaunchableImageView?>(R.id.end_button)?.let {
+ keyguardRootView.findViewById<LaunchableImageView?>(R.id.end_button)?.let { imageView ->
shortcutsBindings.add(
KeyguardQuickAffordanceViewBinder.bind(
- it,
- quickAffordancesCombinedViewModel.endButton,
- keyguardRootViewModel.alpha,
- falsingManager,
- vibratorHelper,
- ) {
- indicationController.showTransientIndication(it)
+ view = imageView,
+ viewModel = quickAffordancesCombinedViewModel.endButton,
+ alpha = flowOf(1f),
+ falsingManager = falsingManager,
+ vibratorHelper = vibratorHelper,
+ ) { message ->
+ indicationController.showTransientIndication(message)
}
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt
index 55df46679f6d..cd46d6cf2188 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt
@@ -61,7 +61,7 @@ constructor(
KeyguardQuickAffordanceViewBinder.bind(
constraintLayout.requireViewById(R.id.start_button),
keyguardQuickAffordancesCombinedViewModel.startButton,
- keyguardRootViewModel.alpha,
+ keyguardQuickAffordancesCombinedViewModel.transitionAlpha,
falsingManager,
vibratorHelper,
) {
@@ -71,7 +71,7 @@ constructor(
KeyguardQuickAffordanceViewBinder.bind(
constraintLayout.requireViewById(R.id.end_button),
keyguardQuickAffordancesCombinedViewModel.endButton,
- keyguardRootViewModel.alpha,
+ keyguardQuickAffordancesCombinedViewModel.transitionAlpha,
falsingManager,
vibratorHelper,
) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt
index 0f6a966aad2e..2a68f26d3ae7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt
@@ -25,14 +25,12 @@ import androidx.constraintlayout.widget.ConstraintSet.LEFT
import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
import androidx.constraintlayout.widget.ConstraintSet.RIGHT
import com.android.systemui.Flags.keyguardBottomAreaRefactor
-import com.android.systemui.res.R
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.ui.binder.KeyguardQuickAffordanceViewBinder
import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordancesCombinedViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.res.R
import com.android.systemui.statusbar.KeyguardIndicationController
import com.android.systemui.statusbar.VibratorHelper
import javax.inject.Inject
@@ -61,7 +59,7 @@ constructor(
KeyguardQuickAffordanceViewBinder.bind(
constraintLayout.requireViewById(R.id.start_button),
keyguardQuickAffordancesCombinedViewModel.startButton,
- keyguardRootViewModel.alpha,
+ keyguardQuickAffordancesCombinedViewModel.transitionAlpha,
falsingManager,
vibratorHelper,
) {
@@ -71,7 +69,7 @@ constructor(
KeyguardQuickAffordanceViewBinder.bind(
constraintLayout.requireViewById(R.id.end_button),
keyguardQuickAffordancesCombinedViewModel.endButton,
- keyguardRootViewModel.alpha,
+ keyguardQuickAffordancesCombinedViewModel.transitionAlpha,
falsingManager,
vibratorHelper,
) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt
index 14de01b41867..1864437a7d11 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt
@@ -55,6 +55,14 @@ constructor(
onStep = { 1f },
)
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 167.milliseconds,
+ startTime = 67.milliseconds,
+ onStep = { it },
+ onCancel = { 0f },
+ )
+
val deviceEntryBackgroundViewAlpha: Flow<Float> =
deviceEntryUdfpsInteractor.isUdfpsSupported.flatMapLatest { isUdfps ->
if (isUdfps) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt
index 27fb8a3d2473..a728a2810916 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt
@@ -22,6 +22,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInterac
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -41,6 +42,13 @@ constructor(
transitionFlow = interactor.dozingToLockscreenTransition,
)
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 150.milliseconds,
+ onStep = { it },
+ onCancel = { 0f },
+ )
+
override val deviceEntryParentViewAlpha: Flow<Float> =
transitionAnimation.immediatelyTransitionTo(1f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingHostedToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingHostedToLockscreenTransitionViewModel.kt
new file mode 100644
index 000000000000..58235ae02abe
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingHostedToLockscreenTransitionViewModel.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 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.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromDreamingLockscreenHostedTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class DreamingHostedToLockscreenTransitionViewModel
+@Inject
+constructor(
+ interactor: KeyguardTransitionInteractor,
+) {
+
+ private val transitionAnimation =
+ KeyguardTransitionAnimationFlow(
+ transitionDuration = TO_LOCKSCREEN_DURATION,
+ transitionFlow = interactor.dreamingLockscreenHostedToLockscreenTransition
+ )
+
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { it },
+ onCancel = { 0f },
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
index a3b8b85fc53d..f943bdfa7550 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
@@ -96,6 +96,14 @@ constructor(
onStep = { it },
)
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ startTime = 233.milliseconds,
+ duration = 250.milliseconds,
+ onStep = { it },
+ onCancel = { 0f },
+ )
+
val deviceEntryBackgroundViewAlpha =
deviceEntryUdfpsInteractor.isUdfpsSupported.flatMapLatest { isUdfps ->
if (isUdfps) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModel.kt
new file mode 100644
index 000000000000..5804a205445c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModel.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 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.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromGoneTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class GoneToLockscreenTransitionViewModel
+@Inject
+constructor(
+ interactor: KeyguardTransitionInteractor,
+) {
+
+ private val transitionAnimation =
+ KeyguardTransitionAnimationFlow(
+ transitionDuration = TO_LOCKSCREEN_DURATION,
+ transitionFlow = interactor.goneToLockscreenTransition
+ )
+
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { it },
+ onCancel = { 0f },
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
index 02ea5508f34f..188be244be4a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
@@ -23,6 +23,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceIn
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -32,6 +33,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
@OptIn(ExperimentalCoroutinesApi::class)
class KeyguardQuickAffordancesCombinedViewModel
@@ -39,6 +41,22 @@ class KeyguardQuickAffordancesCombinedViewModel
constructor(
private val quickAffordanceInteractor: KeyguardQuickAffordanceInteractor,
private val keyguardInteractor: KeyguardInteractor,
+ shadeInteractor: ShadeInteractor,
+ aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
+ dozingToLockscreenTransitionViewModel: DozingToLockscreenTransitionViewModel,
+ dreamingHostedToLockscreenTransitionViewModel: DreamingHostedToLockscreenTransitionViewModel,
+ dreamingToLockscreenTransitionViewModel: DreamingToLockscreenTransitionViewModel,
+ goneToLockscreenTransitionViewModel: GoneToLockscreenTransitionViewModel,
+ occludedToLockscreenTransitionViewModel: OccludedToLockscreenTransitionViewModel,
+ offToLockscreenTransitionViewModel: OffToLockscreenTransitionViewModel,
+ primaryBouncerToLockscreenTransitionViewModel: PrimaryBouncerToLockscreenTransitionViewModel,
+ lockscreenToAodTransitionViewModel: LockscreenToAodTransitionViewModel,
+ lockscreenToDozingTransitionViewModel: LockscreenToDozingTransitionViewModel,
+ lockscreenToDreamingHostedTransitionViewModel: LockscreenToDreamingHostedTransitionViewModel,
+ lockscreenToDreamingTransitionViewModel: LockscreenToDreamingTransitionViewModel,
+ lockscreenToGoneTransitionViewModel: LockscreenToGoneTransitionViewModel,
+ lockscreenToOccludedTransitionViewModel: LockscreenToOccludedTransitionViewModel,
+ lockscreenToPrimaryBouncerTransitionViewModel: LockscreenToPrimaryBouncerTransitionViewModel,
) {
data class PreviewMode(
@@ -60,6 +78,39 @@ constructor(
private val selectedPreviewSlotId =
MutableStateFlow(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START)
+ /** alpha while fading the quick affordances out */
+ private val fadeInAlpha: Flow<Float> =
+ merge(
+ aodToLockscreenTransitionViewModel.shortcutsAlpha,
+ dozingToLockscreenTransitionViewModel.shortcutsAlpha,
+ dreamingHostedToLockscreenTransitionViewModel.shortcutsAlpha,
+ dreamingToLockscreenTransitionViewModel.shortcutsAlpha,
+ goneToLockscreenTransitionViewModel.shortcutsAlpha,
+ occludedToLockscreenTransitionViewModel.shortcutsAlpha,
+ offToLockscreenTransitionViewModel.shortcutsAlpha,
+ primaryBouncerToLockscreenTransitionViewModel.shortcutsAlpha,
+ )
+
+ /** alpha while fading the quick affordances in */
+ private val fadeOutAlpha: Flow<Float> =
+ merge(
+ lockscreenToAodTransitionViewModel.shortcutsAlpha,
+ lockscreenToDozingTransitionViewModel.shortcutsAlpha,
+ lockscreenToDreamingHostedTransitionViewModel.shortcutsAlpha,
+ lockscreenToDreamingTransitionViewModel.shortcutsAlpha,
+ lockscreenToGoneTransitionViewModel.shortcutsAlpha,
+ lockscreenToOccludedTransitionViewModel.shortcutsAlpha,
+ lockscreenToPrimaryBouncerTransitionViewModel.shortcutsAlpha,
+ shadeInteractor.qsExpansion.map { 1 - it },
+ )
+
+ /** The source of truth of alpha for all of the quick affordances on lockscreen */
+ val transitionAlpha: Flow<Float> =
+ merge(
+ fadeInAlpha,
+ fadeOutAlpha,
+ )
+
/**
* Whether quick affordances are "opaque enough" to be considered visible to and interactive by
* the user. If they are not interactive, user input should not be allowed on them.
@@ -73,7 +124,7 @@ constructor(
* interactive/clickable unless "fully opaque" to avoid issues like in b/241830987.
*/
private val areQuickAffordancesFullyOpaque: Flow<Boolean> =
- keyguardInteractor.keyguardAlpha
+ transitionAlpha
.map { alpha -> alpha >= AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD }
.distinctUntilChanged()
@@ -89,7 +140,7 @@ constructor(
* Notifies that a slot with the given ID has been selected in the preview experience that is
* rendering in the wallpaper picker. This is ignored for the real lock screen experience.
*
- * @see [KeyguardRootViewModel.enablePreviewMode]
+ * @see [enablePreviewMode]
*/
fun onPreviewSlotSelected(slotId: String) {
selectedPreviewSlotId.value = slotId
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index 524fa1ede90a..f63afebb60ab 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -47,13 +47,11 @@ import javax.inject.Inject
import javax.inject.Provider
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onStart
@@ -74,16 +72,6 @@ constructor(
private val aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
screenOffAnimationController: ScreenOffAnimationController,
) {
-
- data class PreviewMode(val isInPreviewMode: Boolean = false)
-
- /**
- * Whether this view-model instance is powering the preview experience that renders exclusively
- * in the wallpaper picker application. This should _always_ be `false` for the real lock screen
- * experience.
- */
- private val previewMode = MutableStateFlow(PreviewMode())
-
var clockControllerProvider: Provider<ClockController>? = null
/** System insets that keyguard needs to stay out of */
@@ -103,14 +91,7 @@ constructor(
keyguardInteractor.notificationContainerBounds
/** An observable for the alpha level for the entire keyguard root view. */
- val alpha: Flow<Float> =
- previewMode.flatMapLatest {
- if (it.isInPreviewMode) {
- flowOf(1f)
- } else {
- keyguardInteractor.keyguardAlpha.distinctUntilChanged()
- }
- }
+ val alpha: Flow<Float> = keyguardInteractor.keyguardAlpha.distinctUntilChanged()
private fun burnIn(): Flow<BurnInModel> {
val dozingAmount: Flow<Float> =
@@ -147,55 +128,29 @@ constructor(
val lockscreenStateAlpha: Flow<Float> = aodToLockscreenTransitionViewModel.lockscreenAlpha
/** For elements that appear and move during the animation -> AOD */
- val burnInLayerAlpha: Flow<Float> =
- previewMode.flatMapLatest {
- if (it.isInPreviewMode) {
- flowOf(1f)
- } else {
- goneToAodTransitionViewModel.enterFromTopAnimationAlpha
- }
- }
+ val burnInLayerAlpha: Flow<Float> = goneToAodTransitionViewModel.enterFromTopAnimationAlpha
val translationY: Flow<Float> =
- previewMode.flatMapLatest {
- if (it.isInPreviewMode) {
- flowOf(0f)
- } else {
- keyguardInteractor.configurationChange.flatMapLatest { _ ->
- val enterFromTopAmount =
- context.resources.getDimensionPixelSize(
- R.dimen.keyguard_enter_from_top_translation_y
- )
- combine(
- keyguardInteractor.keyguardTranslationY.onStart { emit(0f) },
- burnIn().map { it.translationY.toFloat() }.onStart { emit(0f) },
- goneToAodTransitionViewModel
- .enterFromTopTranslationY(enterFromTopAmount)
- .onStart { emit(0f) },
- ) { keyguardTransitionY, burnInTranslationY, goneToAodTransitionTranslationY ->
- // All 3 values need to be combined for a smooth translation
- keyguardTransitionY + burnInTranslationY + goneToAodTransitionTranslationY
- }
- }
+ keyguardInteractor.configurationChange.flatMapLatest { _ ->
+ val enterFromTopAmount =
+ context.resources.getDimensionPixelSize(
+ R.dimen.keyguard_enter_from_top_translation_y
+ )
+ combine(
+ keyguardInteractor.keyguardTranslationY.onStart { emit(0f) },
+ burnIn().map { it.translationY.toFloat() }.onStart { emit(0f) },
+ goneToAodTransitionViewModel.enterFromTopTranslationY(enterFromTopAmount).onStart {
+ emit(0f)
+ },
+ ) { keyguardTransitionY, burnInTranslationY, goneToAodTransitionTranslationY ->
+ // All 3 values need to be combined for a smooth translation
+ keyguardTransitionY + burnInTranslationY + goneToAodTransitionTranslationY
}
}
- val translationX: Flow<Float> =
- previewMode.flatMapLatest {
- if (it.isInPreviewMode) {
- flowOf(0f)
- } else {
- burnIn().map { it.translationX.toFloat() }
- }
- }
+ val translationX: Flow<Float> = burnIn().map { it.translationX.toFloat() }
- val scale: Flow<Pair<Float, Boolean>> =
- previewMode.flatMapLatest { previewMode ->
- burnIn().map {
- val scale = if (previewMode.isInPreviewMode) 1f else it.scale
- Pair(scale, it.scaleClockOnly)
- }
- }
+ val scale: Flow<Pair<Float, Boolean>> = burnIn().map { Pair(it.scale, it.scaleClockOnly) }
/** Is the notification icon container visible? */
val isNotifIconContainerVisible: Flow<AnimatedValue<Boolean>> =
@@ -238,20 +193,7 @@ constructor(
}
.distinctUntilChanged()
- /**
- * Puts this view-model in "preview mode", which means it's being used for UI that is rendering
- * the lock screen preview in wallpaper picker / settings and not the real experience on the
- * lock screen.
- */
- fun enablePreviewMode() {
- previewMode.value = PreviewMode(true)
- }
-
fun onNotificationContainerBoundsChanged(top: Float, bottom: Float) {
- // Notifications should not be visible in preview mode
- if (previewMode.value.isInPreviewMode) {
- return
- }
keyguardInteractor.setNotificationContainerBounds(NotificationContainerBounds(top, bottom))
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
index 2bf12e8e33b2..8e8fd75cc1c0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
@@ -57,6 +57,15 @@ constructor(
onFinish = { 0f },
),
)
+
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { 1 - it },
+ onFinish = { 0f },
+ onCancel = { 1f },
+ )
+
override val deviceEntryParentViewAlpha: Flow<Float> =
deviceEntryUdfpsInteractor.isUdfpsEnrolledAndEnabled.flatMapLatest {
isUdfpsEnrolledAndEnabled ->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt
new file mode 100644
index 000000000000..263ed11503ba
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 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.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_DOZING_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class LockscreenToDozingTransitionViewModel
+@Inject
+constructor(
+ interactor: KeyguardTransitionInteractor,
+) {
+
+ private val transitionAnimation =
+ KeyguardTransitionAnimationFlow(
+ transitionDuration = TO_DOZING_DURATION,
+ transitionFlow = interactor.lockscreenToDozingTransition
+ )
+
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { 1 - it },
+ onFinish = { 0f },
+ onCancel = { 1f },
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingHostedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingHostedTransitionViewModel.kt
new file mode 100644
index 000000000000..17015056bda0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingHostedTransitionViewModel.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 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.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_DREAMING_HOSTED_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class LockscreenToDreamingHostedTransitionViewModel
+@Inject
+constructor(
+ interactor: KeyguardTransitionInteractor,
+) {
+
+ private val transitionAnimation =
+ KeyguardTransitionAnimationFlow(
+ transitionDuration = TO_DREAMING_HOSTED_DURATION,
+ transitionFlow = interactor.lockscreenToDreamingLockscreenHostedTransition
+ )
+
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { 1 - it },
+ onFinish = { 0f },
+ onCancel = { 1f },
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt
index 52296137a3d6..401c0ff76c29 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt
@@ -62,6 +62,14 @@ constructor(
onStep = { 1f - it },
)
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { 1 - it },
+ onFinish = { 0f },
+ onCancel = { 1f },
+ )
+
override val deviceEntryParentViewAlpha: Flow<Float> =
shadeDependentFlows.transitionFlow(
flowWhenShadeIsNotExpanded = lockscreenAlpha,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
index 59e5aa845051..cfb4bf59c8a8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
@@ -23,6 +23,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -43,6 +44,14 @@ constructor(
transitionFlow = interactor.transition(KeyguardState.LOCKSCREEN, KeyguardState.GONE),
)
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { 1 - it },
+ onFinish = { 0f },
+ onCancel = { 1f },
+ )
+
override val deviceEntryParentViewAlpha: Flow<Float> =
transitionAnimation.immediatelyTransitionTo(0f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
index d49bc4994b0f..a6136f95d0f6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
@@ -50,6 +50,14 @@ constructor(
onStep = { 1f - it },
)
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { 1 - it },
+ onFinish = { 0f },
+ onCancel = { 1f },
+ )
+
/** Lockscreen views y-translation */
fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
return transitionAnimation.createFlow(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
index f04b67a1d4d4..07dd4ef49c5d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
@@ -26,6 +26,7 @@ import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
/**
* Breaks down LOCKSCREEN->PRIMARY BOUNCER transition into discrete steps for corresponding views to
@@ -46,6 +47,11 @@ constructor(
interactor.transition(KeyguardState.LOCKSCREEN, KeyguardState.PRIMARY_BOUNCER),
)
+ val shortcutsAlpha: Flow<Float> =
+ interactor.transition(KeyguardState.LOCKSCREEN, KeyguardState.PRIMARY_BOUNCER).map {
+ 1 - it.value
+ }
+
override val deviceEntryParentViewAlpha: Flow<Float> =
shadeDependentFlows.transitionFlow(
flowWhenShadeIsNotExpanded =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
index 0bdc85d05106..58be0934beca 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
@@ -58,6 +58,13 @@ constructor(
)
}
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { it },
+ onCancel = { 0f },
+ )
+
/** Lockscreen views alpha */
val lockscreenAlpha: Flow<Float> =
transitionAnimation.createFlow(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModel.kt
new file mode 100644
index 000000000000..c3bc799435a8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModel.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 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.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class OffToLockscreenTransitionViewModel
+@Inject
+constructor(
+ interactor: KeyguardTransitionInteractor,
+) {
+
+ private val transitionAnimation =
+ KeyguardTransitionAnimationFlow(
+ transitionDuration = 250.milliseconds,
+ transitionFlow = interactor.offToLockscreenTransition
+ )
+
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { it },
+ onCancel = { 0f },
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
index 3cf793ab9dc8..7ef8374023fb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
@@ -28,6 +28,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.map
/**
* Breaks down PRIMARY BOUNCER->LOCKSCREEN transition into discrete steps for corresponding views to
@@ -57,6 +58,11 @@ constructor(
}
}
+ val shortcutsAlpha: Flow<Float> =
+ interactor.transition(KeyguardState.PRIMARY_BOUNCER, KeyguardState.LOCKSCREEN).map {
+ it.value
+ }
+
override val deviceEntryParentViewAlpha: Flow<Float> =
transitionAnimation.immediatelyTransitionTo(1f)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
index 67c4e2688cd0..0c30d10ea563 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
@@ -51,6 +51,7 @@ import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.res.R
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.FakeSharedPreferences
@@ -58,8 +59,10 @@ import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.settings.FakeSettings
import com.google.common.truth.Truth
-import kotlin.math.max
import kotlin.math.min
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
@@ -73,6 +76,7 @@ import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(JUnit4::class)
class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
@@ -85,6 +89,47 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
@Mock private lateinit var keyguardStateController: KeyguardStateController
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
@Mock private lateinit var logger: KeyguardQuickAffordancesMetricsLogger
+ @Mock private lateinit var shadeInteractor: ShadeInteractor
+ @Mock
+ private lateinit var aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel
+ @Mock
+ private lateinit var dozingToLockscreenTransitionViewModel:
+ DozingToLockscreenTransitionViewModel
+ @Mock
+ private lateinit var dreamingHostedToLockscreenTransitionViewModel:
+ DreamingHostedToLockscreenTransitionViewModel
+ @Mock
+ private lateinit var dreamingToLockscreenTransitionViewModel:
+ DreamingToLockscreenTransitionViewModel
+ @Mock
+ private lateinit var goneToLockscreenTransitionViewModel: GoneToLockscreenTransitionViewModel
+ @Mock
+ private lateinit var occludedToLockscreenTransitionViewModel:
+ OccludedToLockscreenTransitionViewModel
+ @Mock
+ private lateinit var offToLockscreenTransitionViewModel: OffToLockscreenTransitionViewModel
+ @Mock
+ private lateinit var primaryBouncerToLockscreenTransitionViewModel:
+ PrimaryBouncerToLockscreenTransitionViewModel
+ @Mock
+ private lateinit var lockscreenToAodTransitionViewModel: LockscreenToAodTransitionViewModel
+ @Mock
+ private lateinit var lockscreenToDozingTransitionViewModel:
+ LockscreenToDozingTransitionViewModel
+ @Mock
+ private lateinit var lockscreenToDreamingHostedTransitionViewModel:
+ LockscreenToDreamingHostedTransitionViewModel
+ @Mock
+ private lateinit var lockscreenToDreamingTransitionViewModel:
+ LockscreenToDreamingTransitionViewModel
+ @Mock
+ private lateinit var lockscreenToGoneTransitionViewModel: LockscreenToGoneTransitionViewModel
+ @Mock
+ private lateinit var lockscreenToOccludedTransitionViewModel:
+ LockscreenToOccludedTransitionViewModel
+ @Mock
+ private lateinit var lockscreenToPrimaryBouncerTransitionViewModel:
+ LockscreenToPrimaryBouncerTransitionViewModel
private lateinit var underTest: KeyguardQuickAffordancesCombinedViewModel
@@ -97,6 +142,10 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
private lateinit var keyguardInteractor: KeyguardInteractor
+ private val intendedAlphaMutableStateFlow: MutableStateFlow<Float> = MutableStateFlow(1f)
+ // the viewModel does a `map { 1 - it }` on this value, which is why it's different
+ private val intendedShadeAlphaMutableStateFlow: MutableStateFlow<Float> = MutableStateFlow(0f)
+
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
@@ -191,6 +240,31 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
userHandle = UserHandle.SYSTEM,
)
+ intendedAlphaMutableStateFlow.value = 1f
+ intendedShadeAlphaMutableStateFlow.value = 0f
+ whenever(aodToLockscreenTransitionViewModel.shortcutsAlpha)
+ .thenReturn(intendedAlphaMutableStateFlow)
+ whenever(dozingToLockscreenTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(dreamingHostedToLockscreenTransitionViewModel.shortcutsAlpha)
+ .thenReturn(emptyFlow())
+ whenever(dreamingToLockscreenTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(goneToLockscreenTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(occludedToLockscreenTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(offToLockscreenTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(primaryBouncerToLockscreenTransitionViewModel.shortcutsAlpha)
+ .thenReturn(emptyFlow())
+ whenever(lockscreenToAodTransitionViewModel.shortcutsAlpha)
+ .thenReturn(intendedAlphaMutableStateFlow)
+ whenever(lockscreenToDozingTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(lockscreenToDreamingHostedTransitionViewModel.shortcutsAlpha)
+ .thenReturn(emptyFlow())
+ whenever(lockscreenToDreamingTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(lockscreenToGoneTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(lockscreenToOccludedTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(lockscreenToPrimaryBouncerTransitionViewModel.shortcutsAlpha)
+ .thenReturn(emptyFlow())
+ whenever(shadeInteractor.qsExpansion).thenReturn(intendedShadeAlphaMutableStateFlow)
+
underTest =
KeyguardQuickAffordancesCombinedViewModel(
quickAffordanceInteractor =
@@ -210,7 +284,27 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
backgroundDispatcher = testDispatcher,
appContext = mContext,
),
- keyguardInteractor = keyguardInteractor
+ keyguardInteractor = keyguardInteractor,
+ shadeInteractor = shadeInteractor,
+ aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel,
+ dozingToLockscreenTransitionViewModel = dozingToLockscreenTransitionViewModel,
+ dreamingHostedToLockscreenTransitionViewModel =
+ dreamingHostedToLockscreenTransitionViewModel,
+ dreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel,
+ goneToLockscreenTransitionViewModel = goneToLockscreenTransitionViewModel,
+ occludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel,
+ offToLockscreenTransitionViewModel = offToLockscreenTransitionViewModel,
+ primaryBouncerToLockscreenTransitionViewModel =
+ primaryBouncerToLockscreenTransitionViewModel,
+ lockscreenToAodTransitionViewModel = lockscreenToAodTransitionViewModel,
+ lockscreenToDozingTransitionViewModel = lockscreenToDozingTransitionViewModel,
+ lockscreenToDreamingHostedTransitionViewModel =
+ lockscreenToDreamingHostedTransitionViewModel,
+ lockscreenToDreamingTransitionViewModel = lockscreenToDreamingTransitionViewModel,
+ lockscreenToGoneTransitionViewModel = lockscreenToGoneTransitionViewModel,
+ lockscreenToOccludedTransitionViewModel = lockscreenToOccludedTransitionViewModel,
+ lockscreenToPrimaryBouncerTransitionViewModel =
+ lockscreenToPrimaryBouncerTransitionViewModel
)
}
@@ -526,15 +620,15 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
@Test
fun isClickable_falseWhenAlphaBelowThreshold() =
testScope.runTest {
+ intendedAlphaMutableStateFlow.value =
+ KeyguardQuickAffordancesCombinedViewModel.AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD -
+ .1f
+ // the viewModel does a `map { 1 - it }` on this value, which is why it's different
+ intendedShadeAlphaMutableStateFlow.value =
+ KeyguardQuickAffordancesCombinedViewModel.AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD +
+ .1f
repository.setKeyguardShowing(true)
val latest = collectLastValue(underTest.startButton)
- repository.setKeyguardAlpha(
- max(
- 0f,
- KeyguardQuickAffordancesCombinedViewModel
- .AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD - 0.1f
- ),
- )
val testConfig =
TestConfig(
@@ -561,9 +655,10 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
@Test
fun isClickable_falseWhenAlphaAtZero() =
testScope.runTest {
+ intendedAlphaMutableStateFlow.value = 0f
+ intendedShadeAlphaMutableStateFlow.value = 1f
repository.setKeyguardShowing(true)
val latest = collectLastValue(underTest.startButton)
- repository.setKeyguardAlpha(0f)
val testConfig =
TestConfig(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
index e6d6cf263d69..a57feda64723 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
@@ -163,23 +163,6 @@ class KeyguardRootViewModelTest : SysuiTestCase() {
}
@Test
- fun alpha_inPreviewMode_doesNotChange() =
- testScope.runTest {
- val value = collectLastValue(underTest.alpha)
- underTest.enablePreviewMode()
-
- assertThat(value()).isEqualTo(1f)
- repository.setKeyguardAlpha(0.1f)
- assertThat(value()).isEqualTo(1f)
- repository.setKeyguardAlpha(0.5f)
- assertThat(value()).isEqualTo(1f)
- repository.setKeyguardAlpha(0.2f)
- assertThat(value()).isEqualTo(1f)
- repository.setKeyguardAlpha(0f)
- assertThat(value()).isEqualTo(1f)
- }
-
- @Test
fun translationAndScaleFromBurnInNotDozing() =
testScope.runTest {
val translationX by collectLastValue(underTest.translationX)