From 2e59268f3bb62c2affe826a4f1cd10322c175704 Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Tue, 13 Aug 2024 16:50:15 -0700 Subject: [PATCH] Add a contentDescription to splitscreen's first staged task Currently, when we stage the first app in a split, the floatingTaskView has no contentDescription and is announced by screen readers as "unlabeled". This CL allows FloatingTaskView to copy a contentDescription from the underlying task or ItemInfo when it is created. Also changes SplitConfigurationOptions#itemInfo to a private field with a public getter for mockito compatibility. Fixes: 319783133 Test: Confirmed with TalkBack on Overview, contextual and Intent splits Flag: EXEMPT bugfix Change-Id: Ia5a95e403bfe8623e17d2ceac9073ef15c7bb476 --- .../launcher3/taskbar/TaskbarUIController.java | 2 +- .../launcher3/uioverrides/QuickstepLauncher.java | 6 ++++-- .../quickstep/util/SplitAnimationController.kt | 12 ++++++++---- .../src/com/android/quickstep/views/RecentsView.java | 3 ++- .../quickstep/util/SplitAnimationControllerTest.kt | 4 ++++ .../launcher3/util/SplitConfigurationOptions.java | 6 +++++- 6 files changed, 24 insertions(+), 9 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java index 42bf8db7df..112863e417 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java @@ -232,7 +232,7 @@ public class TaskbarUIController { } recentsView.getSplitSelectController().findLastActiveTasksAndRunCallback( - Collections.singletonList(splitSelectSource.itemInfo.getComponentKey()), + Collections.singletonList(splitSelectSource.getItemInfo().getComponentKey()), false /* findExactPairMatch */, foundTasks -> { @Nullable Task foundTask = foundTasks[0]; diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index c3d37292a7..8cabab3a42 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -729,7 +729,7 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer, // Check if there is already an instance of this app running, if so, initiate the split // using that. mSplitSelectStateController.findLastActiveTasksAndRunCallback( - Collections.singletonList(splitSelectSource.itemInfo.getComponentKey()), + Collections.singletonList(splitSelectSource.getItemInfo().getComponentKey()), false /* findExactPairMatch */, foundTasks -> { @Nullable Task foundTask = foundTasks[0]; @@ -756,7 +756,7 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer, Rect tempRect = new Rect(); mSplitSelectStateController.setInitialTaskSelect(source.intent, - source.position.stagePosition, source.itemInfo, source.splitEvent, + source.position.stagePosition, source.getItemInfo(), source.splitEvent, source.alreadyRunningTaskId); RecentsView recentsView = getOverviewPanel(); @@ -774,6 +774,8 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer, floatingTaskView.setOnClickListener(view -> mSplitSelectStateController.getSplitAnimationController(). playAnimPlaceholderToFullscreen(this, view, Optional.empty())); + floatingTaskView.setContentDescription(source.getItemInfo().contentDescription); + mSplitSelectStateController.setFirstFloatingTaskView(floatingTaskView); anim.addListener(new AnimatorListenerAdapter() { @Override diff --git a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt index 0335fa13b8..fa5a67a7e6 100644 --- a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt +++ b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt @@ -91,7 +91,8 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC val iconDrawable: Drawable, val fadeWithThumbnail: Boolean, val isStagedTask: Boolean, - val iconView: View? + val iconView: View?, + val contentDescription: CharSequence? ) } @@ -112,7 +113,8 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC splitSelectSource.drawable, fadeWithThumbnail = false, isStagedTask = true, - iconView = null + iconView = null, + splitSelectSource.itemInfo.contentDescription ) } else if (splitSelectStateController.isDismissingFromSplitPair) { // Initiating split from overview, but on a split pair @@ -126,7 +128,8 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC drawable, fadeWithThumbnail = true, isStagedTask = true, - iconView = container.iconView.asView() + iconView = container.iconView.asView(), + container.task.titleDescription ) } } @@ -145,7 +148,8 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC drawable, fadeWithThumbnail = true, isStagedTask = true, - iconView = it.iconView.asView() + iconView = it.iconView.asView(), + it.task.titleDescription ) } } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 5a6c278118..d35015ef05 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -3447,6 +3447,7 @@ public abstract class RecentsView resetFromSplitSelectionState()))); + firstFloatingTaskView.setContentDescription(splitAnimInitProps.getContentDescription()); // SplitInstructionsView: animate in safeRemoveDragLayerView(mSplitSelectStateController.getSplitInstructionsView()); @@ -4880,7 +4881,7 @@ public abstract class RecentsView = mock() private val depthController: DepthController = mock() @@ -89,11 +91,13 @@ class SplitAnimationControllerTest { whenever(mockTaskContainer.snapshotView).thenReturn(mockSnapshotView) whenever(mockTaskContainer.splitAnimationThumbnail).thenReturn(mockBitmap) whenever(mockTaskContainer.iconView).thenReturn(mockIconView) + whenever(mockTaskContainer.task).thenReturn(mockTask) whenever(mockIconView.drawable).thenReturn(mockTaskViewDrawable) whenever(mockTaskView.taskContainers).thenReturn(List(1) { mockTaskContainer }) whenever(splitSelectSource.drawable).thenReturn(mockSplitSourceDrawable) whenever(splitSelectSource.view).thenReturn(mockSplitSourceView) + whenever(splitSelectSource.itemInfo).thenReturn(mockItemInfo) splitAnimationController = SplitAnimationController(mockSplitSelectStateController) } diff --git a/src/com/android/launcher3/util/SplitConfigurationOptions.java b/src/com/android/launcher3/util/SplitConfigurationOptions.java index 837d7bc04d..f457e4e369 100644 --- a/src/com/android/launcher3/util/SplitConfigurationOptions.java +++ b/src/com/android/launcher3/util/SplitConfigurationOptions.java @@ -211,7 +211,7 @@ public final class SplitConfigurationOptions { private Drawable drawable; public final Intent intent; public final SplitPositionOption position; - public final ItemInfo itemInfo; + private ItemInfo itemInfo; public final StatsLogManager.EventEnum splitEvent; /** Represents the taskId of the first app to start in split screen */ public int alreadyRunningTaskId = INVALID_TASK_ID; @@ -239,5 +239,9 @@ public final class SplitConfigurationOptions { public View getView() { return view; } + + public ItemInfo getItemInfo() { + return itemInfo; + } } }