am 95478ee7: am 1550aa97: am 73728797: Merge "Correctly handle accessibility for incoming/outgoing calls" into mnc-dev

* commit '95478ee7a7bd2f906a86bd05af47c894f0998dc7':
  Correctly handle accessibility for incoming/outgoing calls
diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java
index 413b233..fa049e7 100644
--- a/InCallUI/src/com/android/incallui/CallCardFragment.java
+++ b/InCallUI/src/com/android/incallui/CallCardFragment.java
@@ -42,6 +42,7 @@
 import android.view.ViewTreeObserver;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 import android.widget.ImageButton;
@@ -92,6 +93,13 @@
      * resetting to its previous value.
      */
     private static final long CALL_STATE_LABEL_RESET_DELAY_MS = 3000;
+    /**
+     * Amount of time to wait before sending an announcement via the accessibility manager.
+     * When the call state changes to an outgoing or incoming state for the first time, the
+     * UI can often be changing due to call updates or contact lookup. This allows the UI
+     * to settle to a stable state to ensure that the correct information is announced.
+     */
+    private static final long ACCESSIBILITY_ANNOUNCEMENT_DELAY_MS = 500;
 
     private AnimatorSet mAnimatorSet;
     private int mShrinkAnimationDuration;
@@ -628,15 +636,6 @@
         } else {
             mCallStateVideoCallIcon.setVisibility(View.GONE);
         }
-
-        if (state == Call.State.INCOMING) {
-            if (callStateLabel != null) {
-                getView().announceForAccessibility(callStateLabel.getCallStateLabel());
-            }
-            if (mPrimaryName.getText() != null) {
-                getView().announceForAccessibility(mPrimaryName.getText());
-            }
-        }
     }
 
     private void setCallStateLabel(CallStateLabel callStateLabel) {
@@ -887,9 +886,10 @@
     }
 
     public void dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+        if (event.getEventType() == AccessibilityEvent.TYPE_ANNOUNCEMENT) {
             dispatchPopulateAccessibilityEvent(event, mCallStateLabel);
             dispatchPopulateAccessibilityEvent(event, mPrimaryName);
+            dispatchPopulateAccessibilityEvent(event, mCallTypeLabel);
             dispatchPopulateAccessibilityEvent(event, mPhoneNumber);
             return;
         }
@@ -904,6 +904,21 @@
     }
 
     @Override
+    public void sendAccessibilityAnnouncement() {
+        mHandler.postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                if (getView() != null && getView().getParent() != null) {
+                    AccessibilityEvent event = AccessibilityEvent.obtain(
+                            AccessibilityEvent.TYPE_ANNOUNCEMENT);
+                    dispatchPopulateAccessibilityEvent(event);
+                    getView().getParent().requestSendAccessibilityEvent(getView(), event);
+                }
+            }
+        }, ACCESSIBILITY_ANNOUNCEMENT_DELAY_MS);
+    }
+
+    @Override
     public void setEndCallButtonEnabled(boolean enabled, boolean animate) {
         if (enabled != mFloatingActionButton.isEnabled()) {
             if (animate) {
diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java
index 6992142..0fb5b2e 100644
--- a/InCallUI/src/com/android/incallui/CallCardPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java
@@ -35,6 +35,7 @@
 import android.telecom.VideoProfile;
 import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
+import android.view.accessibility.AccessibilityManager;
 
 import com.android.incallui.ContactInfoCache.ContactCacheEntry;
 import com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
@@ -279,6 +280,8 @@
         // Hide the end call button instantly if we're receiving an incoming call.
         getUi().setEndCallButtonEnabled(shouldShowEndCallButton(mPrimary, callState),
                 callState != Call.State.INCOMING /* animate */);
+
+        maybeSendAccessibilityEvent(oldState, newState);
     }
 
     @Override
@@ -836,6 +839,23 @@
         return true;
     }
 
+    private void maybeSendAccessibilityEvent(InCallState oldState, InCallState newState) {
+        if (mContext == null) {
+            return;
+        }
+        final AccessibilityManager am = (AccessibilityManager) mContext.getSystemService(
+                Context.ACCESSIBILITY_SERVICE);
+        if (!am.isEnabled()) {
+            return;
+        }
+        if ((oldState != InCallState.OUTGOING && newState == InCallState.OUTGOING)
+                || (oldState != InCallState.INCOMING && newState == InCallState.INCOMING)) {
+            if (getUi() != null) {
+                getUi().sendAccessibilityAnnouncement();
+            }
+        }
+    }
+
     public interface CallCardUi extends Ui {
         void setVisible(boolean on);
         void setCallCardVisible(boolean visible);
@@ -859,5 +879,6 @@
         void showManageConferenceCallButton(boolean visible);
         boolean isManageConferenceVisible();
         void animateForNewOutgoingCall();
+        void sendAccessibilityAnnouncement();
     }
 }