Merge "[DO NOT MERGE] OCCLUDED->LOCKSCREEN transition" into tm-qpr-dev

This commit is contained in:
TreeHugger Robot
2022-12-22 14:24:40 +00:00
committed by Android (Google) Code Review
8 changed files with 282 additions and 17 deletions

View File

@@ -1275,6 +1275,9 @@
<!-- DREAMING -> LOCKSCREEN transition: Amount to shift lockscreen content on entering --> <!-- DREAMING -> LOCKSCREEN transition: Amount to shift lockscreen content on entering -->
<dimen name="dreaming_to_lockscreen_transition_lockscreen_translation_y">40dp</dimen> <dimen name="dreaming_to_lockscreen_transition_lockscreen_translation_y">40dp</dimen>
<!-- OCCLUDED -> LOCKSCREEN transition: Amount to shift lockscreen content on entering -->
<dimen name="occluded_to_lockscreen_transition_lockscreen_translation_y">40dp</dimen>
<!-- The amount of vertical offset for the keyguard during the full shade transition. --> <!-- The amount of vertical offset for the keyguard during the full shade transition. -->
<dimen name="lockscreen_shade_keyguard_transition_vertical_offset">0dp</dimen> <dimen name="lockscreen_shade_keyguard_transition_vertical_offset">0dp</dimen>

View File

@@ -80,7 +80,7 @@ constructor(
name, name,
KeyguardState.OCCLUDED, KeyguardState.OCCLUDED,
KeyguardState.LOCKSCREEN, KeyguardState.LOCKSCREEN,
getAnimator(), getAnimator(TO_LOCKSCREEN_DURATION),
) )
) )
} }
@@ -97,6 +97,6 @@ constructor(
companion object { companion object {
private val DEFAULT_DURATION = 500.milliseconds private val DEFAULT_DURATION = 500.milliseconds
val TO_LOCKSCREEN_DURATION = 1183.milliseconds val TO_LOCKSCREEN_DURATION = 933.milliseconds
} }
} }

View File

@@ -24,7 +24,9 @@ import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.KeyguardState.AOD import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.keyguard.shared.model.TransitionStep
import javax.inject.Inject import javax.inject.Inject
import kotlin.time.Duration import kotlin.time.Duration
@@ -50,6 +52,10 @@ constructor(
val dreamingToLockscreenTransition: Flow<TransitionStep> = val dreamingToLockscreenTransition: Flow<TransitionStep> =
repository.transition(DREAMING, LOCKSCREEN) repository.transition(DREAMING, LOCKSCREEN)
/** OCCLUDED->LOCKSCREEN transition information. */
val occludedToLockscreenTransition: Flow<TransitionStep> =
repository.transition(OCCLUDED, LOCKSCREEN)
/** (any)->AOD transition information */ /** (any)->AOD transition information */
val anyStateToAodTransition: Flow<TransitionStep> = val anyStateToAodTransition: Flow<TransitionStep> =
repository.transitions.filter { step -> step.to == KeyguardState.AOD } repository.transitions.filter { step -> step.to == KeyguardState.AOD }
@@ -93,7 +99,14 @@ constructor(
val start = (params.startTime / totalDuration).toFloat() val start = (params.startTime / totalDuration).toFloat()
val chunks = (totalDuration / params.duration).toFloat() val chunks = (totalDuration / params.duration).toFloat()
return flow return flow
.map { step -> (step.value - start) * chunks } // When starting, emit a value of 0f to give animations a chance to set initial state
.map { step ->
if (step.transitionState == STARTED) {
0f
} else {
(step.value - start) * chunks
}
}
.filter { value -> value >= 0f && value <= 1f } .filter { value -> value >= 0f && value <= 1f }
} }
} }

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2022 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.animation.Interpolators.EMPHASIZED_DECELERATE
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.FromOccludedTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.AnimationParams
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
/**
* Breaks down OCCLUDED->LOCKSCREEN transition into discrete steps for corresponding views to
* consume.
*/
@SysUISingleton
class OccludedToLockscreenTransitionViewModel
@Inject
constructor(
private val interactor: KeyguardTransitionInteractor,
) {
/** Lockscreen views y-translation */
fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
return flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { value ->
-translatePx + (EMPHASIZED_DECELERATE.getInterpolation(value) * translatePx)
}
}
/** Lockscreen views alpha */
val lockscreenAlpha: Flow<Float> = flowForAnimation(LOCKSCREEN_ALPHA)
private fun flowForAnimation(params: AnimationParams): Flow<Float> {
return interactor.transitionStepAnimation(
interactor.occludedToLockscreenTransition,
params,
totalDuration = TO_LOCKSCREEN_DURATION
)
}
companion object {
@JvmField val LOCKSCREEN_ANIMATION_DURATION_MS = TO_LOCKSCREEN_DURATION.inWholeMilliseconds
val LOCKSCREEN_TRANSLATION_Y = AnimationParams(duration = TO_LOCKSCREEN_DURATION)
val LOCKSCREEN_ALPHA =
AnimationParams(startTime = 233.milliseconds, duration = 250.milliseconds)
}
}

View File

@@ -144,6 +144,7 @@ import com.android.systemui.keyguard.shared.model.TransitionState;
import com.android.systemui.keyguard.shared.model.TransitionStep; import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel; import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel; import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel;
import com.android.systemui.media.controls.pipeline.MediaDataManager; import com.android.systemui.media.controls.pipeline.MediaDataManager;
import com.android.systemui.media.controls.ui.KeyguardMediaController; import com.android.systemui.media.controls.ui.KeyguardMediaController;
import com.android.systemui.media.controls.ui.MediaHierarchyManager; import com.android.systemui.media.controls.ui.MediaHierarchyManager;
@@ -238,6 +239,8 @@ import java.util.function.Consumer;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Provider; import javax.inject.Provider;
import kotlinx.coroutines.CoroutineDispatcher;
@CentralSurfacesComponent.CentralSurfacesScope @CentralSurfacesComponent.CentralSurfacesScope
public final class NotificationPanelViewController implements Dumpable { public final class NotificationPanelViewController implements Dumpable {
@@ -683,10 +686,13 @@ public final class NotificationPanelViewController implements Dumpable {
private boolean mIgnoreXTouchSlop; private boolean mIgnoreXTouchSlop;
private boolean mExpandLatencyTracking; private boolean mExpandLatencyTracking;
private DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel; private DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel;
private OccludedToLockscreenTransitionViewModel mOccludedToLockscreenTransitionViewModel;
private KeyguardTransitionInteractor mKeyguardTransitionInteractor; private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
private boolean mIsDreamToLockscreenTransitionRunning = false; private CoroutineDispatcher mMainDispatcher;
private boolean mIsToLockscreenTransitionRunning = false;
private int mDreamingToLockscreenTransitionTranslationY; private int mDreamingToLockscreenTransitionTranslationY;
private int mOccludedToLockscreenTransitionTranslationY;
private boolean mUnocclusionTransitionFlagEnabled = false; private boolean mUnocclusionTransitionFlagEnabled = false;
private final Runnable mFlingCollapseRunnable = () -> fling(0, false /* expand */, private final Runnable mFlingCollapseRunnable = () -> fling(0, false /* expand */,
@@ -705,7 +711,13 @@ public final class NotificationPanelViewController implements Dumpable {
private final Consumer<TransitionStep> mDreamingToLockscreenTransition = private final Consumer<TransitionStep> mDreamingToLockscreenTransition =
(TransitionStep step) -> { (TransitionStep step) -> {
mIsDreamToLockscreenTransitionRunning = mIsToLockscreenTransitionRunning =
step.getTransitionState() == TransitionState.RUNNING;
};
private final Consumer<TransitionStep> mOccludedToLockscreenTransition =
(TransitionStep step) -> {
mIsToLockscreenTransitionRunning =
step.getTransitionState() == TransitionState.RUNNING; step.getTransitionState() == TransitionState.RUNNING;
}; };
@@ -778,6 +790,8 @@ public final class NotificationPanelViewController implements Dumpable {
KeyguardBottomAreaViewModel keyguardBottomAreaViewModel, KeyguardBottomAreaViewModel keyguardBottomAreaViewModel,
KeyguardBottomAreaInteractor keyguardBottomAreaInteractor, KeyguardBottomAreaInteractor keyguardBottomAreaInteractor,
DreamingToLockscreenTransitionViewModel dreamingToLockscreenTransitionViewModel, DreamingToLockscreenTransitionViewModel dreamingToLockscreenTransitionViewModel,
OccludedToLockscreenTransitionViewModel occludedToLockscreenTransitionViewModel,
@Main CoroutineDispatcher mainDispatcher,
KeyguardTransitionInteractor keyguardTransitionInteractor, KeyguardTransitionInteractor keyguardTransitionInteractor,
DumpManager dumpManager) { DumpManager dumpManager) {
keyguardStateController.addCallback(new KeyguardStateController.Callback() { keyguardStateController.addCallback(new KeyguardStateController.Callback() {
@@ -795,6 +809,7 @@ public final class NotificationPanelViewController implements Dumpable {
mShadeHeightLogger = shadeHeightLogger; mShadeHeightLogger = shadeHeightLogger;
mGutsManager = gutsManager; mGutsManager = gutsManager;
mDreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel; mDreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel;
mOccludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel;
mKeyguardTransitionInteractor = keyguardTransitionInteractor; mKeyguardTransitionInteractor = keyguardTransitionInteractor;
mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override @Override
@@ -873,6 +888,7 @@ public final class NotificationPanelViewController implements Dumpable {
mFalsingCollector = falsingCollector; mFalsingCollector = falsingCollector;
mPowerManager = powerManager; mPowerManager = powerManager;
mWakeUpCoordinator = coordinator; mWakeUpCoordinator = coordinator;
mMainDispatcher = mainDispatcher;
mAccessibilityManager = accessibilityManager; mAccessibilityManager = accessibilityManager;
mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle()); mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
setPanelAlpha(255, false /* animate */); setPanelAlpha(255, false /* animate */);
@@ -1097,15 +1113,27 @@ public final class NotificationPanelViewController implements Dumpable {
controller.setup(mNotificationContainerParent)); controller.setup(mNotificationContainerParent));
if (mUnocclusionTransitionFlagEnabled) { if (mUnocclusionTransitionFlagEnabled) {
// Dreaming->Lockscreen
collectFlow(mView, mKeyguardTransitionInteractor.getDreamingToLockscreenTransition(),
mDreamingToLockscreenTransition, mMainDispatcher);
collectFlow(mView, mDreamingToLockscreenTransitionViewModel.getLockscreenAlpha(), collectFlow(mView, mDreamingToLockscreenTransitionViewModel.getLockscreenAlpha(),
dreamingToLockscreenTransitionAlpha(mNotificationStackScrollLayoutController)); toLockscreenTransitionAlpha(mNotificationStackScrollLayoutController),
mMainDispatcher);
collectFlow(mView, mDreamingToLockscreenTransitionViewModel.lockscreenTranslationY( collectFlow(mView, mDreamingToLockscreenTransitionViewModel.lockscreenTranslationY(
mDreamingToLockscreenTransitionTranslationY), mDreamingToLockscreenTransitionTranslationY),
dreamingToLockscreenTransitionY(mNotificationStackScrollLayoutController)); toLockscreenTransitionY(mNotificationStackScrollLayoutController),
mMainDispatcher);
collectFlow(mView, mKeyguardTransitionInteractor.getDreamingToLockscreenTransition(), // Occluded->Lockscreen
mDreamingToLockscreenTransition); collectFlow(mView, mKeyguardTransitionInteractor.getOccludedToLockscreenTransition(),
mOccludedToLockscreenTransition, mMainDispatcher);
collectFlow(mView, mOccludedToLockscreenTransitionViewModel.getLockscreenAlpha(),
toLockscreenTransitionAlpha(mNotificationStackScrollLayoutController),
mMainDispatcher);
collectFlow(mView, mOccludedToLockscreenTransitionViewModel.lockscreenTranslationY(
mOccludedToLockscreenTransitionTranslationY),
toLockscreenTransitionY(mNotificationStackScrollLayoutController),
mMainDispatcher);
} }
} }
@@ -1143,6 +1171,8 @@ public final class NotificationPanelViewController implements Dumpable {
R.dimen.split_shade_scrim_transition_distance); R.dimen.split_shade_scrim_transition_distance);
mDreamingToLockscreenTransitionTranslationY = mResources.getDimensionPixelSize( mDreamingToLockscreenTransitionTranslationY = mResources.getDimensionPixelSize(
R.dimen.dreaming_to_lockscreen_transition_lockscreen_translation_y); R.dimen.dreaming_to_lockscreen_transition_lockscreen_translation_y);
mOccludedToLockscreenTransitionTranslationY = mResources.getDimensionPixelSize(
R.dimen.occluded_to_lockscreen_transition_lockscreen_translation_y);
} }
private void updateViewControllers(KeyguardStatusView keyguardStatusView, private void updateViewControllers(KeyguardStatusView keyguardStatusView,
@@ -1806,7 +1836,7 @@ public final class NotificationPanelViewController implements Dumpable {
} }
private void updateClock() { private void updateClock() {
if (mIsDreamToLockscreenTransitionRunning) { if (mIsToLockscreenTransitionRunning) {
return; return;
} }
float alpha = mClockPositionResult.clockAlpha * mKeyguardOnlyContentAlpha; float alpha = mClockPositionResult.clockAlpha * mKeyguardOnlyContentAlpha;
@@ -2697,7 +2727,7 @@ public final class NotificationPanelViewController implements Dumpable {
} else if (statusBarState == KEYGUARD } else if (statusBarState == KEYGUARD
|| statusBarState == StatusBarState.SHADE_LOCKED) { || statusBarState == StatusBarState.SHADE_LOCKED) {
mKeyguardBottomArea.setVisibility(View.VISIBLE); mKeyguardBottomArea.setVisibility(View.VISIBLE);
if (!mIsDreamToLockscreenTransitionRunning) { if (!mIsToLockscreenTransitionRunning) {
mKeyguardBottomArea.setAlpha(1f); mKeyguardBottomArea.setAlpha(1f);
} }
} else { } else {
@@ -3566,7 +3596,7 @@ public final class NotificationPanelViewController implements Dumpable {
} }
private void updateNotificationTranslucency() { private void updateNotificationTranslucency() {
if (mIsDreamToLockscreenTransitionRunning) { if (mIsToLockscreenTransitionRunning) {
return; return;
} }
float alpha = 1f; float alpha = 1f;
@@ -3624,7 +3654,7 @@ public final class NotificationPanelViewController implements Dumpable {
} }
private void updateKeyguardBottomAreaAlpha() { private void updateKeyguardBottomAreaAlpha() {
if (mIsDreamToLockscreenTransitionRunning) { if (mIsToLockscreenTransitionRunning) {
return; return;
} }
// There are two possible panel expansion behaviors: // There are two possible panel expansion behaviors:
@@ -5856,7 +5886,7 @@ public final class NotificationPanelViewController implements Dumpable {
mCurrentPanelState = state; mCurrentPanelState = state;
} }
private Consumer<Float> dreamingToLockscreenTransitionAlpha( private Consumer<Float> toLockscreenTransitionAlpha(
NotificationStackScrollLayoutController stackScroller) { NotificationStackScrollLayoutController stackScroller) {
return (Float alpha) -> { return (Float alpha) -> {
mKeyguardStatusViewController.setAlpha(alpha); mKeyguardStatusViewController.setAlpha(alpha);
@@ -5874,7 +5904,7 @@ public final class NotificationPanelViewController implements Dumpable {
}; };
} }
private Consumer<Float> dreamingToLockscreenTransitionY( private Consumer<Float> toLockscreenTransitionY(
NotificationStackScrollLayoutController stackScroller) { NotificationStackScrollLayoutController stackScroller) {
return (Float translationY) -> { return (Float translationY) -> {
mKeyguardStatusViewController.setTranslationY(translationY, /* excludeMedia= */false); mKeyguardStatusViewController.setTranslationY(translationY, /* excludeMedia= */false);

View File

@@ -21,6 +21,8 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.lifecycle.repeatWhenAttached
import java.util.function.Consumer import java.util.function.Consumer
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
@@ -34,7 +36,10 @@ fun <T> collectFlow(
view: View, view: View,
flow: Flow<T>, flow: Flow<T>,
consumer: Consumer<T>, consumer: Consumer<T>,
coroutineContext: CoroutineContext = EmptyCoroutineContext,
state: Lifecycle.State = Lifecycle.State.CREATED, state: Lifecycle.State = Lifecycle.State.CREATED,
) { ) {
view.repeatWhenAttached { repeatOnLifecycle(state) { flow.collect { consumer.accept(it) } } } view.repeatWhenAttached(coroutineContext) {
repeatOnLifecycle(state) { flow.collect { consumer.accept(it) } }
}
} }

View File

@@ -0,0 +1,144 @@
/*
* Copyright (C) 2022 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 androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Interpolators.EMPHASIZED_DECELERATE
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.FromOccludedTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.AnimationParams
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel.Companion.LOCKSCREEN_ALPHA
import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel.Companion.LOCKSCREEN_TRANSLATION_Y
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@SmallTest
@RunWith(JUnit4::class)
class OccludedToLockscreenTransitionViewModelTest : SysuiTestCase() {
private lateinit var underTest: OccludedToLockscreenTransitionViewModel
private lateinit var repository: FakeKeyguardTransitionRepository
@Before
fun setUp() {
repository = FakeKeyguardTransitionRepository()
val interactor = KeyguardTransitionInteractor(repository)
underTest = OccludedToLockscreenTransitionViewModel(interactor)
}
@Test
fun lockscreenFadeIn() =
runTest(UnconfinedTestDispatcher()) {
val values = mutableListOf<Float>()
val job = underTest.lockscreenAlpha.onEach { values.add(it) }.launchIn(this)
repository.sendTransitionStep(step(0f))
// Should start running here...
repository.sendTransitionStep(step(0.3f))
repository.sendTransitionStep(step(0.4f))
repository.sendTransitionStep(step(0.5f))
// ...up to here
repository.sendTransitionStep(step(0.6f))
repository.sendTransitionStep(step(1f))
// Only two values should be present, since the dream overlay runs for a small fraction
// of the overall animation time
assertThat(values.size).isEqualTo(3)
assertThat(values[0]).isEqualTo(animValue(0.3f, LOCKSCREEN_ALPHA))
assertThat(values[1]).isEqualTo(animValue(0.4f, LOCKSCREEN_ALPHA))
assertThat(values[2]).isEqualTo(animValue(0.5f, LOCKSCREEN_ALPHA))
job.cancel()
}
@Test
fun lockscreenTranslationY() =
runTest(UnconfinedTestDispatcher()) {
val values = mutableListOf<Float>()
val pixels = 100
val job =
underTest.lockscreenTranslationY(pixels).onEach { values.add(it) }.launchIn(this)
repository.sendTransitionStep(step(0f))
repository.sendTransitionStep(step(0.3f))
repository.sendTransitionStep(step(0.5f))
repository.sendTransitionStep(step(1f))
assertThat(values.size).isEqualTo(4)
assertThat(values[0])
.isEqualTo(
-pixels +
EMPHASIZED_DECELERATE.getInterpolation(
animValue(0f, LOCKSCREEN_TRANSLATION_Y)
) * pixels
)
assertThat(values[1])
.isEqualTo(
-pixels +
EMPHASIZED_DECELERATE.getInterpolation(
animValue(0.3f, LOCKSCREEN_TRANSLATION_Y)
) * pixels
)
assertThat(values[2])
.isEqualTo(
-pixels +
EMPHASIZED_DECELERATE.getInterpolation(
animValue(0.5f, LOCKSCREEN_TRANSLATION_Y)
) * pixels
)
assertThat(values[3])
.isEqualTo(
-pixels +
EMPHASIZED_DECELERATE.getInterpolation(
animValue(1f, LOCKSCREEN_TRANSLATION_Y)
) * pixels
)
job.cancel()
}
private fun animValue(stepValue: Float, params: AnimationParams): Float {
val totalDuration = TO_LOCKSCREEN_DURATION
val startValue = (params.startTime / totalDuration).toFloat()
val multiplier = (totalDuration / params.duration).toFloat()
return (stepValue - startValue) * multiplier
}
private fun step(value: Float): TransitionStep {
return TransitionStep(
from = KeyguardState.OCCLUDED,
to = KeyguardState.LOCKSCREEN,
value = value,
transitionState = TransitionState.RUNNING,
ownerName = "OccludedToLockscreenTransitionViewModelTest"
)
}
}

View File

@@ -107,6 +107,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInterac
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel; import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel; import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel;
import com.android.systemui.media.controls.pipeline.MediaDataManager; import com.android.systemui.media.controls.pipeline.MediaDataManager;
import com.android.systemui.media.controls.ui.KeyguardMediaController; import com.android.systemui.media.controls.ui.KeyguardMediaController;
import com.android.systemui.media.controls.ui.MediaHierarchyManager; import com.android.systemui.media.controls.ui.MediaHierarchyManager;
@@ -188,6 +189,8 @@ import org.mockito.stubbing.Answer;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import kotlinx.coroutines.CoroutineDispatcher;
@SmallTest @SmallTest
@RunWith(AndroidTestingRunner.class) @RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper @TestableLooper.RunWithLooper
@@ -289,7 +292,9 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
@Mock private KeyguardBottomAreaViewModel mKeyguardBottomAreaViewModel; @Mock private KeyguardBottomAreaViewModel mKeyguardBottomAreaViewModel;
@Mock private KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor; @Mock private KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
@Mock private DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel; @Mock private DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel;
@Mock private OccludedToLockscreenTransitionViewModel mOccludedToLockscreenTransitionViewModel;
@Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor; @Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
@Mock private CoroutineDispatcher mMainDispatcher;
@Mock private MotionEvent mDownMotionEvent; @Mock private MotionEvent mDownMotionEvent;
@Captor @Captor
private ArgumentCaptor<NotificationStackScrollLayout.OnEmptySpaceClickListener> private ArgumentCaptor<NotificationStackScrollLayout.OnEmptySpaceClickListener>
@@ -507,6 +512,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
mKeyguardBottomAreaViewModel, mKeyguardBottomAreaViewModel,
mKeyguardBottomAreaInteractor, mKeyguardBottomAreaInteractor,
mDreamingToLockscreenTransitionViewModel, mDreamingToLockscreenTransitionViewModel,
mOccludedToLockscreenTransitionViewModel,
mMainDispatcher,
mKeyguardTransitionInteractor, mKeyguardTransitionInteractor,
mDumpManager); mDumpManager);
mNotificationPanelViewController.initDependencies( mNotificationPanelViewController.initDependencies(