From e2711c254ad8b918c7f0e4d461af4193433174a6 Mon Sep 17 00:00:00 2001 From: Saumya Prakash Date: Wed, 31 May 2023 18:24:05 +0000 Subject: [PATCH] Enforce the correct orientation for the gesture navigation tutorial The lottie animations used for the gesture navigation tutorial are designed for specific orientations depending on the device. This change ensures that users are in the correct orientation for their device. For large screen users in portrait mode, we display a prompt to rotate the screen. Flag: ENABLE_NEW_GESTURE_TUTORIAL Fix: 277781713 Bug: 276515961 Test: Manually went through the tutorial starting from both orientations on handheld, foldable, and tablet to ensure that the prompt was shown and hidden correctly. Also ensured that gestures cannot be completed in the background while the prompt is being shown. Change-Id: I86ae566721f240264177ad4ec7fc12e58d1b95cd --- quickstep/AndroidManifest.xml | 3 +- quickstep/res/drawable/rotate_prompt_bg.xml | 21 +++++ .../res/drawable/rotate_tutorial_warning.xml | 26 ++++++ .../res/layout/gesture_tutorial_activity.xml | 79 ++++++++++++++++++- quickstep/res/values/strings.xml | 4 + quickstep/res/values/styles.xml | 8 ++ .../BackGestureTutorialController.java | 6 +- .../interaction/GestureSandboxActivity.java | 50 ++++++++++++ .../HomeGestureTutorialController.java | 4 +- .../OverviewGestureTutorialController.java | 4 +- .../SwipeUpGestureTutorialController.java | 4 +- .../interaction/TutorialController.java | 4 + .../interaction/TutorialFragment.java | 5 ++ 13 files changed, 205 insertions(+), 13 deletions(-) create mode 100644 quickstep/res/drawable/rotate_prompt_bg.xml create mode 100644 quickstep/res/drawable/rotate_tutorial_warning.xml diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml index 8e1baba956..7c0a5aece0 100644 --- a/quickstep/AndroidManifest.xml +++ b/quickstep/AndroidManifest.xml @@ -104,7 +104,8 @@ android:autoRemoveFromRecents="true" android:excludeFromRecents="true" android:theme="@style/GestureTutorialActivity" - android:exported="true"> + android:exported="true" + android:configChanges="orientation"> diff --git a/quickstep/res/drawable/rotate_prompt_bg.xml b/quickstep/res/drawable/rotate_prompt_bg.xml new file mode 100644 index 0000000000..528a2bc90d --- /dev/null +++ b/quickstep/res/drawable/rotate_prompt_bg.xml @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/quickstep/res/drawable/rotate_tutorial_warning.xml b/quickstep/res/drawable/rotate_tutorial_warning.xml new file mode 100644 index 0000000000..d1117a4321 --- /dev/null +++ b/quickstep/res/drawable/rotate_tutorial_warning.xml @@ -0,0 +1,26 @@ + + + + diff --git a/quickstep/res/layout/gesture_tutorial_activity.xml b/quickstep/res/layout/gesture_tutorial_activity.xml index 4dc8913ef5..0e763ec734 100644 --- a/quickstep/res/layout/gesture_tutorial_activity.xml +++ b/quickstep/res/layout/gesture_tutorial_activity.xml @@ -13,7 +13,80 @@ 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/values/strings.xml b/quickstep/res/values/strings.xml index bd69f9f4ec..3b8278451d 100644 --- a/quickstep/res/values/strings.xml +++ b/quickstep/res/values/strings.xml @@ -94,6 +94,10 @@ Predicted app: %1$s + + Rotate your device + + Please rotate your device to complete the gesture navigation tutorial Make sure you swipe from the far-right or far-left edge. diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml index 612682a86b..21b7fd5139 100644 --- a/quickstep/res/values/styles.xml +++ b/quickstep/res/values/styles.xml @@ -290,4 +290,12 @@ @android:color/system_accent2_300 ?androidprv:attr/materialColorOnSecondaryFixedVariant + + + + diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java index 54c441b59e..9083d514d3 100644 --- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java @@ -147,7 +147,7 @@ final class BackGestureTutorialController extends TutorialController { @Override public void onBackGestureAttempted(BackGestureResult result) { - if (isGestureCompleted()) { + if (skipGestureAttempt()) { return; } switch (mTutorialType) { @@ -165,7 +165,7 @@ final class BackGestureTutorialController extends TutorialController { @Override public void onBackGestureProgress(float diffx, float diffy, boolean isLeftGesture) { - if (isGestureCompleted()) { + if (skipGestureAttempt()) { return; } @@ -234,7 +234,7 @@ final class BackGestureTutorialController extends TutorialController { @Override public void onNavBarGestureAttempted(NavBarGestureResult result, PointF finalVelocity) { - if (isGestureCompleted()) { + if (skipGestureAttempt()) { return; } if (mTutorialType == BACK_NAVIGATION_COMPLETE) { diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java index aeac760025..62726a01d2 100644 --- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java +++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java @@ -16,6 +16,8 @@ package com.android.quickstep.interaction; import android.content.SharedPreferences; +import android.content.pm.ActivityInfo; +import android.content.res.Configuration; import android.graphics.Color; import android.graphics.Rect; import android.os.Bundle; @@ -29,6 +31,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.FragmentActivity; +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; import com.android.launcher3.config.FeatureFlags; @@ -53,10 +57,12 @@ public class GestureSandboxActivity extends FragmentActivity { private int mCurrentStep; private int mNumSteps; + private boolean mShowRotationPrompt; private SharedPreferences mSharedPrefs; private StatsLogManager mStatsLogManager; + private View mRotationPrompt; private TISBindHelper mTISBindHelper; private TISBinder mBinder; @@ -94,9 +100,49 @@ public class GestureSandboxActivity extends FragmentActivity { .add(R.id.gesture_tutorial_fragment_container, mFragment) .commit(); + mRotationPrompt = findViewById(R.id.rotation_prompt); + if (FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) { + correctUserOrientation(); + } mTISBindHelper = new TISBindHelper(this, this::onTISConnected); } + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + // Ensure the prompt to rotate the screen is updated + if (FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) { + correctUserOrientation(); + } + } + + /** + * Gesture animations are only in landscape for large screens and portrait for mobile. This + * method enforces the following flows: + * 1) phone / two-panel closed -> lock to portrait + * 2) two-panel open / tablet + portrait -> prompt the user to rotate the screen + * 3) two-panel open / tablet + landscape -> hide potential rotating prompt + */ + private void correctUserOrientation() { + DeviceProfile deviceProfile = InvariantDeviceProfile.INSTANCE.get( + getApplicationContext()).getDeviceProfile(this); + if (deviceProfile.isTablet) { + mShowRotationPrompt = getResources().getConfiguration().orientation + == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; + updateVisibility(mRotationPrompt, mShowRotationPrompt ? View.VISIBLE : View.GONE); + } else { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + } + } + + void updateVisibility(View view, int visibility) { + if (view == null || view.getVisibility() == visibility) { + return; + } + view.setVisibility(visibility); + } + @Override public void onAttachedToWindow() { super.onAttachedToWindow(); @@ -128,6 +174,10 @@ public class GestureSandboxActivity extends FragmentActivity { super.onSaveInstanceState(savedInstanceState); } + protected boolean isRotationPromptShowing() { + return mShowRotationPrompt; + } + protected SharedPreferences getSharedPrefs() { return mSharedPrefs; } diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java index 891f20e560..333ecbbb2c 100644 --- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java @@ -140,7 +140,7 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll @Override public void onBackGestureAttempted(BackGestureResult result) { - if (isGestureCompleted()) { + if (skipGestureAttempt()) { return; } switch (mTutorialType) { @@ -167,7 +167,7 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll @Override public void onNavBarGestureAttempted(NavBarGestureResult result, PointF finalVelocity) { - if (isGestureCompleted()) { + if (skipGestureAttempt()) { return; } switch (mTutorialType) { diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java index 667fe4dfad..09a6bbe6b2 100644 --- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java @@ -170,7 +170,7 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont @Override public void onBackGestureAttempted(BackGestureResult result) { - if (isGestureCompleted()) { + if (skipGestureAttempt()) { return; } switch (mTutorialType) { @@ -197,7 +197,7 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont @Override public void onNavBarGestureAttempted(NavBarGestureResult result, PointF finalVelocity) { - if (isGestureCompleted()) { + if (skipGestureAttempt()) { return; } switch (mTutorialType) { diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java index 0bbf373023..f1cbfcc613 100644 --- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java @@ -260,7 +260,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController { @Override public void setNavBarGestureProgress(@Nullable Float displacement) { - if (isGestureCompleted()) { + if (skipGestureAttempt()) { return; } if (mTutorialType == HOME_NAVIGATION_COMPLETE @@ -281,7 +281,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController { @Override public void onMotionPaused(boolean unused) { - if (isGestureCompleted()) { + if (skipGestureAttempt()) { return; } if (mShowTasks) { diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java index 5ec92a6542..a58f4538c8 100644 --- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java @@ -462,6 +462,10 @@ 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 bfad64308c..84326f5a27 100644 --- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java +++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java @@ -498,6 +498,11 @@ 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();