Fixed some issues in dialer's dialpad for talkback users.

 - Content description for voicemail button is now "1... double tap and hold to
 call vociemail"
 - Content description for 0 button is now "0... double tap and hold for plus
 symbol"

Bug: 19621015,62712616
Test: manual + a11y office hours
PiperOrigin-RevId: 191673375
Change-Id: I9b5d8d875f1bf218be6fcc33dff4ac9e479e4f43
diff --git a/java/com/android/dialer/dialpadview/DialpadFragment.java b/java/com/android/dialer/dialpadview/DialpadFragment.java
index 6f8d677..9d88d8e 100644
--- a/java/com/android/dialer/dialpadview/DialpadFragment.java
+++ b/java/com/android/dialer/dialpadview/DialpadFragment.java
@@ -1050,9 +1050,15 @@
       digits.clear();
       return true;
     } else if (id == R.id.one) {
-      if (isDigitsEmpty() || TextUtils.equals(this.digits.getText(), "1")) {
+      // For non-talkback users: check for empty
+      // For linear navigation users: check for "1"
+      // For explore by touch users: check for "11"
+      if (isDigitsEmpty()
+          || TextUtils.equals(this.digits.getText(), "1")
+          || TextUtils.equals(this.digits.getText(), "11")) {
         // We'll try to initiate voicemail and thus we want to remove irrelevant string.
         removePreviousDigitIfPossible('1');
+        removePreviousDigitIfPossible('1');
 
         List<PhoneAccountHandle> subscriptionAccountHandles =
             TelecomUtil.getSubscriptionPhoneAccounts(getActivity());
@@ -1094,6 +1100,7 @@
         // (and not via other means like certain accessibility input methods).
         // Remove the '0' that was input when the key was first pressed.
         removePreviousDigitIfPossible('0');
+        removePreviousDigitIfPossible('0');
       }
       keyPressed(KeyEvent.KEYCODE_PLUS);
       stopTone();
diff --git a/java/com/android/dialer/dialpadview/DialpadKeyButton.java b/java/com/android/dialer/dialpadview/DialpadKeyButton.java
index 84aca14..47553b6 100644
--- a/java/com/android/dialer/dialpadview/DialpadKeyButton.java
+++ b/java/com/android/dialer/dialpadview/DialpadKeyButton.java
@@ -19,13 +19,14 @@
 import android.content.Context;
 import android.graphics.RectF;
 import android.os.Bundle;
+import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewConfiguration;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.widget.FrameLayout;
 
 /**
@@ -45,33 +46,21 @@
  */
 public class DialpadKeyButton extends FrameLayout {
 
-  /** Timeout before switching to long-click accessibility mode. */
-  private static final int LONG_HOVER_TIMEOUT = ViewConfiguration.getLongPressTimeout() * 2;
-
   /** Accessibility manager instance used to check touch exploration state. */
   private AccessibilityManager accessibilityManager;
 
   /** Bounds used to filter HOVER_EXIT events. */
   private RectF hoverBounds = new RectF();
 
-  /** Whether this view is currently in the long-hover state. */
-  private boolean longHovered;
-
   /** Alternate content description for long-hover state. */
   private CharSequence longHoverContentDesc;
 
-  /** Backup of standard content description. Used for accessibility. */
-  private CharSequence backupContentDesc;
-
   /** Backup of clickable property. Used for accessibility. */
   private boolean wasClickable;
 
   /** Backup of long-clickable property. Used for accessibility. */
   private boolean wasLongClickable;
 
-  /** Runnable used to trigger long-click mode for accessibility. */
-  private Runnable longHoverRunnable;
-
   private OnPressedListener onPressedListener;
 
   public DialpadKeyButton(Context context, AttributeSet attrs) {
@@ -95,19 +84,6 @@
 
   public void setLongHoverContentDescription(CharSequence contentDescription) {
     longHoverContentDesc = contentDescription;
-
-    if (longHovered) {
-      super.setContentDescription(longHoverContentDesc);
-    }
-  }
-
-  @Override
-  public void setContentDescription(CharSequence contentDescription) {
-    if (longHovered) {
-      backupContentDesc = contentDescription;
-    } else {
-      super.setContentDescription(contentDescription);
-    }
   }
 
   @Override
@@ -139,6 +115,18 @@
   }
 
   @Override
+  public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+    super.onInitializeAccessibilityNodeInfo(info);
+    // If the button has a long hover description, ask talkback to announce the action follow by
+    // the description (for example "double tap and hold to call voicemail").
+    if (!TextUtils.isEmpty(longHoverContentDesc)) {
+      AccessibilityAction longClickAction =
+          new AccessibilityAction(AccessibilityNodeInfo.ACTION_LONG_CLICK, longHoverContentDesc);
+      info.addAction(longClickAction);
+    }
+  }
+
+  @Override
   public boolean onHoverEvent(MotionEvent event) {
     // When touch exploration is turned on, lifting a finger while inside
     // the button's hover target bounds should perform a click action.
@@ -148,20 +136,6 @@
           // Lift-to-type temporarily disables double-tap activation.
           wasClickable = isClickable();
           wasLongClickable = isLongClickable();
-          if (wasLongClickable && longHoverContentDesc != null) {
-            if (longHoverRunnable == null) {
-              longHoverRunnable =
-                  new Runnable() {
-                    @Override
-                    public void run() {
-                      setLongHovered(true);
-                      announceForAccessibility(longHoverContentDesc);
-                    }
-                  };
-            }
-            postDelayed(longHoverRunnable, LONG_HOVER_TIMEOUT);
-          }
-
           setClickable(false);
           setLongClickable(false);
           break;
@@ -170,7 +144,6 @@
             simulateClickForAccessibility();
           }
 
-          cancelLongHover();
           setClickable(wasClickable);
           setLongClickable(wasLongClickable);
           break;
@@ -201,27 +174,6 @@
     setPressed(false);
   }
 
-  private void setLongHovered(boolean enabled) {
-    if (longHovered != enabled) {
-      longHovered = enabled;
-
-      // Switch between normal and alternate description, if available.
-      if (enabled) {
-        backupContentDesc = getContentDescription();
-        super.setContentDescription(longHoverContentDesc);
-      } else {
-        super.setContentDescription(backupContentDesc);
-      }
-    }
-  }
-
-  private void cancelLongHover() {
-    if (longHoverRunnable != null) {
-      removeCallbacks(longHoverRunnable);
-    }
-    setLongHovered(false);
-  }
-
   public interface OnPressedListener {
 
     void onPressed(View view, boolean pressed);
diff --git a/java/com/android/dialer/dialpadview/DialpadView.java b/java/com/android/dialer/dialpadview/DialpadView.java
index 0369b40..6d538f3 100644
--- a/java/com/android/dialer/dialpadview/DialpadView.java
+++ b/java/com/android/dialer/dialpadview/DialpadView.java
@@ -171,6 +171,9 @@
       } else if (BUTTON_IDS[i] == R.id.star) {
         numberString = resources.getString(R.string.dialpad_star_number);
         numberContentDescription = numberString;
+      } else if (BUTTON_IDS[i] == R.id.zero) {
+        numberString = numberFormat.format(i);
+        numberContentDescription = numberString;
       } else {
         numberString = numberFormat.format(i);
         // The content description is used for Talkback key presses. The number is
diff --git a/java/com/android/dialer/dialpadview/res/values/strings.xml b/java/com/android/dialer/dialpadview/res/values/strings.xml
index 5d8d8e6..eb5c04f 100644
--- a/java/com/android/dialer/dialpadview/res/values/strings.xml
+++ b/java/com/android/dialer/dialpadview/res/values/strings.xml
@@ -30,12 +30,12 @@
   <string name="description_delete_button">backspace</string>
 
   <!--  String describing the button used to add a plus (+) symbol to the dialpad -->
-  <string name="description_image_button_plus">plus</string>
+  <string name="description_image_button_plus">dial plus</string>
 
   <!-- String describing the Voicemail ImageButton.
        Used by AccessibilityService to announce the purpose of the button.
   -->
-  <string name="description_voicemail_button">voicemail</string>
+  <string name="description_voicemail_button">call voicemail</string>
 
   <!-- String describing the Dial ImageButton