/* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.keyguard import android.testing.AndroidTestingRunner import android.view.View import android.view.ViewGroup import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardUnfoldTransition.Companion.LEFT import com.android.keyguard.KeyguardUnfoldTransition.Companion.RIGHT import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider import com.android.systemui.util.mockito.capture import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.Captor import org.mockito.Mock import org.mockito.MockitoAnnotations import org.mockito.Mockito.`when` import org.mockito.Mockito.verify /** * Translates items away/towards the hinge when the device is opened/closed. This is controlled by * the set of ids, which also dictact which direction to move and when, via a filter fn. */ @SmallTest @RunWith(AndroidTestingRunner::class) class KeyguardUnfoldTransitionTest : SysuiTestCase() { @Mock private lateinit var progressProvider: NaturalRotationUnfoldProgressProvider @Captor private lateinit var progressListenerCaptor: ArgumentCaptor @Mock private lateinit var parent: ViewGroup private lateinit var keyguardUnfoldTransition: KeyguardUnfoldTransition private lateinit var progressListener: TransitionProgressListener private var xTranslationMax = 0f @Before fun setup() { MockitoAnnotations.initMocks(this) xTranslationMax = context.resources.getDimensionPixelSize( R.dimen.keyguard_unfold_translation_x).toFloat() keyguardUnfoldTransition = KeyguardUnfoldTransition( getContext(), progressProvider ) verify(progressProvider).addCallback(capture(progressListenerCaptor)) progressListener = progressListenerCaptor.value keyguardUnfoldTransition.setup(parent) keyguardUnfoldTransition.statusViewCentered = false } @Test fun onTransition_noMatchingIds() { // GIVEN no views matching any ids // WHEN the transition starts progressListener.onTransitionStarted() progressListener.onTransitionProgress(.1f) // THEN nothing... no exceptions } @Test fun onTransition_oneMovesLeft() { // GIVEN one view with a matching id val view = View(getContext()) `when`(parent.findViewById(R.id.keyguard_status_area)).thenReturn(view) moveAndValidate(listOf(view to LEFT)) } @Test fun onTransition_oneMovesLeftAndOneMovesRightMultipleTimes() { // GIVEN two views with a matching id val leftView = View(getContext()) val rightView = View(getContext()) `when`(parent.findViewById(R.id.keyguard_status_area)).thenReturn(leftView) `when`(parent.findViewById(R.id.notification_stack_scroller)).thenReturn(rightView) moveAndValidate(listOf(leftView to LEFT, rightView to RIGHT)) moveAndValidate(listOf(leftView to LEFT, rightView to RIGHT)) } @Test fun onTransition_centeredViewDoesNotMove() { keyguardUnfoldTransition.statusViewCentered = true val view = View(getContext()) `when`(parent.findViewById(R.id.lockscreen_clock_view_large)).thenReturn(view) moveAndValidate(listOf(view to 0)) } private fun moveAndValidate(list: List>) { // Compare values as ints because -0f != 0f // WHEN the transition starts progressListener.onTransitionStarted() progressListener.onTransitionProgress(0f) list.forEach { (view, direction) -> assertEquals((-xTranslationMax * direction).toInt(), view.getTranslationX().toInt()) } // WHEN the transition progresses, translation is updated progressListener.onTransitionProgress(.5f) list.forEach { (view, direction) -> assertEquals( (-xTranslationMax / 2f * direction).toInt(), view.getTranslationX().toInt() ) } // WHEN the transition ends, translation is completed progressListener.onTransitionProgress(1f) progressListener.onTransitionFinished() list.forEach { (view, _) -> assertEquals(0, view.getTranslationX().toInt()) } } }