Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0dbdccd2 authored by Yorke Lee's avatar Yorke Lee
Browse files

Correctly handle accessibility for incoming/outgoing calls

The previous behavior relied on WINDOW_STATE_CHANGED events to
announce outgoing/incoming calls, at which point in time
the CallCardFragment was not guaranteed to be non-null.

Bug: 20172391
Change-Id: I65bf86bc1a5edf5430ae5aabcb3535f42d1ccb08
parent 1e0585f3
Loading
Loading
Loading
Loading
+25 −10
Original line number Original line Diff line number Diff line
@@ -42,6 +42,7 @@ import android.view.ViewPropertyAnimator;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.Animation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.AnimationUtils;
import android.widget.ImageButton;
import android.widget.ImageButton;
@@ -92,6 +93,13 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
     * resetting to its previous value.
     * resetting to its previous value.
     */
     */
    private static final long CALL_STATE_LABEL_RESET_DELAY_MS = 3000;
    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 AnimatorSet mAnimatorSet;
    private int mShrinkAnimationDuration;
    private int mShrinkAnimationDuration;
@@ -604,15 +612,6 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
        } else {
        } else {
            mCallStateVideoCallIcon.setVisibility(View.GONE);
            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) {
    private void setCallStateLabel(CallStateLabel callStateLabel) {
@@ -861,9 +860,10 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
    }
    }


    public void dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
    public void dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
        if (event.getEventType() == AccessibilityEvent.TYPE_ANNOUNCEMENT) {
            dispatchPopulateAccessibilityEvent(event, mCallStateLabel);
            dispatchPopulateAccessibilityEvent(event, mCallStateLabel);
            dispatchPopulateAccessibilityEvent(event, mPrimaryName);
            dispatchPopulateAccessibilityEvent(event, mPrimaryName);
            dispatchPopulateAccessibilityEvent(event, mCallTypeLabel);
            dispatchPopulateAccessibilityEvent(event, mPhoneNumber);
            dispatchPopulateAccessibilityEvent(event, mPhoneNumber);
            return;
            return;
        }
        }
@@ -877,6 +877,21 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
        return;
        return;
    }
    }


    @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
    @Override
    public void setEndCallButtonEnabled(boolean enabled, boolean animate) {
    public void setEndCallButtonEnabled(boolean enabled, boolean animate) {
        if (enabled != mFloatingActionButton.isEnabled()) {
        if (enabled != mFloatingActionButton.isEnabled()) {
+21 −0
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@ import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import android.telecom.VideoProfile;
import android.telephony.PhoneNumberUtils;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.text.TextUtils;
import android.view.accessibility.AccessibilityManager;


import com.android.incallui.ContactInfoCache.ContactCacheEntry;
import com.android.incallui.ContactInfoCache.ContactCacheEntry;
import com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
import com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
@@ -279,6 +280,8 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
        // Hide the end call button instantly if we're receiving an incoming call.
        // Hide the end call button instantly if we're receiving an incoming call.
        getUi().setEndCallButtonEnabled(shouldShowEndCallButton(mPrimary, callState),
        getUi().setEndCallButtonEnabled(shouldShowEndCallButton(mPrimary, callState),
                callState != Call.State.INCOMING /* animate */);
                callState != Call.State.INCOMING /* animate */);

        maybeSendAccessibilityEvent(oldState, newState);
    }
    }


    @Override
    @Override
@@ -828,6 +831,23 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
        return true;
        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 {
    public interface CallCardUi extends Ui {
        void setVisible(boolean on);
        void setVisible(boolean on);
        void setCallCardVisible(boolean visible);
        void setCallCardVisible(boolean visible);
@@ -851,5 +871,6 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
        void showManageConferenceCallButton(boolean visible);
        void showManageConferenceCallButton(boolean visible);
        boolean isManageConferenceVisible();
        boolean isManageConferenceVisible();
        void animateForNewOutgoingCall();
        void animateForNewOutgoingCall();
        void sendAccessibilityAnnouncement();
    }
    }
}
}