Bubble v2 accessibility.
Add description and action for primary button and expanded view action buttons.
Bug: 67605985
Test: manual
PiperOrigin-RevId: 178955927
Change-Id: I43ad24334cb1e1676cbc390cdba5465ded1464b5
diff --git a/java/com/android/newbubble/NewBubble.java b/java/com/android/newbubble/NewBubble.java
index 23c4411..34a9585 100644
--- a/java/com/android/newbubble/NewBubble.java
+++ b/java/com/android/newbubble/NewBubble.java
@@ -47,11 +47,14 @@
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
+import android.view.View.AccessibilityDelegate;
import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.view.ViewTreeObserver.OnPreDrawListener;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.ImageView;
@@ -228,6 +231,8 @@
if (isUserAction) {
logBasicOrCallImpression(DialerImpression.Type.BUBBLE_PRIMARY_BUTTON_EXPAND);
}
+ setPrimaryButtonAccessibilityAction(
+ context.getString(R.string.a11y_bubble_primary_button_collapse_action));
viewHolder.setDrawerVisibility(View.INVISIBLE);
View expandedView = viewHolder.getExpandedView();
expandedView
@@ -310,6 +315,8 @@
if (isUserAction && collapseEndAction == CollapseEnd.NOTHING) {
logBasicOrCallImpression(DialerImpression.Type.BUBBLE_COLLAPSE_BY_USER);
}
+ setPrimaryButtonAccessibilityAction(
+ context.getString(R.string.a11y_bubble_primary_button_expand_action));
// Animate expanded view to move from its position to above primary button and hide
collapseAnimation =
expandedView
@@ -448,6 +455,9 @@
viewHolder.setChildClickable(true);
visibility = Visibility.ENTERING;
+ setPrimaryButtonAccessibilityAction(
+ context.getString(R.string.a11y_bubble_primary_button_expand_action));
+
// Show bubble animation: scale the whole bubble to 1, and change avatar+icon's alpha to 1
ObjectAnimator scaleXAnimator =
ObjectAnimator.ofFloat(viewHolder.getPrimaryButton(), "scaleX", 1);
@@ -726,6 +736,11 @@
exitAnimatorSet.addListener(
new AnimatorListenerAdapter() {
@Override
+ public void onAnimationStart(Animator animation) {
+ viewHolder.getPrimaryButton().setAccessibilityDelegate(null);
+ }
+
+ @Override
public void onAnimationEnd(Animator animation) {
afterHiding.run();
}
@@ -793,6 +808,7 @@
button.setChecked(action.isChecked());
button.setEnabled(action.isEnabled());
button.setText(action.getName());
+ button.setContentDescription(action.getName());
button.setOnClickListener(v -> doAction(action));
}
@@ -822,6 +838,8 @@
viewHolder
.getPrimaryIcon()
.setTranslationX(isDrawingFromRight() ? -primaryIconMoveDistance : 0);
+ setPrimaryButtonAccessibilityAction(
+ context.getString(R.string.a11y_bubble_primary_button_expand_action));
update();
@@ -883,6 +901,22 @@
}
}
+ private void setPrimaryButtonAccessibilityAction(String description) {
+ viewHolder
+ .getPrimaryButton()
+ .setAccessibilityDelegate(
+ new AccessibilityDelegate() {
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(v, info);
+
+ AccessibilityAction clickAction =
+ new AccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, description);
+ info.addAction(clickAction);
+ }
+ });
+ }
+
@VisibleForTesting
class ViewHolder {
diff --git a/java/com/android/newbubble/res/layout/new_bubble_base.xml b/java/com/android/newbubble/res/layout/new_bubble_base.xml
index 8d47716..216dce0 100644
--- a/java/com/android/newbubble/res/layout/new_bubble_base.xml
+++ b/java/com/android/newbubble/res/layout/new_bubble_base.xml
@@ -38,6 +38,7 @@
android:layout_marginEnd="@dimen/bubble_shadow_padding_size_horizontal"
android:layout_marginTop="@dimen/bubble_shadow_padding_size_vertical"
android:layout_marginBottom="@dimen/bubble_shadow_padding_size_vertical"
+ android:contentDescription="@string/a11y_bubble_description"
android:background="@drawable/bubble_shape_circle"
android:measureAllChildren="false"
android:elevation="@dimen/bubble_elevation"
diff --git a/java/com/android/newbubble/res/values/strings.xml b/java/com/android/newbubble/res/values/strings.xml
new file mode 100644
index 0000000..5b82b18
--- /dev/null
+++ b/java/com/android/newbubble/res/values/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2017 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
+ -->
+
+<resources>
+ <!-- A string for Talkback to read when accessibility user touch bubble. -->
+ <string name="a11y_bubble_description">Dialer bubble</string>
+ <!-- A string to describe available action for accessibility user. It will be read as "Actions:
+ double tap to expand call action menu". -->
+ <string name="a11y_bubble_primary_button_expand_action">Expand call action menu</string>
+ <!-- A string to describe available action for accessibility user. It will be read as "Actions:
+ double tap to collapse call action menu". -->
+ <string name="a11y_bubble_primary_button_collapse_action">Collapse call action menu</string>
+</resources>
\ No newline at end of file