Separated animation of status bar in split shade
This change fixes the bug where date view from status bar of notification split shade is not animated while folding and unfolding is in progress. The root cause is that the incorrect date view is being animated due to multiple views with the same ID under the same parent ViewGroup(Split shade). Hence we separated the animation of the status bar of the split shade from other views in the split shade. This allowed us to use the split shade status bar as the parent ViewGroup to correctly register the date view for animation. Test: atest com.android.systemui.shade.NotificationPanelUnfoldAnimationControllerTest Test: functional test in a follow-up cl Fixes: 277214741 Change-Id: I27d33721b1c835a51587f3865898a1e8a48f3f3c
This commit is contained in:
committed by
Shivangi Dubey
parent
644791aae4
commit
3c18f4418d
@@ -47,19 +47,36 @@ constructor(
|
||||
viewsIdToTranslate =
|
||||
setOf(
|
||||
ViewIdToTranslate(R.id.quick_settings_panel, START, filterShade),
|
||||
ViewIdToTranslate(R.id.notification_stack_scroller, END, filterShade),
|
||||
ViewIdToTranslate(R.id.statusIcons, END, filterShade),
|
||||
ViewIdToTranslate(R.id.privacy_container, END, filterShade),
|
||||
ViewIdToTranslate(R.id.batteryRemainingIcon, END, filterShade),
|
||||
ViewIdToTranslate(R.id.carrier_group, END, filterShade),
|
||||
ViewIdToTranslate(R.id.clock, START, filterShade),
|
||||
ViewIdToTranslate(R.id.date, START, filterShade)),
|
||||
ViewIdToTranslate(R.id.notification_stack_scroller, END, filterShade)),
|
||||
progressProvider = progressProvider)
|
||||
}
|
||||
|
||||
private val translateAnimatorStatusBar by lazy {
|
||||
UnfoldConstantTranslateAnimator(
|
||||
viewsIdToTranslate =
|
||||
setOf(
|
||||
ViewIdToTranslate(R.id.statusIcons, END, filterShade),
|
||||
ViewIdToTranslate(R.id.privacy_container, END, filterShade),
|
||||
ViewIdToTranslate(R.id.batteryRemainingIcon, END, filterShade),
|
||||
ViewIdToTranslate(R.id.carrier_group, END, filterShade),
|
||||
ViewIdToTranslate(R.id.clock, START, filterShade),
|
||||
ViewIdToTranslate(R.id.date, START, filterShade)
|
||||
),
|
||||
progressProvider = progressProvider
|
||||
)
|
||||
}
|
||||
|
||||
fun setup(root: ViewGroup) {
|
||||
val translationMax =
|
||||
context.resources.getDimensionPixelSize(R.dimen.notification_side_paddings).toFloat()
|
||||
translateAnimator.init(root, translationMax)
|
||||
val splitShadeStatusBarViewGroup: ViewGroup? =
|
||||
root.findViewById(R.id.split_shade_status_bar)
|
||||
if (splitShadeStatusBarViewGroup != null) {
|
||||
translateAnimatorStatusBar.init(
|
||||
splitShadeStatusBarViewGroup,
|
||||
translationMax
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.Captor
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.atLeastOnce
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@@ -54,10 +55,12 @@ class NotificationPanelUnfoldAnimationControllerTest : SysuiTestCase() {
|
||||
|
||||
@Mock private lateinit var parent: ViewGroup
|
||||
|
||||
@Mock private lateinit var splitShadeStatusBar: ViewGroup
|
||||
|
||||
@Mock private lateinit var statusBarStateController: StatusBarStateController
|
||||
|
||||
private lateinit var underTest: NotificationPanelUnfoldAnimationController
|
||||
private lateinit var progressListener: TransitionProgressListener
|
||||
private lateinit var progressListeners: List<TransitionProgressListener>
|
||||
private var xTranslationMax = 0f
|
||||
|
||||
@Before
|
||||
@@ -73,10 +76,13 @@ class NotificationPanelUnfoldAnimationControllerTest : SysuiTestCase() {
|
||||
statusBarStateController,
|
||||
progressProvider
|
||||
)
|
||||
whenever(parent.findViewById<ViewGroup>(R.id.split_shade_status_bar)).thenReturn(
|
||||
splitShadeStatusBar
|
||||
)
|
||||
underTest.setup(parent)
|
||||
|
||||
verify(progressProvider).addCallback(capture(progressListenerCaptor))
|
||||
progressListener = progressListenerCaptor.value
|
||||
verify(progressProvider, atLeastOnce()).addCallback(capture(progressListenerCaptor))
|
||||
progressListeners = progressListenerCaptor.allValues
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -86,16 +92,16 @@ class NotificationPanelUnfoldAnimationControllerTest : SysuiTestCase() {
|
||||
val view = View(context)
|
||||
whenever(parent.findViewById<View>(R.id.quick_settings_panel)).thenReturn(view)
|
||||
|
||||
progressListener.onTransitionStarted()
|
||||
onTransitionStarted()
|
||||
assertThat(view.translationX).isZero()
|
||||
|
||||
progressListener.onTransitionProgress(0f)
|
||||
onTransitionProgress(0f)
|
||||
assertThat(view.translationX).isZero()
|
||||
|
||||
progressListener.onTransitionProgress(0.5f)
|
||||
onTransitionProgress(0.5f)
|
||||
assertThat(view.translationX).isZero()
|
||||
|
||||
progressListener.onTransitionFinished()
|
||||
onTransitionFinished()
|
||||
assertThat(view.translationX).isZero()
|
||||
}
|
||||
|
||||
@@ -106,16 +112,16 @@ class NotificationPanelUnfoldAnimationControllerTest : SysuiTestCase() {
|
||||
val view = View(context)
|
||||
whenever(parent.findViewById<View>(R.id.quick_settings_panel)).thenReturn(view)
|
||||
|
||||
progressListener.onTransitionStarted()
|
||||
onTransitionStarted()
|
||||
assertThat(view.translationX).isZero()
|
||||
|
||||
progressListener.onTransitionProgress(0f)
|
||||
onTransitionProgress(0f)
|
||||
assertThat(view.translationX).isEqualTo(xTranslationMax)
|
||||
|
||||
progressListener.onTransitionProgress(0.5f)
|
||||
onTransitionProgress(0.5f)
|
||||
assertThat(view.translationX).isEqualTo(0.5f * xTranslationMax)
|
||||
|
||||
progressListener.onTransitionFinished()
|
||||
onTransitionFinished()
|
||||
assertThat(view.translationX).isZero()
|
||||
}
|
||||
|
||||
@@ -126,16 +132,88 @@ class NotificationPanelUnfoldAnimationControllerTest : SysuiTestCase() {
|
||||
val view = View(context)
|
||||
whenever(parent.findViewById<View>(R.id.quick_settings_panel)).thenReturn(view)
|
||||
|
||||
progressListener.onTransitionStarted()
|
||||
onTransitionStarted()
|
||||
assertThat(view.translationX).isZero()
|
||||
|
||||
progressListener.onTransitionProgress(0f)
|
||||
onTransitionProgress(0f)
|
||||
assertThat(view.translationX).isEqualTo(xTranslationMax)
|
||||
|
||||
progressListener.onTransitionProgress(0.5f)
|
||||
onTransitionProgress(0.5f)
|
||||
assertThat(view.translationX).isEqualTo(0.5f * xTranslationMax)
|
||||
|
||||
progressListener.onTransitionFinished()
|
||||
onTransitionFinished()
|
||||
assertThat(view.translationX).isZero()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenInKeyguardState_statusBarViewDoesNotMove() {
|
||||
whenever(statusBarStateController.getState()).thenReturn(KEYGUARD)
|
||||
|
||||
val view = View(context)
|
||||
whenever(splitShadeStatusBar.findViewById<View>(R.id.date)).thenReturn(view)
|
||||
|
||||
onTransitionStarted()
|
||||
assertThat(view.translationX).isZero()
|
||||
|
||||
onTransitionProgress(0f)
|
||||
assertThat(view.translationX).isZero()
|
||||
|
||||
onTransitionProgress(0.5f)
|
||||
assertThat(view.translationX).isZero()
|
||||
|
||||
onTransitionFinished()
|
||||
assertThat(view.translationX).isZero()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenInShadeState_statusBarViewDoesMove() {
|
||||
whenever(statusBarStateController.getState()).thenReturn(SHADE)
|
||||
|
||||
val view = View(context)
|
||||
whenever(splitShadeStatusBar.findViewById<View>(R.id.date)).thenReturn(view)
|
||||
|
||||
onTransitionStarted()
|
||||
assertThat(view.translationX).isZero()
|
||||
|
||||
onTransitionProgress(0f)
|
||||
assertThat(view.translationX).isEqualTo(xTranslationMax)
|
||||
|
||||
onTransitionProgress(0.5f)
|
||||
assertThat(view.translationX).isEqualTo(0.5f * xTranslationMax)
|
||||
|
||||
onTransitionFinished()
|
||||
assertThat(view.translationX).isZero()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenInShadeLockedState_statusBarViewDoesMove() {
|
||||
whenever(statusBarStateController.getState()).thenReturn(SHADE_LOCKED)
|
||||
|
||||
val view = View(context)
|
||||
whenever(splitShadeStatusBar.findViewById<View>(R.id.date)).thenReturn(view)
|
||||
onTransitionStarted()
|
||||
assertThat(view.translationX).isZero()
|
||||
|
||||
onTransitionProgress(0f)
|
||||
assertThat(view.translationX).isEqualTo(xTranslationMax)
|
||||
|
||||
onTransitionProgress(0.5f)
|
||||
assertThat(view.translationX).isEqualTo(0.5f * xTranslationMax)
|
||||
|
||||
onTransitionFinished()
|
||||
assertThat(view.translationX).isZero()
|
||||
}
|
||||
|
||||
private fun onTransitionStarted() {
|
||||
progressListeners.forEach { it.onTransitionStarted() }
|
||||
}
|
||||
|
||||
private fun onTransitionProgress(progress: Float) {
|
||||
progressListeners.forEach { it.onTransitionProgress(progress) }
|
||||
}
|
||||
|
||||
private fun onTransitionFinished() {
|
||||
progressListeners.forEach { it.onTransitionFinished() }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user