diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java index 8c0cfba5aea89..aa4c88af46903 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java @@ -16,6 +16,8 @@ package com.android.systemui.keyguard; +import static com.android.systemui.flags.Flags.KEYGUARD_TALKBACK_FIX; + import android.annotation.Nullable; import android.content.res.ColorStateList; import android.graphics.Color; @@ -28,6 +30,7 @@ import androidx.annotation.VisibleForTesting; import com.android.keyguard.logging.KeyguardLogger; import com.android.systemui.Dumpable; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.flags.FeatureFlags; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.KeyguardIndicationController; import com.android.systemui.statusbar.phone.KeyguardIndicationTextView; @@ -75,6 +78,7 @@ public class KeyguardIndicationRotateTextViewController extends // Executor that will show the next message after a delay private final DelayableExecutor mExecutor; + private final FeatureFlags mFeatureFlags; @VisibleForTesting @Nullable ShowNextIndication mShowNextIndicationRunnable; @@ -91,7 +95,8 @@ public class KeyguardIndicationRotateTextViewController extends KeyguardIndicationTextView view, @Main DelayableExecutor executor, StatusBarStateController statusBarStateController, - KeyguardLogger logger + KeyguardLogger logger, + FeatureFlags flags ) { super(view); mMaxAlpha = view.getAlpha(); @@ -100,12 +105,14 @@ public class KeyguardIndicationRotateTextViewController extends ? mView.getTextColors() : ColorStateList.valueOf(Color.WHITE); mStatusBarStateController = statusBarStateController; mLogger = logger; + mFeatureFlags = flags; init(); } @Override protected void onViewAttached() { mStatusBarStateController.addCallback(mStatusBarStateListener); + mView.setAlwaysAnnounceEnabled(mFeatureFlags.isEnabled(KEYGUARD_TALKBACK_FIX)); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 926d9b8072c3d..795bcadc82724 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -91,6 +91,7 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dock.DockManager; +import com.android.systemui.flags.FeatureFlags; import com.android.systemui.keyguard.KeyguardIndication; import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController; import com.android.systemui.keyguard.ScreenLifecycle; @@ -226,6 +227,7 @@ public class KeyguardIndicationController { // triggered while the device is asleep private final AlarmTimeout mHideTransientMessageHandler; private final AlarmTimeout mHideBiometricMessageHandler; + private FeatureFlags mFeatureFlags; /** * Creates a new KeyguardIndicationController and registers callbacks. @@ -256,7 +258,8 @@ public class KeyguardIndicationController { AlternateBouncerInteractor alternateBouncerInteractor, AlarmManager alarmManager, UserTracker userTracker, - BouncerMessageInteractor bouncerMessageInteractor + BouncerMessageInteractor bouncerMessageInteractor, + FeatureFlags flags ) { mContext = context; mBroadcastDispatcher = broadcastDispatcher; @@ -282,6 +285,8 @@ public class KeyguardIndicationController { mAlternateBouncerInteractor = alternateBouncerInteractor; mUserTracker = userTracker; mBouncerMessageInteractor = bouncerMessageInteractor; + mFeatureFlags = flags; + mFaceAcquiredMessageDeferral = faceHelpMessageDeferral; mCoExFaceAcquisitionMsgIdsToShow = new HashSet<>(); int[] msgIds = context.getResources().getIntArray( @@ -345,7 +350,8 @@ public class KeyguardIndicationController { mLockScreenIndicationView, mExecutor, mStatusBarStateController, - mKeyguardLogger + mKeyguardLogger, + mFeatureFlags ); updateDeviceEntryIndication(false /* animate */); updateOrganizedOwnedDevice(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java index 61c1cc82482aa..29a249fcaa415 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java @@ -51,6 +51,7 @@ public class KeyguardIndicationTextView extends TextView { private KeyguardIndication mKeyguardIndicationInfo; private Animator mLastAnimator; + private boolean mAlwaysAnnounceText; public KeyguardIndicationTextView(Context context) { super(context); @@ -103,6 +104,19 @@ public class KeyguardIndicationTextView extends TextView { switchIndication(text, indication, true, null); } + /** + * Controls whether the text displayed in the indication area will be announced always. + */ + public void setAlwaysAnnounceEnabled(boolean enabled) { + this.mAlwaysAnnounceText = enabled; + if (mAlwaysAnnounceText) { + // We will announce the text programmatically anyway. + setAccessibilityLiveRegion(ACCESSIBILITY_LIVE_REGION_NONE); + } else { + setAccessibilityLiveRegion(ACCESSIBILITY_LIVE_REGION_POLITE); + } + } + /** * Updates the text with an optional animation. * @@ -227,6 +241,9 @@ public class KeyguardIndicationTextView extends TextView { setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null); } setText(mMessage); + if (mAlwaysAnnounceText) { + announceForAccessibility(mMessage); + } } private AnimatorSet getInAnimator() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java index d934f761f7c52..39fcd417ec7af 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java @@ -17,6 +17,7 @@ package com.android.systemui.keyguard; +import static com.android.systemui.flags.Flags.KEYGUARD_TALKBACK_FIX; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BIOMETRIC_MESSAGE; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_DISCLOSURE; @@ -42,6 +43,7 @@ import androidx.test.filters.SmallTest; import com.android.keyguard.logging.KeyguardLogger; import com.android.systemui.SysuiTestCase; +import com.android.systemui.flags.FakeFeatureFlags; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.phone.KeyguardIndicationTextView; import com.android.systemui.util.concurrency.DelayableExecutor; @@ -81,8 +83,10 @@ public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCas public void setUp() throws Exception { MockitoAnnotations.initMocks(this); when(mView.getTextColors()).thenReturn(ColorStateList.valueOf(Color.WHITE)); + FakeFeatureFlags flags = new FakeFeatureFlags(); + flags.set(KEYGUARD_TALKBACK_FIX, true); mController = new KeyguardIndicationRotateTextViewController(mView, mExecutor, - mStatusBarStateController, mLogger); + mStatusBarStateController, mLogger, flags); mController.onViewAttached(); verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java index 01572f266e39d..48c3e2d855749 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java @@ -26,6 +26,7 @@ import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIME import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_AVAILABLE; import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED; +import static com.android.systemui.flags.Flags.KEYGUARD_TALKBACK_FIX; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BIOMETRIC_MESSAGE; @@ -99,6 +100,7 @@ import com.android.systemui.biometrics.AuthController; import com.android.systemui.biometrics.FaceHelpMessageDeferral; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dock.DockManager; +import com.android.systemui.flags.FakeFeatureFlags; import com.android.systemui.keyguard.KeyguardIndication; import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController; import com.android.systemui.keyguard.ScreenLifecycle; @@ -286,6 +288,8 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { Looper.prepare(); } + FakeFeatureFlags flags = new FakeFeatureFlags(); + flags.set(KEYGUARD_TALKBACK_FIX, true); mController = new KeyguardIndicationController( mContext, mTestableLooper.getLooper(), @@ -299,7 +303,8 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { mAlternateBouncerInteractor, mAlarmManager, mUserTracker, - mock(BouncerMessageInteractor.class) + mock(BouncerMessageInteractor.class), + flags ); mController.init(); mController.setIndicationArea(mIndicationArea); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java index 6068f0d17720c..5cea931e20705 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java @@ -16,6 +16,9 @@ package com.android.systemui.statusbar.phone; +import static android.view.View.ACCESSIBILITY_LIVE_REGION_NONE; +import static android.view.View.ACCESSIBILITY_LIVE_REGION_POLITE; + import static com.google.common.truth.Truth.assertThat; import android.testing.AndroidTestingRunner; @@ -56,6 +59,22 @@ public class KeyguardIndicationTextViewTest extends SysuiTestCase { assertThat(mKeyguardIndicationTextView.getText()).isEqualTo(""); } + @Test + public void alwaysAnnounce_setsLiveRegionToNone() { + mKeyguardIndicationTextView.setAlwaysAnnounceEnabled(true); + + assertThat(mKeyguardIndicationTextView.getAccessibilityLiveRegion()).isEqualTo( + ACCESSIBILITY_LIVE_REGION_NONE); + } + + @Test + public void alwaysAnnounce_setsLiveRegionToDefaultPolite_whenDisabled() { + mKeyguardIndicationTextView.setAlwaysAnnounceEnabled(false); + + assertThat(mKeyguardIndicationTextView.getAccessibilityLiveRegion()).isEqualTo( + ACCESSIBILITY_LIVE_REGION_POLITE); + } + @Test public void switchIndication_emptyText_hideIndication() { mKeyguardIndicationTextView.switchIndication("" /* text */, null);