Merge "[Chipbar] When animating out, always run the end runnable." into tm-qpr-dev am: fab66fdb0f

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21073589

Change-Id: I69448178466dcacae3cf2e695cf17b62eb35e032
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Caitlin Shkuratov
2023-01-25 15:30:45 +00:00
committed by Automerger Merge Worker
4 changed files with 53 additions and 97 deletions

View File

@@ -206,6 +206,10 @@ constructor(
} }
override fun animateViewIn(view: ViewGroup) { override fun animateViewIn(view: ViewGroup) {
val onAnimationEnd = Runnable {
maybeGetAccessibilityFocus(view.getTag(INFO_TAG) as ChipbarInfo?, view)
}
val added =
ViewHierarchyAnimator.animateAddition( ViewHierarchyAnimator.animateAddition(
view.getInnerView(), view.getInnerView(),
ViewHierarchyAnimator.Hotspot.TOP, ViewHierarchyAnimator.Hotspot.TOP,
@@ -214,15 +218,19 @@ constructor(
includeMargins = true, includeMargins = true,
includeFadeIn = true, includeFadeIn = true,
// We can only request focus once the animation finishes. // We can only request focus once the animation finishes.
onAnimationEnd = { onAnimationEnd = onAnimationEnd,
maybeGetAccessibilityFocus(view.getTag(INFO_TAG) as ChipbarInfo?, view)
},
) )
// If the view doesn't get animated, the [onAnimationEnd] runnable won't get run. So, just
// run it immediately.
if (!added) {
onAnimationEnd.run()
}
} }
override fun animateViewOut(view: ViewGroup, removalReason: String?, onAnimationEnd: Runnable) { override fun animateViewOut(view: ViewGroup, removalReason: String?, onAnimationEnd: Runnable) {
val innerView = view.getInnerView() val innerView = view.getInnerView()
innerView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_NONE innerView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_NONE
val removed =
ViewHierarchyAnimator.animateRemoval( ViewHierarchyAnimator.animateRemoval(
innerView, innerView,
ViewHierarchyAnimator.Hotspot.TOP, ViewHierarchyAnimator.Hotspot.TOP,
@@ -231,6 +239,11 @@ constructor(
includeMargins = true, includeMargins = true,
onAnimationEnd, onAnimationEnd,
) )
// If the view doesn't get animated, the [onAnimationEnd] runnable won't get run. So, just
// run it immediately.
if (!removed) {
onAnimationEnd.run()
}
updateGestureListening() updateGestureListening()
} }

View File

@@ -47,7 +47,6 @@ import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.temporarydisplay.TemporaryViewDisplayController import com.android.systemui.temporarydisplay.TemporaryViewDisplayController
import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
import com.android.systemui.temporarydisplay.chipbar.ChipbarLogger import com.android.systemui.temporarydisplay.chipbar.ChipbarLogger
import com.android.systemui.temporarydisplay.chipbar.FakeChipbarCoordinator
import com.android.systemui.temporarydisplay.chipbar.SwipeChipbarAwayGestureHandler import com.android.systemui.temporarydisplay.chipbar.SwipeChipbarAwayGestureHandler
import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.any
@@ -137,7 +136,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
uiEventLogger = MediaTttSenderUiEventLogger(uiEventLoggerFake) uiEventLogger = MediaTttSenderUiEventLogger(uiEventLoggerFake)
chipbarCoordinator = chipbarCoordinator =
FakeChipbarCoordinator( ChipbarCoordinator(
context, context,
chipbarLogger, chipbarLogger,
windowManager, windowManager,

View File

@@ -66,7 +66,7 @@ import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class) @RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper @TestableLooper.RunWithLooper
class ChipbarCoordinatorTest : SysuiTestCase() { class ChipbarCoordinatorTest : SysuiTestCase() {
private lateinit var underTest: FakeChipbarCoordinator private lateinit var underTest: ChipbarCoordinator
@Mock private lateinit var logger: ChipbarLogger @Mock private lateinit var logger: ChipbarLogger
@Mock private lateinit var accessibilityManager: AccessibilityManager @Mock private lateinit var accessibilityManager: AccessibilityManager
@@ -100,7 +100,7 @@ class ChipbarCoordinatorTest : SysuiTestCase() {
uiEventLoggerFake = UiEventLoggerFake() uiEventLoggerFake = UiEventLoggerFake()
underTest = underTest =
FakeChipbarCoordinator( ChipbarCoordinator(
context, context,
logger, logger,
windowManager, windowManager,
@@ -436,6 +436,23 @@ class ChipbarCoordinatorTest : SysuiTestCase() {
verify(logger).logViewUpdate(eq(WINDOW_TITLE), eq("new title text"), any()) verify(logger).logViewUpdate(eq(WINDOW_TITLE), eq("new title text"), any())
} }
/** Regression test for b/266209420. */
@Test
fun displayViewThenImmediateRemoval_viewStillRemoved() {
underTest.displayView(
createChipbarInfo(
Icon.Resource(R.drawable.ic_cake, contentDescription = null),
Text.Loaded("title text"),
endItem = ChipbarEndItem.Error,
),
)
val chipbarView = getChipbarView()
underTest.removeView(DEVICE_ID, "test reason")
verify(windowManager).removeView(chipbarView)
}
@Test @Test
fun swipeToDismiss_false_neverListensForGesture() { fun swipeToDismiss_false_neverListensForGesture() {
underTest.displayView( underTest.displayView(

View File

@@ -1,73 +0,0 @@
/*
* 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.temporarydisplay.chipbar
import android.content.Context
import android.os.PowerManager
import android.view.ViewGroup
import android.view.WindowManager
import android.view.accessibility.AccessibilityManager
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.time.SystemClock
import com.android.systemui.util.view.ViewUtil
import com.android.systemui.util.wakelock.WakeLock
/** A fake implementation of [ChipbarCoordinator] for testing. */
class FakeChipbarCoordinator(
context: Context,
logger: ChipbarLogger,
windowManager: WindowManager,
mainExecutor: DelayableExecutor,
accessibilityManager: AccessibilityManager,
configurationController: ConfigurationController,
dumpManager: DumpManager,
powerManager: PowerManager,
falsingManager: FalsingManager,
falsingCollector: FalsingCollector,
swipeChipbarAwayGestureHandler: SwipeChipbarAwayGestureHandler,
viewUtil: ViewUtil,
vibratorHelper: VibratorHelper,
wakeLockBuilder: WakeLock.Builder,
systemClock: SystemClock,
) :
ChipbarCoordinator(
context,
logger,
windowManager,
mainExecutor,
accessibilityManager,
configurationController,
dumpManager,
powerManager,
falsingManager,
falsingCollector,
swipeChipbarAwayGestureHandler,
viewUtil,
vibratorHelper,
wakeLockBuilder,
systemClock,
) {
override fun animateViewOut(view: ViewGroup, removalReason: String?, onAnimationEnd: Runnable) {
// Just bypass the animation in tests
onAnimationEnd.run()
}
}