From 41f7e169c30475071346e1d207c965bda18c0b16 Mon Sep 17 00:00:00 2001 From: Schneider Victor-tulias Date: Thu, 20 Jul 2023 15:24:04 -0700 Subject: [PATCH] Fix broken gesture nav edu on tablets in portrait. Launching the gesture nav tutorial in portrait mode on tablets causes fragments with the wrong layout file to be inflated (uses the default phone layout). Reinflating fragments whenever they need to be switched. Added a new rotation prompt fragment Flag: ENABLE_NEW_GESTURE_NAV_TUTORIAL Fixes: 291062054 Test: Launched the tutorial in portrait mode and landscape mode, then rotated the screen several times. tried with the flag disabled as well. Change-Id: I0215d7589285007d04ef81d3a63e404c2cda3895 --- .../res/layout/gesture_tutorial_activity.xml | 78 +------------------ .../gesture_tutorial_rotation_prompt.xml | 60 ++++++++++++++ .../BackGestureTutorialController.java | 6 +- .../BackGestureTutorialFragment.java | 6 ++ .../interaction/GestureSandboxActivity.java | 62 +++++++-------- .../interaction/GestureSandboxFragment.java | 6 ++ .../HomeGestureTutorialController.java | 4 +- .../HomeGestureTutorialFragment.java | 6 ++ .../quickstep/interaction/MenuFragment.java | 6 ++ .../OverviewGestureTutorialController.java | 4 +- .../OverviewGestureTutorialFragment.java | 6 ++ .../interaction/RotationPromptFragment.java | 37 +++++++++ .../SwipeUpGestureTutorialController.java | 4 +- .../interaction/TutorialController.java | 4 - .../interaction/TutorialFragment.java | 18 +++-- 15 files changed, 181 insertions(+), 126 deletions(-) create mode 100644 quickstep/res/layout/gesture_tutorial_rotation_prompt.xml create mode 100644 quickstep/src/com/android/quickstep/interaction/RotationPromptFragment.java diff --git a/quickstep/res/layout/gesture_tutorial_activity.xml b/quickstep/res/layout/gesture_tutorial_activity.xml index 0e763ec734..82caedf45f 100644 --- a/quickstep/res/layout/gesture_tutorial_activity.xml +++ b/quickstep/res/layout/gesture_tutorial_activity.xml @@ -13,80 +13,8 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - - - - - - - - - - - - - - - - \ No newline at end of file + android:layout_height="match_parent"/> \ No newline at end of file diff --git a/quickstep/res/layout/gesture_tutorial_rotation_prompt.xml b/quickstep/res/layout/gesture_tutorial_rotation_prompt.xml new file mode 100644 index 0000000000..b41a96dd06 --- /dev/null +++ b/quickstep/res/layout/gesture_tutorial_rotation_prompt.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java index 135cb72f77..631cff7639 100644 --- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java @@ -154,7 +154,7 @@ final class BackGestureTutorialController extends TutorialController { @Override public void onBackGestureAttempted(BackGestureResult result) { - if (skipGestureAttempt()) { + if (isGestureCompleted()) { return; } switch (mTutorialType) { @@ -172,7 +172,7 @@ final class BackGestureTutorialController extends TutorialController { @Override public void onBackGestureProgress(float diffx, float diffy, boolean isLeftGesture) { - if (skipGestureAttempt()) { + if (isGestureCompleted()) { return; } @@ -241,7 +241,7 @@ final class BackGestureTutorialController extends TutorialController { @Override public void onNavBarGestureAttempted(NavBarGestureResult result, PointF finalVelocity) { - if (skipGestureAttempt()) { + if (isGestureCompleted()) { return; } if (mTutorialType == BACK_NAVIGATION_COMPLETE) { diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java index a16b239ff5..b379baabe0 100644 --- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java +++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java @@ -42,6 +42,12 @@ public class BackGestureTutorialFragment extends TutorialFragment { super(fromTutorialMenu); } + @NonNull + @Override + TutorialType getDefaultTutorialType() { + return TutorialType.BACK_NAVIGATION; + } + @Nullable @Override Integer getEdgeAnimationResId() { diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java index 2189a243fe..d10250224d 100644 --- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java +++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java @@ -53,16 +53,14 @@ public class GestureSandboxActivity extends FragmentActivity { static final String KEY_USE_TUTORIAL_MENU = "use_tutorial_menu"; @Nullable private TutorialType[] mTutorialSteps; - private GestureSandboxFragment mFragment; + private GestureSandboxFragment mCurrentFragment; + private GestureSandboxFragment mPendingFragment; private int mCurrentStep; private int mNumSteps; - private boolean mShowRotationPrompt; private SharedPreferences mSharedPrefs; private StatsLogManager mStatsLogManager; - - private View mRotationPrompt; private TISBindHelper mTISBindHelper; @Override @@ -82,7 +80,7 @@ public class GestureSandboxActivity extends FragmentActivity { && args.getBoolean(KEY_USE_TUTORIAL_MENU, false)) { mTutorialSteps = null; TutorialType tutorialTypeOverride = (TutorialType) args.get(KEY_TUTORIAL_TYPE); - mFragment = tutorialTypeOverride == null + mCurrentFragment = tutorialTypeOverride == null ? new MenuFragment() : makeTutorialFragment( tutorialTypeOverride, @@ -90,16 +88,15 @@ public class GestureSandboxActivity extends FragmentActivity { /* fromMenu= */ true); } else { mTutorialSteps = getTutorialSteps(args); - mFragment = makeTutorialFragment( + mCurrentFragment = makeTutorialFragment( mTutorialSteps[mCurrentStep - 1], gestureComplete, /* fromMenu= */ false); } getSupportFragmentManager().beginTransaction() - .add(R.id.gesture_tutorial_fragment_container, mFragment) + .add(R.id.gesture_tutorial_fragment_container, mCurrentFragment) .commit(); - mRotationPrompt = findViewById(R.id.rotation_prompt); if (FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) { correctUserOrientation(); } @@ -127,34 +124,45 @@ public class GestureSandboxActivity extends FragmentActivity { DeviceProfile deviceProfile = InvariantDeviceProfile.INSTANCE.get( getApplicationContext()).getDeviceProfile(this); if (deviceProfile.isTablet) { - mShowRotationPrompt = getResources().getConfiguration().orientation + boolean showRotationPrompt = getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; - updateVisibility(mRotationPrompt, mShowRotationPrompt ? View.VISIBLE : View.GONE); + + GestureSandboxFragment recreatedFragment = + showRotationPrompt || mPendingFragment == null + ? null : mPendingFragment.recreateFragment(); + showFragment(showRotationPrompt + ? new RotationPromptFragment() + : recreatedFragment == null + ? mCurrentFragment : recreatedFragment); } else { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } } - void updateVisibility(View view, int visibility) { - if (view == null || view.getVisibility() == visibility) { - return; + private void showFragment(@NonNull GestureSandboxFragment fragment) { + if (mCurrentFragment.recreateFragment() != null) { + mPendingFragment = mCurrentFragment; } - view.setVisibility(visibility); + mCurrentFragment = fragment; + getSupportFragmentManager().beginTransaction() + .replace(R.id.gesture_tutorial_fragment_container, mCurrentFragment) + .runOnCommit(() -> mCurrentFragment.onAttachedToWindow()) + .commit(); } @Override public void onAttachedToWindow() { super.onAttachedToWindow(); - if (mFragment.shouldDisableSystemGestures()) { + if (mCurrentFragment.shouldDisableSystemGestures()) { disableSystemGestures(); } - mFragment.onAttachedToWindow(); + mCurrentFragment.onAttachedToWindow(); } @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); - mFragment.onDetachedFromWindow(); + mCurrentFragment.onDetachedFromWindow(); } @Override @@ -169,14 +177,10 @@ public class GestureSandboxActivity extends FragmentActivity { protected void onSaveInstanceState(@NonNull Bundle savedInstanceState) { savedInstanceState.putStringArray(KEY_TUTORIAL_STEPS, getTutorialStepNames()); savedInstanceState.putInt(KEY_CURRENT_STEP, mCurrentStep); - mFragment.onSaveInstanceState(savedInstanceState); + mCurrentFragment.onSaveInstanceState(savedInstanceState); super.onSaveInstanceState(savedInstanceState); } - protected boolean isRotationPromptShowing() { - return mShowRotationPrompt; - } - protected SharedPreferences getSharedPrefs() { return mSharedPrefs; } @@ -205,7 +209,7 @@ public class GestureSandboxActivity extends FragmentActivity { */ public void continueTutorial() { if (isTutorialComplete() || mTutorialSteps == null) { - mFragment.close(); + mCurrentFragment.close(); return; } launchTutorialStep(mTutorialSteps[mCurrentStep], false); @@ -224,20 +228,12 @@ public class GestureSandboxActivity extends FragmentActivity { * the menu when complete. */ public void launchTutorialStep(@NonNull TutorialType tutorialType, boolean fromMenu) { - mFragment = makeTutorialFragment(tutorialType, false, fromMenu); - getSupportFragmentManager().beginTransaction() - .replace(R.id.gesture_tutorial_fragment_container, mFragment) - .runOnCommit(() -> mFragment.onAttachedToWindow()) - .commit(); + showFragment(makeTutorialFragment(tutorialType, false, fromMenu)); } /** Launches the gesture nav tutorial menu page */ public void launchTutorialMenu() { - mFragment = new MenuFragment(); - getSupportFragmentManager().beginTransaction() - .replace(R.id.gesture_tutorial_fragment_container, mFragment) - .runOnCommit(() -> mFragment.onAttachedToWindow()) - .commit(); + showFragment(new MenuFragment()); } private String[] getTutorialStepNames() { diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxFragment.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxFragment.java index d52f19a2b5..08f298965c 100644 --- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxFragment.java +++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxFragment.java @@ -17,6 +17,7 @@ package com.android.quickstep.interaction; import android.app.Activity; +import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; @@ -27,6 +28,11 @@ public abstract class GestureSandboxFragment extends Fragment { void onDetachedFromWindow() {} + @Nullable + GestureSandboxFragment recreateFragment() { + return null; + } + boolean shouldDisableSystemGestures() { return true; } diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java index 0aa80d3e79..daac99bfee 100644 --- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java @@ -147,7 +147,7 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll @Override public void onBackGestureAttempted(BackGestureResult result) { - if (skipGestureAttempt()) { + if (isGestureCompleted()) { return; } switch (mTutorialType) { @@ -174,7 +174,7 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll @Override public void onNavBarGestureAttempted(NavBarGestureResult result, PointF finalVelocity) { - if (skipGestureAttempt()) { + if (isGestureCompleted()) { return; } switch (mTutorialType) { diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java index bced8c4aef..3e924d7ed1 100644 --- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java +++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java @@ -41,6 +41,12 @@ public class HomeGestureTutorialFragment extends TutorialFragment { super(fromTutorialMenu); } + @NonNull + @Override + TutorialType getDefaultTutorialType() { + return TutorialType.HOME_NAVIGATION; + } + @Nullable @Override Integer getEdgeAnimationResId() { diff --git a/quickstep/src/com/android/quickstep/interaction/MenuFragment.java b/quickstep/src/com/android/quickstep/interaction/MenuFragment.java index c19d44a55f..dbf141b987 100644 --- a/quickstep/src/com/android/quickstep/interaction/MenuFragment.java +++ b/quickstep/src/com/android/quickstep/interaction/MenuFragment.java @@ -32,6 +32,12 @@ import com.android.launcher3.R; /** Displays the gesture nav tutorial menu. */ public final class MenuFragment extends GestureSandboxFragment { + @NonNull + @Override + GestureSandboxFragment recreateFragment() { + return new MenuFragment(); + } + @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java index 75b80b31f9..afdc1e54a7 100644 --- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java @@ -179,7 +179,7 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont @Override public void onBackGestureAttempted(BackGestureResult result) { - if (skipGestureAttempt()) { + if (isGestureCompleted()) { return; } switch (mTutorialType) { @@ -206,7 +206,7 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont @Override public void onNavBarGestureAttempted(NavBarGestureResult result, PointF finalVelocity) { - if (skipGestureAttempt()) { + if (isGestureCompleted()) { return; } switch (mTutorialType) { diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java index 01074dd276..ee1c46057e 100644 --- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java +++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java @@ -41,6 +41,12 @@ public class OverviewGestureTutorialFragment extends TutorialFragment { super(fromTutorialMenu); } + @NonNull + @Override + TutorialType getDefaultTutorialType() { + return TutorialType.OVERVIEW_NAVIGATION; + } + @Nullable @Override Integer getEdgeAnimationResId() { diff --git a/quickstep/src/com/android/quickstep/interaction/RotationPromptFragment.java b/quickstep/src/com/android/quickstep/interaction/RotationPromptFragment.java new file mode 100644 index 0000000000..89af647985 --- /dev/null +++ b/quickstep/src/com/android/quickstep/interaction/RotationPromptFragment.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.quickstep.interaction; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.launcher3.R; + +/** Displays the prompt requesting that the user rotates their device. */ +public class RotationPromptFragment extends GestureSandboxFragment { + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + return inflater.inflate(R.layout.gesture_tutorial_rotation_prompt, container, false); + } +} diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java index d0d7534772..87defc5252 100644 --- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java @@ -282,7 +282,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController { @Override public void setNavBarGestureProgress(@Nullable Float displacement) { - if (skipGestureAttempt()) { + if (isGestureCompleted()) { return; } if (mTutorialType == HOME_NAVIGATION_COMPLETE @@ -303,7 +303,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController { @Override public void onMotionPaused(boolean unused) { - if (skipGestureAttempt()) { + if (isGestureCompleted()) { return; } if (mShowTasks) { diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java index 4a1fec3ecf..ed2d18a243 100644 --- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java @@ -489,10 +489,6 @@ abstract class TutorialController implements BackGestureAttemptCallback, return mGestureCompleted; } - public boolean skipGestureAttempt() { - return isGestureCompleted() || mTutorialFragment.isRotationPromptShowing(); - } - void hideFeedback() { if (mFeedbackView.getVisibility() != View.VISIBLE) { return; diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java index 84326f5a27..a28cf58c35 100644 --- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java +++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java @@ -100,6 +100,19 @@ abstract class TutorialFragment extends GestureSandboxFragment implements OnTouc return fragment; } + @Nullable + @Override + GestureSandboxFragment recreateFragment() { + TutorialType tutorialType = mTutorialController == null + ? (mTutorialType == null + ? getDefaultTutorialType() : mTutorialType) + : mTutorialController.mTutorialType; + return newInstance(tutorialType, isGestureComplete(), mFromTutorialMenu); + } + + @NonNull + abstract TutorialType getDefaultTutorialType(); + TutorialFragment(boolean fromTutorialMenu) { mFromTutorialMenu = fromTutorialMenu; } @@ -498,11 +511,6 @@ abstract class TutorialFragment extends GestureSandboxFragment implements OnTouc return activity != null ? activity.getStatsLogManager() : null; } - protected boolean isRotationPromptShowing() { - GestureSandboxActivity activity = getGestureSandboxActivity(); - return activity != null && activity.isRotationPromptShowing(); - } - @Nullable private SharedPreferences getSharedPreferences() { GestureSandboxActivity activity = getGestureSandboxActivity();