diff --git a/quickstep/res/layout/redesigned_gesture_tutorial_fragment.xml b/quickstep/res/layout/redesigned_gesture_tutorial_fragment.xml index b004dfda6a..7530c286f4 100644 --- a/quickstep/res/layout/redesigned_gesture_tutorial_fragment.xml +++ b/quickstep/res/layout/redesigned_gesture_tutorial_fragment.xml @@ -147,6 +147,7 @@ android:layout_height="wrap_content" android:layout_marginTop="104dp" android:accessibilityHeading="true" + android:accessibilityTraversalBefore="@id/gesture_tutorial_fragment_feedback_subtitle" android:gravity="top" android:lineSpacingExtra="-1sp" android:textAppearance="@style/TextAppearance.GestureTutorial.MainTitle" @@ -161,6 +162,8 @@ android:layout_marginTop="24dp" android:lineSpacingExtra="4sp" android:textAppearance="@style/TextAppearance.GestureTutorial.MainSubtitle" + android:accessibilityTraversalAfter="@id/gesture_tutorial_fragment_feedback_title" + android:accessibilityTraversalBefore="@id/gesture_tutorial_fragment_action_button" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_fragment_feedback_title" /> @@ -224,6 +227,10 @@ android:layout_marginBottom="@dimen/gesture_tutorial_done_button_bottom_margin" android:layout_alignParentBottom="true" android:layout_alignParentEnd="true" + android:clickable="true" + android:focusableInTouchMode="true" + android:accessibilityTraversalAfter="@id/gesture_tutorial_fragment_feedback_subtitle" + android:contentDescription="@string/gesture_tutorial_action_button_label" android:background="@drawable/gesture_tutorial_action_button_background" android:stateListAnimator="@null" android:text="@string/gesture_tutorial_action_button_label" diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java index 7d14a3ebd5..0fc95e2102 100644 --- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java @@ -80,8 +80,8 @@ abstract class TutorialController implements BackGestureAttemptCallback, private static final CharSequence DEFAULT_PIXEL_TIPS_APP_NAME = "Pixel Tips"; private static final int FEEDBACK_ANIMATION_MS = 133; - private static final int RIPPLE_VISIBLE_MS = 300; - private static final int GESTURE_ANIMATION_DELAY_MS = 1500; + private static final int SUBTITLE_ANNOUNCE_DELAY_MS = 3000; + private static final int DONE_BUTTON_ANNOUNCE_DELAY_MS = 4000; private static final int ADVANCE_TUTORIAL_TIMEOUT_MS = 3000; private static final long GESTURE_ANIMATION_PAUSE_DURATION_MILLIS = 1000; protected float mExitingAppEndingCornerRadius; @@ -124,10 +124,12 @@ abstract class TutorialController implements BackGestureAttemptCallback, // These runnables should be used when posting callbacks to their views and cleared from their // views before posting new callbacks. private final Runnable mTitleViewCallback; + private final Runnable mSubtitleViewCallback; @Nullable private Runnable mFeedbackViewCallback; @Nullable private Runnable mFakeTaskViewCallback; @Nullable private Runnable mFakeTaskbarViewCallback; private final Runnable mShowFeedbackRunnable; + private final AccessibilityManager mAccessibilityManager; TutorialController(TutorialFragment tutorialFragment, TutorialType tutorialType) { mTutorialFragment = tutorialFragment; @@ -175,6 +177,7 @@ abstract class TutorialController implements BackGestureAttemptCallback, mFeedbackTitleView.setText(getIntroductionTitle()); mFeedbackSubtitleView.setText(getIntroductionSubtitle()); + mExitingAppView.setClipToOutline(true); mExitingAppView.setOutlineProvider(new ViewOutlineProvider() { @Override @@ -183,8 +186,16 @@ abstract class TutorialController implements BackGestureAttemptCallback, } }); - mTitleViewCallback = () -> mFeedbackTitleView.sendAccessibilityEvent( - AccessibilityEvent.TYPE_VIEW_FOCUSED); + mAccessibilityManager = AccessibilityManager.getInstance(mContext); + mTitleViewCallback = () -> { + mFeedbackTitleView.requestFocus(); + mFeedbackTitleView.sendAccessibilityEvent( + AccessibilityEvent.TYPE_VIEW_FOCUSED); + }; + mSubtitleViewCallback = () -> { + mFeedbackSubtitleView.requestFocus(); + mFeedbackSubtitleView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED); + }; mShowFeedbackRunnable = () -> { mFeedbackView.setAlpha(0f); mFeedbackView.setScaleX(0.95f); @@ -203,10 +214,10 @@ abstract class TutorialController implements BackGestureAttemptCallback, mFeedbackViewCallback = mTutorialFragment::continueTutorial; mFeedbackView.postDelayed( mFeedbackViewCallback, - AccessibilityManager.getInstance(mContext) - .getRecommendedTimeoutMillis( - ADVANCE_TUTORIAL_TIMEOUT_MS, - AccessibilityManager.FLAG_CONTENT_TEXT)); + mAccessibilityManager.getRecommendedTimeoutMillis( + ADVANCE_TUTORIAL_TIMEOUT_MS, + AccessibilityManager.FLAG_CONTENT_TEXT + | AccessibilityManager.FLAG_CONTENT_CONTROLS)); } }) .start(); @@ -404,6 +415,7 @@ abstract class TutorialController implements BackGestureAttemptCallback, int subtitleResId, boolean isGestureSuccessful) { mFeedbackTitleView.removeCallbacks(mTitleViewCallback); + mFeedbackSubtitleView.removeCallbacks(mSubtitleViewCallback); if (mFeedbackViewCallback != null) { mFeedbackView.removeCallbacks(mFeedbackViewCallback); mFeedbackViewCallback = null; @@ -411,6 +423,15 @@ abstract class TutorialController implements BackGestureAttemptCallback, mFeedbackTitleView.setText(titleResId); mFeedbackSubtitleView.setText(subtitleResId); + mFeedbackTitleView.postDelayed(mTitleViewCallback, mAccessibilityManager + .getRecommendedTimeoutMillis( + FEEDBACK_ANIMATION_MS, + AccessibilityManager.FLAG_CONTENT_TEXT)); + mFeedbackSubtitleView.postDelayed(mSubtitleViewCallback, mAccessibilityManager + .getRecommendedTimeoutMillis( + SUBTITLE_ANNOUNCE_DELAY_MS, + AccessibilityManager.FLAG_CONTENT_TEXT)); + if (isGestureSuccessful) { if (mTutorialFragment.isAtFinalStep()) { showActionButton(); @@ -467,6 +488,7 @@ abstract class TutorialController implements BackGestureAttemptCallback, mFakeTaskbarViewCallback = null; } mFeedbackTitleView.removeCallbacks(mTitleViewCallback); + mFeedbackSubtitleView.removeCallbacks(mSubtitleViewCallback); } private void playFeedbackAnimation() { @@ -542,6 +564,13 @@ abstract class TutorialController implements BackGestureAttemptCallback, mSkipButton.setVisibility(GONE); mDoneButton.setVisibility(View.VISIBLE); mDoneButton.setOnClickListener(this::onActionButtonClicked); + mDoneButton.postDelayed(() -> { + mDoneButton.requestFocus(); + mDoneButton.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); + }, mAccessibilityManager + .getRecommendedTimeoutMillis( + DONE_BUTTON_ANNOUNCE_DELAY_MS, + AccessibilityManager.FLAG_CONTENT_CONTROLS)); } void hideFakeTaskbar(boolean animateToHotseat) {