mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-18 10:18:20 +00:00
Merge "Enforce the correct orientation for the gesture navigation tutorial" into udc-dev am: 372de4f521
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/23493333 Change-Id: Ic74738724e31203cddbb2eccc187ca562e3de6bd Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -104,7 +104,8 @@
|
||||
android:autoRemoveFromRecents="true"
|
||||
android:excludeFromRecents="true"
|
||||
android:theme="@style/GestureTutorialActivity"
|
||||
android:exported="true">
|
||||
android:exported="true"
|
||||
android:configChanges="orientation">
|
||||
<intent-filter>
|
||||
<action android:name="com.android.quickstep.action.GESTURE_SANDBOX"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
|
||||
21
quickstep/res/drawable/rotate_prompt_bg.xml
Normal file
21
quickstep/res/drawable/rotate_prompt_bg.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<shape
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="?attr/surfaceContainer" />
|
||||
<corners android:radius="@dimen/gesture_tutorial_menu_button_radius" />
|
||||
</shape>
|
||||
26
quickstep/res/drawable/rotate_tutorial_warning.xml
Normal file
26
quickstep/res/drawable/rotate_tutorial_warning.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportHeight="960"
|
||||
android:viewportWidth="960">
|
||||
<path
|
||||
android:fillColor="?androidprv:attr/materialColorOnSurface"
|
||||
android:pathData="M40,840L480,80L920,840L40,840ZM178,760L782,760L480,240L178,760ZM480,720Q497,720 508.5,708.5Q520,697 520,680Q520,663 508.5,651.5Q497,640 480,640Q463,640 451.5,651.5Q440,663 440,680Q440,697 451.5,708.5Q463,720 480,720ZM440,600L520,600L520,400L440,400L440,600ZM480,500L480,500L480,500L480,500Z" />
|
||||
</vector>
|
||||
@@ -13,7 +13,80 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/gesture_tutorial_fragment_container"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/gesture_tutorial_fragment_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rotation_prompt"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/surfaceHome"
|
||||
android:visibility="gone"
|
||||
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/background"
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:background="@drawable/rotate_prompt_bg"
|
||||
android:padding="24dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/rotate_tutorial_warning"
|
||||
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/rotate_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:lineSpacingExtra="2sp"
|
||||
android:text="@string/gesture_tutorial_rotation_prompt_title"
|
||||
android:textAppearance="@style/rotate_prompt_title"
|
||||
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/icon"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/rotate_screen_subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/gesture_tutorial_rotation_prompt"
|
||||
android:textAppearance="@style/rotate_prompt_subtitle"
|
||||
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/rotate_title"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -94,6 +94,10 @@
|
||||
<!-- content description for hotseat items -->
|
||||
<string name="hotseat_prediction_content_description">Predicted app: <xliff:g id="title" example="Chrome">%1$s</xliff:g></string>
|
||||
|
||||
<!-- Title of prompt shown before the gesture navigation tutorial to users who need to rotate their screen. [CHAR LIMIT=100] -->
|
||||
<string name="gesture_tutorial_rotation_prompt_title">Rotate your device</string>
|
||||
<!-- Prompt shown before the gesture navigation tutorial to users who need to rotate their screen to begin. [CHAR LIMIT=100] -->
|
||||
<string name="gesture_tutorial_rotation_prompt">Please rotate your device to complete the gesture navigation tutorial</string>
|
||||
<!-- Feedback shown during interactive parts of Back gesture tutorial for right edge when the gesture is too far from the edge. [CHAR LIMIT=100] -->
|
||||
<string name="back_gesture_feedback_swipe_too_far_from_edge">Make sure you swipe from the far-right or far-left edge.</string>
|
||||
<!-- Feedback shown during interactive parts of Back gesture tutorial for right edge when the gesture is cancelled. [CHAR LIMIT=100] -->
|
||||
|
||||
@@ -290,4 +290,12 @@
|
||||
<item name="surfaceOverview">@android:color/system_accent2_300</item>
|
||||
<item name="secondaryOverview">?androidprv:attr/materialColorOnSecondaryFixedVariant</item>
|
||||
</style>
|
||||
|
||||
<style name="rotate_prompt_title" parent="TextAppearance.GestureTutorial.Dialog.Title">
|
||||
<item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
|
||||
</style>
|
||||
|
||||
<style name="rotate_prompt_subtitle" parent="TextAppearance.GestureTutorial.Dialog.Subtitle">
|
||||
<item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user