Merge changes from topic "bubblebar-a11y" into main

* changes:
  Move bubble bar strings
  Add content description to bubble bar and bubbles
This commit is contained in:
Ats Jenk
2024-06-05 19:04:22 +00:00
committed by Android (Google) Code Review
5 changed files with 70 additions and 5 deletions
+10
View File
@@ -332,4 +332,14 @@
<!-- Accessibility label for quick switch tiles showing split tasks [CHAR LIMIT=NONE] -->
<string name="quick_switch_split_task"><xliff:g id="app_name_1" example="Chrome">%1$s</xliff:g> and <xliff:g id="app_name_2" example="Gmail">%2$s</xliff:g></string>
<!-- Strings for bubble bar -->
<!-- Fallback name for a bubble if it does have a title [CHAR_LIMIT=none] -->
<string name="bubble_bar_bubble_fallback_description">Bubble</string>
<!-- content description for the overflow bubble [CHAR_LIMIT=none] -->
<string name="bubble_bar_overflow_description">Overflow</string>
<!-- Content description for a bubble bar bubble. [CHAR_LIMIT=none] -->
<string name="bubble_bar_bubble_description"><xliff:g id="notification_title" example="some title">%1$s</xliff:g> from <xliff:g id="app_name" example="YouTube">%2$s</xliff:g></string>
<!-- Content description for bubble bar when it has multiple bubbles. [CHAR_LIMIT=NONE] -->
<string name="bubble_bar_description_multiple_bubbles"><xliff:g id="bubble_bar_bubble_description" example="some title from YouTube">%1$s</xliff:g> and <xliff:g id="bubble_count" example="4">%2$d</xliff:g> more</string>
</resources>
@@ -623,6 +623,8 @@ public class BubbleBarView extends FrameLayout {
}
super.addView(child, index, params);
updateWidth();
updateBubbleAccessibilityStates();
updateContentDescription();
}
// TODO: (b/283309949) animate it
@@ -634,6 +636,8 @@ public class BubbleBarView extends FrameLayout {
mBubbleBarBackground.showArrow(false);
}
updateWidth();
updateBubbleAccessibilityStates();
updateContentDescription();
}
private void updateWidth() {
@@ -799,6 +803,7 @@ public class BubbleBarView extends FrameLayout {
}
}
updateChildrenRenderNodeProperties(mBubbleBarLocation);
updateContentDescription();
}
}
@@ -927,6 +932,7 @@ public class BubbleBarView extends FrameLayout {
} else {
mWidthAnimator.reverse();
}
updateBubbleAccessibilityStates();
}
}
@@ -998,6 +1004,47 @@ public class BubbleBarView extends FrameLayout {
return mIsAnimatingNewBubble;
}
private boolean hasOverview() {
// Overview is always the last bubble
View lastChild = getChildAt(getChildCount() - 1);
if (lastChild instanceof BubbleView bubbleView) {
return bubbleView.getBubble() instanceof BubbleBarOverflow;
}
return false;
}
private void updateBubbleAccessibilityStates() {
final int childA11y;
if (mIsBarExpanded) {
// Bar is expanded, focus on the bubbles
setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
childA11y = View.IMPORTANT_FOR_ACCESSIBILITY_YES;
} else {
// Bar is collapsed, only focus on the bar
setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
childA11y = View.IMPORTANT_FOR_ACCESSIBILITY_NO;
}
for (int i = 0; i < getChildCount(); i++) {
getChildAt(i).setImportantForAccessibility(childA11y);
// Only allowing focusing on bubbles when bar is expanded. Otherwise, in talkback mode,
// bubbles can be navigates to in collapsed mode.
getChildAt(i).setFocusable(mIsBarExpanded);
}
}
private void updateContentDescription() {
View firstChild = getChildAt(0);
CharSequence contentDesc = firstChild != null ? firstChild.getContentDescription() : "";
// Don't count overflow if it exists
int bubbleCount = getChildCount() - (hasOverview() ? 1 : 0);
if (bubbleCount > 1) {
contentDesc = getResources().getString(R.string.bubble_bar_description_multiple_bubbles,
contentDesc, bubbleCount - 1);
}
setContentDescription(contentDesc);
}
/** Interface for BubbleBarView to communicate with its controller. */
interface Controller {
@@ -21,6 +21,7 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Outline;
import android.graphics.Rect;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -187,6 +188,16 @@ public class BubbleView extends ConstraintLayout {
mAppIcon.setImageBitmap(bubble.getBadge());
mDotColor = bubble.getDotColor();
mDotRenderer = new DotRenderer(mBubbleSize, bubble.getDotPath(), DEFAULT_PATH_SIZE);
String contentDesc = bubble.getInfo().getTitle();
if (TextUtils.isEmpty(contentDesc)) {
contentDesc = getResources().getString(R.string.bubble_bar_bubble_fallback_description);
}
String appName = bubble.getInfo().getAppName();
if (!TextUtils.isEmpty(appName)) {
contentDesc = getResources().getString(R.string.bubble_bar_bubble_description,
contentDesc, appName);
}
setContentDescription(contentDesc);
}
/**
@@ -392,7 +392,8 @@ class BubbleBarViewAnimatorTest {
overflowView.setOverflow(BubbleBarOverflow(overflowView), bitmap)
bubbleBarView.addView(overflowView)
val bubbleInfo = BubbleInfo("key", 0, null, null, 0, context.packageName, null, false)
val bubbleInfo =
BubbleInfo("key", 0, null, null, 0, context.packageName, null, null, false)
bubbleView =
inflater.inflate(R.layout.bubblebar_item_view, bubbleBarView, false) as BubbleView
bubble =
-4
View File
@@ -498,8 +498,4 @@
<string name="ps_add_button_label">Install</string>
<!-- Content description for install app icon -->
<string name="ps_add_button_content_description">Install apps to Private Space</string>
<!-- Strings for bubble bar -->
<!-- content description for the overflow bubble [CHAR_LIMIT=none] -->
<string name="bubble_bar_overflow_description">Overflow</string>
</resources>