Provide an option in KeyguardIndicationTextView to always announce the text being displayed

Fixes: 281765653
Test: verified manually
  1. flip the flag on
  2. enroll face and fp
  3. enable talkback on
  4. go to lockscreen
  5. try incorrect fingerprint
  6. cover face and try face unlock
  7. plug in charger and unplug charger
  8. try incorrect face
  9. face unlock unsuccessfully
  10.slightly touch udfps to show the press firmly on sensor message
  11.all the messages in the keyguard indication area must be read out loud even if it happens within a period of 30seconds.
Change-Id: I8e8328cc133ca126c3eb40c0623e1dfc0eafbb04
This commit is contained in:
Chandru S
2023-06-09 11:41:55 -07:00
parent 52fcb00a7d
commit 4ffe0d602d
6 changed files with 63 additions and 5 deletions

View File

@@ -16,6 +16,8 @@
package com.android.systemui.keyguard; package com.android.systemui.keyguard;
import static com.android.systemui.flags.Flags.KEYGUARD_TALKBACK_FIX;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.graphics.Color; import android.graphics.Color;
@@ -28,6 +30,7 @@ import androidx.annotation.VisibleForTesting;
import com.android.keyguard.logging.KeyguardLogger; import com.android.keyguard.logging.KeyguardLogger;
import com.android.systemui.Dumpable; import com.android.systemui.Dumpable;
import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.KeyguardIndicationController; import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView; 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 // Executor that will show the next message after a delay
private final DelayableExecutor mExecutor; private final DelayableExecutor mExecutor;
private final FeatureFlags mFeatureFlags;
@VisibleForTesting @VisibleForTesting
@Nullable ShowNextIndication mShowNextIndicationRunnable; @Nullable ShowNextIndication mShowNextIndicationRunnable;
@@ -91,7 +95,8 @@ public class KeyguardIndicationRotateTextViewController extends
KeyguardIndicationTextView view, KeyguardIndicationTextView view,
@Main DelayableExecutor executor, @Main DelayableExecutor executor,
StatusBarStateController statusBarStateController, StatusBarStateController statusBarStateController,
KeyguardLogger logger KeyguardLogger logger,
FeatureFlags flags
) { ) {
super(view); super(view);
mMaxAlpha = view.getAlpha(); mMaxAlpha = view.getAlpha();
@@ -100,12 +105,14 @@ public class KeyguardIndicationRotateTextViewController extends
? mView.getTextColors() : ColorStateList.valueOf(Color.WHITE); ? mView.getTextColors() : ColorStateList.valueOf(Color.WHITE);
mStatusBarStateController = statusBarStateController; mStatusBarStateController = statusBarStateController;
mLogger = logger; mLogger = logger;
mFeatureFlags = flags;
init(); init();
} }
@Override @Override
protected void onViewAttached() { protected void onViewAttached() {
mStatusBarStateController.addCallback(mStatusBarStateListener); mStatusBarStateController.addCallback(mStatusBarStateListener);
mView.setAlwaysAnnounceEnabled(mFeatureFlags.isEnabled(KEYGUARD_TALKBACK_FIX));
} }
@Override @Override

View File

@@ -91,6 +91,7 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.keyguard.KeyguardIndication; import com.android.systemui.keyguard.KeyguardIndication;
import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController; import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.ScreenLifecycle;
@@ -226,6 +227,7 @@ public class KeyguardIndicationController {
// triggered while the device is asleep // triggered while the device is asleep
private final AlarmTimeout mHideTransientMessageHandler; private final AlarmTimeout mHideTransientMessageHandler;
private final AlarmTimeout mHideBiometricMessageHandler; private final AlarmTimeout mHideBiometricMessageHandler;
private FeatureFlags mFeatureFlags;
/** /**
* Creates a new KeyguardIndicationController and registers callbacks. * Creates a new KeyguardIndicationController and registers callbacks.
@@ -256,7 +258,8 @@ public class KeyguardIndicationController {
AlternateBouncerInteractor alternateBouncerInteractor, AlternateBouncerInteractor alternateBouncerInteractor,
AlarmManager alarmManager, AlarmManager alarmManager,
UserTracker userTracker, UserTracker userTracker,
BouncerMessageInteractor bouncerMessageInteractor BouncerMessageInteractor bouncerMessageInteractor,
FeatureFlags flags
) { ) {
mContext = context; mContext = context;
mBroadcastDispatcher = broadcastDispatcher; mBroadcastDispatcher = broadcastDispatcher;
@@ -282,6 +285,8 @@ public class KeyguardIndicationController {
mAlternateBouncerInteractor = alternateBouncerInteractor; mAlternateBouncerInteractor = alternateBouncerInteractor;
mUserTracker = userTracker; mUserTracker = userTracker;
mBouncerMessageInteractor = bouncerMessageInteractor; mBouncerMessageInteractor = bouncerMessageInteractor;
mFeatureFlags = flags;
mFaceAcquiredMessageDeferral = faceHelpMessageDeferral; mFaceAcquiredMessageDeferral = faceHelpMessageDeferral;
mCoExFaceAcquisitionMsgIdsToShow = new HashSet<>(); mCoExFaceAcquisitionMsgIdsToShow = new HashSet<>();
int[] msgIds = context.getResources().getIntArray( int[] msgIds = context.getResources().getIntArray(
@@ -345,7 +350,8 @@ public class KeyguardIndicationController {
mLockScreenIndicationView, mLockScreenIndicationView,
mExecutor, mExecutor,
mStatusBarStateController, mStatusBarStateController,
mKeyguardLogger mKeyguardLogger,
mFeatureFlags
); );
updateDeviceEntryIndication(false /* animate */); updateDeviceEntryIndication(false /* animate */);
updateOrganizedOwnedDevice(); updateOrganizedOwnedDevice();

View File

@@ -51,6 +51,7 @@ public class KeyguardIndicationTextView extends TextView {
private KeyguardIndication mKeyguardIndicationInfo; private KeyguardIndication mKeyguardIndicationInfo;
private Animator mLastAnimator; private Animator mLastAnimator;
private boolean mAlwaysAnnounceText;
public KeyguardIndicationTextView(Context context) { public KeyguardIndicationTextView(Context context) {
super(context); super(context);
@@ -103,6 +104,19 @@ public class KeyguardIndicationTextView extends TextView {
switchIndication(text, indication, true, null); 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. * Updates the text with an optional animation.
* *
@@ -227,6 +241,9 @@ public class KeyguardIndicationTextView extends TextView {
setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null); setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null);
} }
setText(mMessage); setText(mMessage);
if (mAlwaysAnnounceText) {
announceForAccessibility(mMessage);
}
} }
private AnimatorSet getInAnimator() { private AnimatorSet getInAnimator() {

View File

@@ -17,6 +17,7 @@
package com.android.systemui.keyguard; 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_BATTERY;
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BIOMETRIC_MESSAGE; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BIOMETRIC_MESSAGE;
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_DISCLOSURE; 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.keyguard.logging.KeyguardLogger;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView; import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -81,8 +83,10 @@ public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCas
public void setUp() throws Exception { public void setUp() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
when(mView.getTextColors()).thenReturn(ColorStateList.valueOf(Color.WHITE)); when(mView.getTextColors()).thenReturn(ColorStateList.valueOf(Color.WHITE));
FakeFeatureFlags flags = new FakeFeatureFlags();
flags.set(KEYGUARD_TALKBACK_FIX, true);
mController = new KeyguardIndicationRotateTextViewController(mView, mExecutor, mController = new KeyguardIndicationRotateTextViewController(mView, mExecutor,
mStatusBarStateController, mLogger); mStatusBarStateController, mLogger, flags);
mController.onViewAttached(); mController.onViewAttached();
verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture()); verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());

View File

@@ -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_AVAILABLE;
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; 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.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_ALIGNMENT;
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY; 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_BIOMETRIC_MESSAGE;
@@ -99,6 +100,7 @@ import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.FaceHelpMessageDeferral; import com.android.systemui.biometrics.FaceHelpMessageDeferral;
import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManager;
import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.keyguard.KeyguardIndication; import com.android.systemui.keyguard.KeyguardIndication;
import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController; import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.ScreenLifecycle;
@@ -286,6 +288,8 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
Looper.prepare(); Looper.prepare();
} }
FakeFeatureFlags flags = new FakeFeatureFlags();
flags.set(KEYGUARD_TALKBACK_FIX, true);
mController = new KeyguardIndicationController( mController = new KeyguardIndicationController(
mContext, mContext,
mTestableLooper.getLooper(), mTestableLooper.getLooper(),
@@ -299,7 +303,8 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
mAlternateBouncerInteractor, mAlternateBouncerInteractor,
mAlarmManager, mAlarmManager,
mUserTracker, mUserTracker,
mock(BouncerMessageInteractor.class) mock(BouncerMessageInteractor.class),
flags
); );
mController.init(); mController.init();
mController.setIndicationArea(mIndicationArea); mController.setIndicationArea(mIndicationArea);

View File

@@ -16,6 +16,9 @@
package com.android.systemui.statusbar.phone; 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 static com.google.common.truth.Truth.assertThat;
import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner;
@@ -56,6 +59,22 @@ public class KeyguardIndicationTextViewTest extends SysuiTestCase {
assertThat(mKeyguardIndicationTextView.getText()).isEqualTo(""); 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 @Test
public void switchIndication_emptyText_hideIndication() { public void switchIndication_emptyText_hideIndication() {
mKeyguardIndicationTextView.switchIndication("" /* text */, null); mKeyguardIndicationTextView.switchIndication("" /* text */, null);