Merge "Import translations. DO NOT MERGE" into ub-launcher3-rvc-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AllAppsTipView.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AllAppsTipView.java
index 079a738..d93aea4 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AllAppsTipView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AllAppsTipView.java
@@ -74,10 +74,6 @@
launcher.getStateManager().addStateListener(
new LauncherStateManager.StateListener() {
@Override
- public void onStateTransitionStart(LauncherState toState) {
- }
-
- @Override
public void onStateTransitionComplete(LauncherState finalState) {
if (finalState == ALL_APPS) {
if (showAllAppsTipIfNecessary(launcher)) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AppsDividerView.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AppsDividerView.java
index ec46418..81a6070 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AppsDividerView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AppsDividerView.java
@@ -251,9 +251,6 @@
}
@Override
- public void onStateTransitionStart(LauncherState toState) { }
-
- @Override
public void onStateTransitionComplete(LauncherState finalState) {
if (finalState == ALL_APPS) {
setAllAppsVisitedCount(getAllAppsVisitedCount() + 1);
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java
index 8e55609..e68627a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java
@@ -158,9 +158,6 @@
public void reapplyItemInfo(ItemInfoWithIcon info) { }
@Override
- public void onStateTransitionStart(LauncherState toState) { }
-
- @Override
public void onStateTransitionComplete(LauncherState state) {
if (mAppsView == null) {
return;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index 28c2b97..ce7a141 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -15,6 +15,7 @@
*/
package com.android.quickstep;
+import static android.content.Intent.ACTION_CHOOSER;
import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_UP;
@@ -620,7 +621,10 @@
return createDeviceLockedInputConsumer(gestureState);
}
- boolean forceOverviewInputConsumer = false;
+ // Use overview input consumer for sharesheets on top of home.
+ boolean forceOverviewInputConsumer = gestureState.getActivityInterface().isStarted()
+ && gestureState.getRunningTask() != null
+ && ACTION_CHOOSER.equals(gestureState.getRunningTask().baseIntent.getAction());
if (AssistantUtilities.isExcludedAssistant(gestureState.getRunningTask())) {
// In the case where we are in the excluded assistant state, ignore it and treat the
// running activity as the task behind the assistant
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
index 9309110..5abbd86 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
@@ -208,7 +208,6 @@
float alpha;
float cornerRadius = 0f;
float scale = Math.max(mCurrentRect.width(), mTargetRect.width()) / crop.width();
- int layer = RemoteAnimationProvider.getLayer(app, mBoostModeTargetLayers);
if (app.mode == params.mTargetSet.targetMode) {
alpha = mTaskAlphaCallback.getAlpha(app, params.mTargetAlpha);
if (app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
@@ -245,13 +244,11 @@
alpha = mBaseAlphaCallback.getAlpha(app, progress);
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && params.mLauncherOnTop) {
crop = null;
- layer = Integer.MAX_VALUE;
}
}
builder.withAlpha(alpha)
.withMatrix(mTmpMatrix)
.withWindowCrop(crop)
- .withLayer(layer)
// Since radius is in Surface space, but we draw the rounded corners in screen
// space, we have to undo the scale
.withCornerRadius(cornerRadius / scale);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java
index d160686..6e9ca23 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java
@@ -17,7 +17,7 @@
package com.android.quickstep.views;
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
-import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
+import static com.android.quickstep.SysUINavigationMode.getMode;
import android.content.Context;
import android.util.AttributeSet;
@@ -31,6 +31,7 @@
import com.android.launcher3.R;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
+import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.TaskOverlayFactory.OverlayUICallbacks;
import java.lang.annotation.Retention;
@@ -118,7 +119,8 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
updateHiddenFlags(HIDDEN_DISABLED_FEATURE, !ENABLE_OVERVIEW_ACTIONS.get());
- updateHiddenFlags(HIDDEN_UNSUPPORTED_NAVIGATION, !removeShelfFromOverview(getContext()));
+ updateHiddenFlags(HIDDEN_UNSUPPORTED_NAVIGATION,
+ getMode(getContext()) == SysUINavigationMode.Mode.TWO_BUTTONS);
}
public void updateHiddenFlags(@ActionsHiddenFlags int visibilityFlags, boolean enable) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index 3b6fd13..fc42acf 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -70,6 +70,7 @@
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.FloatProperty;
+import android.util.Log;
import android.util.Property;
import android.util.SparseBooleanArray;
import android.view.HapticFeedbackConstants;
@@ -116,6 +117,7 @@
import com.android.quickstep.RecentsAnimationTargets;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.RecentsModel.TaskVisualsChangeListener;
+import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskThumbnailCache;
import com.android.quickstep.TaskUtils;
@@ -693,7 +695,7 @@
final int pageIndex = requiredTaskCount - i - 1 + mTaskViewStartIndex;
final Task task = tasks.get(i);
final TaskView taskView = (TaskView) getChildAt(pageIndex);
- taskView.bind(task, mOrientationState);
+ taskView.bind(task, mOrientationState, mActivity.getDeviceProfile().isMultiWindowMode);
}
if (mNextPage == INVALID_PAGE) {
@@ -800,11 +802,14 @@
@Override
public void setInsets(Rect insets) {
mInsets.set(insets);
+ resetPaddingFromTaskSize();
+ }
+
+ private void resetPaddingFromTaskSize() {
DeviceProfile dp = mActivity.getDeviceProfile();
getTaskSize(dp, mTempRect);
mTaskWidth = mTempRect.width();
mTaskHeight = mTempRect.height();
-
mTempRect.top -= mTaskTopMargin;
setPadding(mTempRect.left - mInsets.left, mTempRect.top - mInsets.top,
dp.widthPx - mInsets.right - mTempRect.right,
@@ -1067,7 +1072,8 @@
new ComponentName(getContext(), getClass()), 0, 0), null, null, "", "", 0, 0,
false, true, false, false, new ActivityManager.TaskDescription(), 0,
new ComponentName("", ""), false);
- taskView.bind(mTmpRunningTask, mOrientationState);
+ taskView.bind(mTmpRunningTask, mOrientationState,
+ mActivity.getDeviceProfile().isMultiWindowMode);
}
boolean runningTaskTileHidden = mRunningTaskTileHidden;
@@ -1569,6 +1575,7 @@
mActivity.getDragLayer().recreateControllers();
mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION,
touchRotation != 0 || launcherRotation != 0);
+ resetPaddingFromTaskSize();
requestLayout();
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java
index 80022b4..9b47520 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java
@@ -40,6 +40,7 @@
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
import com.android.launcher3.popup.SystemShortcut;
+import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.BaseDragLayer;
import com.android.quickstep.TaskOverlayFactory;
@@ -150,9 +151,26 @@
return (type & TYPE_TASK_MENU) != 0;
}
- public void setPosition(float x, float y) {
- setX(x);
- setY(y + mThumbnailTopMargin);
+ public void setPosition(float x, float y, PagedOrientationHandler pagedOrientationHandler) {
+ float adjustedY = y + mThumbnailTopMargin;
+ // Changing pivot to make computations easier
+ // NOTE: Changing the pivots means the rotated view gets rotated about the new pivots set,
+ // which would render the X and Y position set here incorrect
+ setPivotX(0);
+ setPivotY(0);
+ setRotation(pagedOrientationHandler.getDegreesRotated());
+ setX(pagedOrientationHandler.getTaskMenuX(x, mTaskView.getThumbnail()));
+ setY(pagedOrientationHandler.getTaskMenuY(adjustedY, mTaskView.getThumbnail()));
+ }
+
+ public void onRotationChanged() {
+ if (mOpenCloseAnimator != null && mOpenCloseAnimator.isRunning()) {
+ mOpenCloseAnimator.end();
+ }
+ if (mIsOpen) {
+ mOptionLayout.removeAllViews();
+ populateAndLayoutMenu();
+ }
}
public static TaskMenuView showForTask(TaskView taskView) {
@@ -168,12 +186,16 @@
}
mActivity.getDragLayer().addView(this);
mTaskView = taskView;
- addMenuOptions(mTaskView);
- orientAroundTaskView(mTaskView);
+ populateAndLayoutMenu();
post(this::animateOpen);
return true;
}
+ private void populateAndLayoutMenu() {
+ addMenuOptions(mTaskView);
+ orientAroundTaskView(mTaskView);
+ }
+
private void addMenuOptions(TaskView taskView) {
Drawable icon = taskView.getTask().icon.getConstantState().newDrawable();
mTaskIcon.setDrawable(icon);
@@ -200,21 +222,26 @@
R.layout.task_view_menu_option, this, false);
menuOption.setIconAndLabelFor(
menuOptionView.findViewById(R.id.icon), menuOptionView.findViewById(R.id.text));
+ LayoutParams lp = (LayoutParams) menuOptionView.getLayoutParams();
+ mTaskView.getPagedOrientationHandler().setLayoutParamsForTaskMenuOptionItem(lp);
menuOptionView.setOnClickListener(menuOption);
mOptionLayout.addView(menuOptionView);
}
private void orientAroundTaskView(TaskView taskView) {
+ PagedOrientationHandler orientationHandler = taskView.getPagedOrientationHandler();
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
mActivity.getDragLayer().getDescendantRectRelativeToSelf(taskView, sTempRect);
Rect insets = mActivity.getDragLayer().getInsets();
BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams();
- params.width = taskView.getMeasuredWidth();
+ params.width = orientationHandler.getTaskMenuWidth(taskView.getThumbnail());
params.gravity = Gravity.START;
setLayoutParams(params);
setScaleX(taskView.getScaleX());
setScaleY(taskView.getScaleY());
- setPosition(sTempRect.left - insets.left, sTempRect.top - insets.top);
+ mOptionLayout.setOrientation(orientationHandler.getTaskMenuLayoutOrientation());
+ setPosition(sTempRect.left - insets.left, sTempRect.top - insets.top,
+ taskView.getPagedOrientationHandler());
}
private void animateOpen() {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
index a05e0fa..8dc41d0 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -36,6 +36,7 @@
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.FloatProperty;
+import android.util.Log;
import android.util.Property;
import android.view.Surface;
import android.view.View;
@@ -49,6 +50,7 @@
import com.android.quickstep.TaskOverlayFactory;
import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
import com.android.quickstep.views.TaskView.FullscreenDrawParams;
+import com.android.quickstep.util.RecentsOrientedState;
import com.android.systemui.plugins.OverviewScreenshotActions;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.shared.recents.model.Task;
@@ -103,6 +105,7 @@
private boolean mOverlayEnabled;
private OverviewScreenshotActions mOverviewScreenshotActionsPlugin;
+ private boolean mIsMultiWindowMode;
public TaskThumbnailView(Context context) {
this(context, null);
@@ -124,7 +127,8 @@
mPreviewPositionHelper = new PreviewPositionHelper(context);
}
- public void bind(Task task) {
+ public void bind(Task task, boolean isMultiWindowMode) {
+ mIsMultiWindowMode = isMultiWindowMode;
mOverlay.reset();
mTask = task;
int color = task == null ? Color.BLACK : task.colorBackground | 0xFF000000;
@@ -350,7 +354,7 @@
mPreviewRect.set(0, 0, mThumbnailData.thumbnail.getWidth(),
mThumbnailData.thumbnail.getHeight());
mPreviewPositionHelper.updateThumbnailMatrix(mPreviewRect, mThumbnailData,
- mActivity.isInMultiWindowMode(), getMeasuredWidth(), getMeasuredHeight());
+ mIsMultiWindowMode, getMeasuredWidth(), getMeasuredHeight());
mBitmapShader.setLocalMatrix(mPreviewPositionHelper.mMatrix);
mPaint.setShader(mBitmapShader);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
index 12ef521..ad49bfa 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
@@ -295,11 +295,14 @@
/**
* Updates this task view to the given {@param task}.
+ *
+ * TODO(b/142282126) Re-evaluate if we need to pass in isMultiWindowMode after
+ * that issue is fixed
*/
- public void bind(Task task, RecentsOrientedState orientedState) {
+ public void bind(Task task, RecentsOrientedState orientedState, boolean isMultiWindowMode) {
cancelPendingLoadTasks();
mTask = task;
- mSnapshotView.bind(task);
+ mSnapshotView.bind(task, isMultiWindowMode);
setOrientationState(orientedState);
}
@@ -473,6 +476,7 @@
int iconRotation = orientationState.getTouchRotation();
PagedOrientationHandler orientationHandler = orientationState.getOrientationHandler();
boolean isRtl = orientationHandler.getRecentsRtlSetting(getResources());
+ LayoutParams snapshotParams = (LayoutParams) mSnapshotView.getLayoutParams();
int thumbnailPadding = (int) getResources().getDimension(R.dimen.task_thumbnail_top_margin);
LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
int rotation = orientationState.getTouchRotationDegrees();
@@ -480,7 +484,8 @@
case Surface.ROTATION_90:
iconParams.gravity = (isRtl ? END : START) | CENTER_VERTICAL;
iconParams.rightMargin = -thumbnailPadding;
- iconParams.leftMargin = iconParams.topMargin = iconParams.bottomMargin = 0;
+ iconParams.leftMargin = 0;
+ iconParams.topMargin = snapshotParams.topMargin / 2;
break;
case Surface.ROTATION_180:
iconParams.gravity = BOTTOM | CENTER_HORIZONTAL;
@@ -490,17 +495,21 @@
case Surface.ROTATION_270:
iconParams.gravity = (isRtl ? END : START) | CENTER_VERTICAL;
iconParams.leftMargin = -thumbnailPadding;
- iconParams.rightMargin = iconParams.topMargin = iconParams.bottomMargin = 0;
+ iconParams.rightMargin = 0;
+ iconParams.topMargin = snapshotParams.topMargin / 2;
break;
case Surface.ROTATION_0:
default:
iconParams.gravity = TOP | CENTER_HORIZONTAL;
- iconParams.leftMargin = iconParams.topMargin = iconParams.rightMargin =
- iconParams.bottomMargin = 0;
+ iconParams.leftMargin = iconParams.topMargin = iconParams.rightMargin = 0;
break;
}
mIconView.setLayoutParams(iconParams);
mIconView.setRotation(rotation);
+
+ if (mMenuView != null) {
+ mMenuView.onRotationChanged();
+ }
}
private void setIconAndDimTransitionProgress(float progress, boolean invert) {
@@ -607,7 +616,10 @@
}
if (mMenuView != null) {
- mMenuView.setPosition(getX() - getRecentsView().getScrollX(), getY());
+ PagedOrientationHandler pagedOrientationHandler = getPagedOrientationHandler();
+ RecentsView recentsView = getRecentsView();
+ mMenuView.setPosition(getX() - recentsView.getScrollX(),
+ getY() - recentsView.getScrollY(), pagedOrientationHandler);
mMenuView.setScaleX(getScaleX());
mMenuView.setScaleY(getScaleY());
}
@@ -932,6 +944,10 @@
return (RecentsView) getParent();
}
+ PagedOrientationHandler getPagedOrientationHandler() {
+ return getRecentsView().mOrientationState.getOrientationHandler();
+ }
+
public void notifyTaskLaunchFailed(String tag) {
String msg = "Failed to launch task";
if (mTask != null) {
diff --git a/quickstep/res/layout/gesture_tutorial_fragment.xml b/quickstep/res/layout/gesture_tutorial_fragment.xml
index 69481ad..190290e 100644
--- a/quickstep/res/layout/gesture_tutorial_fragment.xml
+++ b/quickstep/res/layout/gesture_tutorial_fragment.xml
@@ -18,6 +18,12 @@
android:layout_height="match_parent"
android:background="@color/gesture_tutorial_background_color">
+ <View
+ android:id="@+id/gesture_tutorial_ripple_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/gesture_tutorial_ripple"/>
+
<ImageView
android:id="@+id/gesture_tutorial_fragment_hand_coaching"
android:layout_width="match_parent"
@@ -66,6 +72,17 @@
style="@style/TextAppearance.GestureTutorial.Subtitle"/>
</LinearLayout>
+ <TextView
+ android:id="@+id/gesture_tutorial_fragment_feedback_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="10dp"
+ android:layout_centerHorizontal="true"
+ android:layout_above="@id/gesture_tutorial_fragment_action_button"
+ android:layout_marginStart="@dimen/gesture_tutorial_feedback_margin_start_end"
+ android:layout_marginEnd="@dimen/gesture_tutorial_feedback_margin_start_end"
+ style="@style/TextAppearance.GestureTutorial.Feedback"/>
+
<!-- android:stateListAnimator="@null" removes shadow and normal on click behavior (increase
of elevation and shadow) which is replaced by ripple effect in android:foreground -->
<Button
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 18dc19c..b06dc6b 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -83,5 +83,6 @@
<!-- Tips Gesture Tutorial -->
<dimen name="gesture_tutorial_title_margin_start_end">40dp</dimen>
<dimen name="gesture_tutorial_subtitle_margin_start_end">16dp</dimen>
+ <dimen name="gesture_tutorial_feedback_margin_start_end">24dp</dimen>
<dimen name="gesture_tutorial_button_margin_start_end">18dp</dimen>
</resources>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 61690ae..b474a32 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -98,12 +98,22 @@
<string name="back_gesture_tutorial_playground_title_swipe_inward_right_edge" translatable="false">Try the back gesture</string>
<!-- Subtitle shown during interactive parts of Back gesture tutorial for right edge. [CHAR LIMIT=60] -->
<string name="back_gesture_tutorial_engaged_subtitle_swipe_inward_right_edge" translatable="false">Start at the right edge and swipe toward the middle</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_right_edge" translatable="false">Make sure you swipe from the far right edge</string>
+ <!-- Feedback shown during interactive parts of Back gesture tutorial for right edge when the gesture is cancelled. [CHAR LIMIT=100] -->
+ <string name="back_gesture_feedback_cancelled_right_edge" translatable="false">Make sure you swipe straight to the left and let go</string>
<!-- Title shown during interactive part of Back gesture tutorial for left edge. [CHAR LIMIT=30] -->
<string name="back_gesture_tutorial_playground_title_swipe_inward_left_edge" translatable="false">Try the other side</string>
<!-- Subtitle shown during interactive parts of Back gesture tutorial for left edge. [CHAR LIMIT=60] -->
<string name="back_gesture_tutorial_engaged_subtitle_swipe_inward_left_edge" translatable="false">That\'s it! Now try swiping from the left edge.</string>
+ <!-- Feedback shown during interactive parts of Back gesture tutorial for left edge when the gesture is too far from the edge. [CHAR LIMIT=100] -->
+ <string name="back_gesture_feedback_swipe_too_far_from_left_edge" translatable="false">Make sure you swipe from the far left edge</string>
+ <!-- Feedback shown during interactive parts of Back gesture tutorial for left edge when the gesture is cancelled. [CHAR LIMIT=100] -->
+ <string name="back_gesture_feedback_cancelled_left_edge" translatable="false">Make sure you swipe straight to the right and let go</string>
+ <!-- Feedback shown during interactive parts of Back gesture tutorial when the gesture is within the nav bar region. [CHAR LIMIT=100] -->
+ <string name="back_gesture_feedback_swipe_in_nav_bar" translatable="false">Make sure you don\'t swipe too close to the bottom of the screen</string>
<!-- Subtitle shown on the confirmation screen after successful gesture. [CHAR LIMIT=60] -->
<string name="back_gesture_tutorial_confirm_subtitle" translatable="false">To change the sensitivity of the back gesture, go to Settings</string>
@@ -112,6 +122,12 @@
<string name="home_gesture_tutorial_playground_title" translatable="false">Tutorial: Go Home</string>
<!-- Subtitle shown during interactive parts of Home gesture tutorial. [CHAR LIMIT=60] -->
<string name="home_gesture_tutorial_playground_subtitle" translatable="false">Try swiping upward from the bottom edge of the screen</string>
+ <!-- Feedback shown during interactive parts of Home gesture tutorial when the gesture is started too far from the edge. [CHAR LIMIT=100] -->
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" translatable="false">Make sure you swipe from the bottom edge of the screen</string>
+ <!-- Feedback shown during interactive parts of Home gesture tutorial when the Overview gesture is detected. [CHAR LIMIT=100] -->
+ <string name="home_gesture_feedback_overview_detected" translatable="false">Make sure you don\'t pause before letting go</string>
+ <!-- Feedback shown during interactive parts of Home gesture tutorial when the gesture is horizontal instead of vertical. [CHAR LIMIT=100] -->
+ <string name="home_gesture_feedback_wrong_swipe_direction" translatable="false">Make sure you swipe straight up</string>
<!-- Title shown on the confirmation screen after successful gesture. [CHAR LIMIT=30] -->
<string name="gesture_tutorial_confirm_title" translatable="false">All set</string>
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index 4915f5f..3926988 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -47,6 +47,14 @@
<item name="android:textSize">21sp</item>
</style>
+ <style name="TextAppearance.GestureTutorial.Feedback"
+ parent="TextAppearance.GestureTutorial">
+ <item name="android:gravity">center</item>
+ <item name="android:textColor">@color/gesture_tutorial_feedback_color</item>
+ <item name="android:letterSpacing">0.03</item>
+ <item name="android:textSize">21sp</item>
+ </style>
+
<style name="TextAppearance.GestureTutorial.ButtonLabel"
parent="TextAppearance.GestureTutorial.CallToAction">
<item name="android:gravity">center</item>
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index 70cbd82..1cb0aa4 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -611,7 +611,6 @@
.withWindowCrop(target.screenSpaceBounds)
.withAlpha(1f);
}
- builder.withLayer(RemoteAnimationProvider.getLayer(target, MODE_OPENING));
params[i] = builder.build();
}
surfaceApplier.scheduleApply(params);
@@ -718,7 +717,6 @@
params[i] = new SurfaceParams.Builder(target.leash)
.withAlpha(1f)
.withWindowCrop(target.screenSpaceBounds)
- .withLayer(RemoteAnimationProvider.getLayer(target, MODE_OPENING))
.withCornerRadius(cornerRadius)
.build();
}
@@ -775,7 +773,6 @@
}
params[i] = builder
.withWindowCrop(target.screenSpaceBounds)
- .withLayer(RemoteAnimationProvider.getLayer(target, MODE_CLOSING))
.build();
}
surfaceApplier.scheduleApply(params);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index ea71d97..81d4224 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -16,6 +16,8 @@
package com.android.launcher3.uioverrides.states;
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
+import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import android.content.Context;
@@ -76,7 +78,7 @@
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
ScaleAndTranslation scaleAndTranslation = LauncherState.OVERVIEW
.getWorkspaceScaleAndTranslation(launcher);
- if (SysUINavigationMode.getMode(launcher) == SysUINavigationMode.Mode.NO_BUTTON) {
+ if (SysUINavigationMode.getMode(launcher) == NO_BUTTON && !ENABLE_OVERVIEW_ACTIONS.get()) {
float normalScale = 1;
// Scale down halfway to where we'd be in overview, to prepare for a potential pause.
scaleAndTranslation.scale = (scaleAndTranslation.scale + normalScale) / 2;
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index e4bb9aa..a7a03e5 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -91,6 +91,11 @@
return activity != null && activity.hasBeenResumed();
}
+ default boolean isStarted() {
+ BaseDraggingActivity activity = getCreatedActivity();
+ return activity != null && activity.isStarted();
+ }
+
@UiThread
@Nullable
<T extends View> T getVisibleRecentsView();
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index 2e99500..2a9f32d 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -99,6 +99,10 @@
return;
}
this.mMode = newMode;
+ // Swipe touch regions are independent of nav mode, so we have to clear them explicitly
+ // here to avoid, for ex, a nav region for 2-button rotation 0 being used for 3-button mode
+ // It tries to cache and reuse swipe regions whenever possible based only on rotation
+ mSwipeTouchRegions.clear();
resetSwipeRegions(info);
}
diff --git a/quickstep/src/com/android/quickstep/SysUINavigationMode.java b/quickstep/src/com/android/quickstep/SysUINavigationMode.java
index c715c93..0569828 100644
--- a/quickstep/src/com/android/quickstep/SysUINavigationMode.java
+++ b/quickstep/src/com/android/quickstep/SysUINavigationMode.java
@@ -24,7 +24,9 @@
import android.content.res.Resources;
import android.util.Log;
+import com.android.launcher3.Launcher;
import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.quickstep.views.RecentsView;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -128,10 +130,14 @@
}
}
- /** @return Whether we can remove the shelf from overview. */
- public static boolean removeShelfFromOverview(Context context) {
- // The shelf is core to the two-button mode model, so we need to continue supporting it.
- return getMode(context) != Mode.TWO_BUTTONS;
+ public static boolean removeShelfFromOverview(Launcher launcher) {
+ // The shelf is core to the two-button mode model, so we need to continue supporting it
+ // when in portrait.
+ if (getMode(launcher) != Mode.TWO_BUTTONS) {
+ return true;
+ }
+ RecentsView recentsView = launcher.getOverviewPanel();
+ return !recentsView.getPagedOrientationHandler().isLayoutNaturalToLauncher();
}
public void dump(PrintWriter pw) {
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
index d58ab5d..fe95e83 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -22,6 +22,7 @@
import com.android.launcher3.R;
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
+import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult;
/** A {@link TutorialController} for the Back tutorial. */
final class BackGestureTutorialController extends TutorialController {
@@ -34,7 +35,7 @@
void transitToController() {
super.transitToController();
if (mTutorialType != BACK_NAVIGATION_COMPLETE) {
- mHandCoachingAnimation.startLoopedAnimation(mTutorialType);
+ showHandCoachingAnimation();
}
}
@@ -95,16 +96,10 @@
public void onBackGestureAttempted(BackGestureResult result) {
switch (mTutorialType) {
case RIGHT_EDGE_BACK_NAVIGATION:
- if (result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) {
- hideHandCoachingAnimation();
- mTutorialFragment.changeController(LEFT_EDGE_BACK_NAVIGATION);
- }
+ handleAttemptFromRight(result);
break;
case LEFT_EDGE_BACK_NAVIGATION:
- if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT) {
- hideHandCoachingAnimation();
- mTutorialFragment.changeController(BACK_NAVIGATION_COMPLETE);
- }
+ handleAttemptFromLeft(result);
break;
case BACK_NAVIGATION_COMPLETE:
if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT
@@ -114,4 +109,57 @@
break;
}
}
+
+ private void handleAttemptFromRight(BackGestureResult result) {
+ switch (result) {
+ case BACK_COMPLETED_FROM_RIGHT:
+ hideFeedback();
+ hideHandCoachingAnimation();
+ showRippleEffect(
+ () -> mTutorialFragment.changeController(LEFT_EDGE_BACK_NAVIGATION));
+ break;
+ case BACK_CANCELLED_FROM_RIGHT:
+ showFeedback(R.string.back_gesture_feedback_cancelled_right_edge);
+ break;
+ case BACK_COMPLETED_FROM_LEFT:
+ case BACK_CANCELLED_FROM_LEFT:
+ case BACK_NOT_STARTED_TOO_FAR_FROM_EDGE:
+ showFeedback(R.string.back_gesture_feedback_swipe_too_far_from_right_edge);
+ break;
+ case BACK_NOT_STARTED_IN_NAV_BAR_REGION:
+ showFeedback(R.string.back_gesture_feedback_swipe_in_nav_bar);
+ break;
+ }
+ }
+
+ private void handleAttemptFromLeft(BackGestureResult result) {
+ switch (result) {
+ case BACK_COMPLETED_FROM_LEFT:
+ hideFeedback();
+ hideHandCoachingAnimation();
+ showRippleEffect(
+ () -> mTutorialFragment.changeController(BACK_NAVIGATION_COMPLETE));
+ break;
+ case BACK_CANCELLED_FROM_LEFT:
+ showFeedback(R.string.back_gesture_feedback_cancelled_left_edge);
+ break;
+ case BACK_COMPLETED_FROM_RIGHT:
+ case BACK_CANCELLED_FROM_RIGHT:
+ case BACK_NOT_STARTED_TOO_FAR_FROM_EDGE:
+ showFeedback(R.string.back_gesture_feedback_swipe_too_far_from_left_edge);
+ break;
+ case BACK_NOT_STARTED_IN_NAV_BAR_REGION:
+ showFeedback(R.string.back_gesture_feedback_swipe_in_nav_bar);
+ break;
+ }
+ }
+
+ @Override
+ public void onNavBarGestureAttempted(NavBarGestureResult result) {
+ if (mTutorialType == BACK_NAVIGATION_COMPLETE) {
+ if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) {
+ mTutorialFragment.closeTutorial();
+ }
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
index 59067c1..bef50ea 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
@@ -15,6 +15,9 @@
*/
package com.android.quickstep.interaction;
+import android.view.MotionEvent;
+import android.view.View;
+
import com.android.launcher3.R;
import com.android.quickstep.interaction.TutorialController.TutorialType;
@@ -29,4 +32,17 @@
TutorialController createController(TutorialType type) {
return new BackGestureTutorialController(this, type);
}
+
+ @Override
+ Class<? extends TutorialController> getControllerClass() {
+ return BackGestureTutorialController.class;
+ }
+
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ if (motionEvent.getAction() == MotionEvent.ACTION_DOWN && mTutorialController != null) {
+ mTutorialController.setRippleHotspot(motionEvent.getX(), motionEvent.getY());
+ }
+ return super.onTouch(view, motionEvent);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java b/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
index 89c57a0..e4b348e 100644
--- a/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
+++ b/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
@@ -58,6 +58,7 @@
private final PointF mDownPoint = new PointF();
private boolean mThresholdCrossed = false;
private boolean mAllowGesture = false;
+ private BackGestureResult mDisallowedGestureReason;
private boolean mIsEnabled;
private int mLeftInset;
private int mRightInset;
@@ -145,11 +146,13 @@
private boolean isWithinTouchRegion(int x, int y) {
// Disallow if too far from the edge
if (x > mEdgeWidth + mLeftInset && x < (mDisplaySize.x - mEdgeWidth - mRightInset)) {
+ mDisallowedGestureReason = BackGestureResult.BACK_NOT_STARTED_TOO_FAR_FROM_EDGE;
return false;
}
// Disallow if we are in the bottom gesture area
if (y >= (mDisplaySize.y - mBottomGestureHeight)) {
+ mDisallowedGestureReason = BackGestureResult.BACK_NOT_STARTED_IN_NAV_BAR_REGION;
return false;
}
@@ -169,12 +172,12 @@
int action = ev.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
boolean isOnLeftEdge = ev.getX() <= mEdgeWidth + mLeftInset;
+ mDisallowedGestureReason = BackGestureResult.UNKNOWN;
mAllowGesture = isWithinTouchRegion((int) ev.getX(), (int) ev.getY());
+ mDownPoint.set(ev.getX(), ev.getY());
if (mAllowGesture) {
mEdgeBackPanel.setIsLeftPanel(isOnLeftEdge);
mEdgeBackPanel.onMotionEvent(ev);
-
- mDownPoint.set(ev.getX(), ev.getY());
mThresholdCrossed = false;
}
} else if (mAllowGesture) {
@@ -193,7 +196,6 @@
if (dy > dx && dy > mTouchSlop) {
cancelGesture(ev);
return;
-
} else if (dx > dy && dx > mTouchSlop) {
mThresholdCrossed = true;
}
@@ -206,8 +208,10 @@
}
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
- if (!mAllowGesture && mGestureCallback != null) {
- mGestureCallback.onBackGestureAttempted(BackGestureResult.BACK_NOT_STARTED);
+ float dx = Math.abs(ev.getX() - mDownPoint.x);
+ float dy = Math.abs(ev.getY() - mDownPoint.y);
+ if (dx > dy && dx > mTouchSlop && !mAllowGesture && mGestureCallback != null) {
+ mGestureCallback.onBackGestureAttempted(mDisallowedGestureReason);
}
}
}
@@ -223,7 +227,8 @@
BACK_COMPLETED_FROM_RIGHT,
BACK_CANCELLED_FROM_LEFT,
BACK_CANCELLED_FROM_RIGHT,
- BACK_NOT_STARTED,
+ BACK_NOT_STARTED_TOO_FAR_FROM_EDGE,
+ BACK_NOT_STARTED_IN_NAV_BAR_REGION,
}
/** Callback to let the UI react to attempted back gestures. */
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
index 0bf996d..0e45376 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
@@ -21,6 +21,7 @@
import com.android.launcher3.R;
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
+import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult;
/** A {@link TutorialController} for the Home tutorial. */
final class HomeGestureTutorialController extends TutorialController {
@@ -33,7 +34,7 @@
void transitToController() {
super.transitToController();
if (mTutorialType != HOME_NAVIGATION_COMPLETE) {
- mHandCoachingAnimation.startLoopedAnimation(mTutorialType);
+ showHandCoachingAnimation();
}
}
@@ -82,4 +83,33 @@
break;
}
}
+
+ @Override
+ public void onNavBarGestureAttempted(NavBarGestureResult result) {
+ switch (mTutorialType) {
+ case HOME_NAVIGATION:
+ switch (result) {
+ case HOME_GESTURE_COMPLETED:
+ hideHandCoachingAnimation();
+ mTutorialFragment.changeController(HOME_NAVIGATION_COMPLETE);
+ break;
+ case HOME_NOT_STARTED_TOO_FAR_FROM_EDGE:
+ case OVERVIEW_NOT_STARTED_TOO_FAR_FROM_EDGE:
+ showFeedback(R.string.home_gesture_feedback_swipe_too_far_from_edge);
+ break;
+ case OVERVIEW_GESTURE_COMPLETED:
+ showFeedback(R.string.home_gesture_feedback_overview_detected);
+ break;
+ case HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION:
+ showFeedback(R.string.home_gesture_feedback_wrong_swipe_direction);
+ break;
+ }
+ break;
+ case HOME_NAVIGATION_COMPLETE:
+ if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) {
+ mTutorialFragment.closeTutorial();
+ }
+ break;
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
index 613f188..e2a9d12 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
@@ -29,4 +29,9 @@
TutorialController createController(TutorialType type) {
return new HomeGestureTutorialController(this, type);
}
+
+ @Override
+ Class<? extends TutorialController> getControllerClass() {
+ return HomeGestureTutorialController.class;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
new file mode 100644
index 0000000..6d8caa2
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2020 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 static com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult.HOME_GESTURE_COMPLETED;
+import static com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult.HOME_NOT_STARTED_TOO_FAR_FROM_EDGE;
+import static com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult.HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION;
+import static com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult.OVERVIEW_GESTURE_COMPLETED;
+import static com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult.OVERVIEW_NOT_STARTED_TOO_FAR_FROM_EDGE;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Point;
+import android.view.Display;
+import android.view.MotionEvent;
+import android.view.Surface;
+import android.view.View;
+import android.view.View.OnTouchListener;
+
+import com.android.launcher3.ResourceUtils;
+import com.android.quickstep.SysUINavigationMode.Mode;
+import com.android.quickstep.util.NavBarPosition;
+import com.android.quickstep.util.TriggerSwipeUpTouchTracker;
+
+/** Utility class to handle home gestures. */
+public class NavBarGestureHandler implements OnTouchListener {
+
+ private static final String LOG_TAG = "NavBarGestureHandler";
+
+ private final Point mDisplaySize = new Point();
+ private final TriggerSwipeUpTouchTracker mSwipeUpTouchTracker;
+ private int mBottomGestureHeight;
+ private boolean mTouchCameFromNavBar;
+ private NavBarGestureAttemptCallback mGestureCallback;
+
+ NavBarGestureHandler(Context context) {
+ final Display display = context.getDisplay();
+ final int displayRotation;
+ if (display == null) {
+ displayRotation = Surface.ROTATION_0;
+ } else {
+ displayRotation = display.getRotation();
+ display.getRealSize(mDisplaySize);
+ }
+ mSwipeUpTouchTracker =
+ new TriggerSwipeUpTouchTracker(context, true /*disableHorizontalSwipe*/,
+ new NavBarPosition(Mode.NO_BUTTON, displayRotation),
+ null /*onInterceptTouch*/, this::onSwipeUp);
+
+ final Resources resources = context.getResources();
+ mBottomGestureHeight =
+ ResourceUtils.getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, resources);
+ }
+
+ void registerNavBarGestureAttemptCallback(NavBarGestureAttemptCallback callback) {
+ mGestureCallback = callback;
+ }
+
+ void unregisterNavBarGestureAttemptCallback() {
+ mGestureCallback = null;
+ }
+
+ private void onSwipeUp(boolean wasFling) {
+ if (mGestureCallback == null) {
+ return;
+ }
+ if (mTouchCameFromNavBar) {
+ mGestureCallback.onNavBarGestureAttempted(wasFling
+ ? HOME_GESTURE_COMPLETED : OVERVIEW_GESTURE_COMPLETED);
+ } else {
+ mGestureCallback.onNavBarGestureAttempted(wasFling
+ ? HOME_NOT_STARTED_TOO_FAR_FROM_EDGE : OVERVIEW_NOT_STARTED_TOO_FAR_FROM_EDGE);
+ }
+ }
+
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ int action = motionEvent.getAction();
+ boolean intercepted = mSwipeUpTouchTracker.interceptedTouch();
+ if (action == MotionEvent.ACTION_DOWN) {
+ mTouchCameFromNavBar = motionEvent.getRawY() >= mDisplaySize.y - mBottomGestureHeight;
+ mSwipeUpTouchTracker.init();
+ } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+ if (mGestureCallback != null && !intercepted && mTouchCameFromNavBar) {
+ mGestureCallback.onNavBarGestureAttempted(
+ HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION);
+ intercepted = true;
+ }
+ }
+ mSwipeUpTouchTracker.onMotionEvent(motionEvent);
+ return intercepted;
+ }
+
+ enum NavBarGestureResult {
+ UNKNOWN,
+ HOME_GESTURE_COMPLETED,
+ OVERVIEW_GESTURE_COMPLETED,
+ HOME_NOT_STARTED_TOO_FAR_FROM_EDGE,
+ OVERVIEW_NOT_STARTED_TOO_FAR_FROM_EDGE,
+ HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION // Side swipe on nav bar.
+ }
+
+ /** Callback to let the UI react to attempted nav bar gestures. */
+ interface NavBarGestureAttemptCallback {
+ /** Called whenever any touch is completed. */
+ void onNavBarGestureAttempted(NavBarGestureResult result);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index f0cb567..1e29f44 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -15,6 +15,7 @@
*/
package com.android.quickstep.interaction;
+import android.graphics.drawable.RippleDrawable;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
@@ -26,20 +27,30 @@
import androidx.annotation.Nullable;
import com.android.launcher3.R;
-import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
+import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureAttemptCallback;
+import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureAttemptCallback;
-abstract class TutorialController {
+abstract class TutorialController implements BackGestureAttemptCallback,
+ NavBarGestureAttemptCallback {
+
+ private static final int FEEDBACK_VISIBLE_MS = 3000;
+ private static final int FEEDBACK_ANIMATION_MS = 500;
+ private static final int RIPPLE_VISIBLE_MS = 300;
final TutorialFragment mTutorialFragment;
- final TutorialType mTutorialType;
+ TutorialType mTutorialType;
final ImageButton mCloseButton;
final TextView mTitleTextView;
final TextView mSubtitleTextView;
+ final TextView mFeedbackView;
+ final View mRippleView;
+ final RippleDrawable mRippleDrawable;
final TutorialHandAnimation mHandCoachingAnimation;
final ImageView mHandCoachingView;
final Button mActionTextButton;
final Button mActionButton;
+ private final Runnable mHideFeedbackRunnable;
TutorialController(TutorialFragment tutorialFragment, TutorialType tutorialType) {
mTutorialFragment = tutorialFragment;
@@ -50,15 +61,24 @@
mCloseButton.setOnClickListener(button -> mTutorialFragment.closeTutorial());
mTitleTextView = rootView.findViewById(R.id.gesture_tutorial_fragment_title_view);
mSubtitleTextView = rootView.findViewById(R.id.gesture_tutorial_fragment_subtitle_view);
+ mFeedbackView = rootView.findViewById(R.id.gesture_tutorial_fragment_feedback_view);
+ mRippleView = rootView.findViewById(R.id.gesture_tutorial_ripple_view);
+ mRippleDrawable = (RippleDrawable) mRippleView.getBackground();
mHandCoachingAnimation = tutorialFragment.getHandAnimation();
mHandCoachingView = rootView.findViewById(R.id.gesture_tutorial_fragment_hand_coaching);
mHandCoachingView.bringToFront();
mActionTextButton =
rootView.findViewById(R.id.gesture_tutorial_fragment_action_text_button);
mActionButton = rootView.findViewById(R.id.gesture_tutorial_fragment_action_button);
+
+ mHideFeedbackRunnable =
+ () -> mFeedbackView.animate().alpha(0).setDuration(FEEDBACK_ANIMATION_MS)
+ .withEndAction(this::showHandCoachingAnimation).start();
}
- abstract void onBackGestureAttempted(BackGestureResult result);
+ void setTutorialType(TutorialType tutorialType) {
+ mTutorialType = tutorialType;
+ }
@Nullable
Integer getTitleStringId() {
@@ -80,16 +100,52 @@
return null;
}
+ void showFeedback(int resId) {
+ hideHandCoachingAnimation();
+ mFeedbackView.setText(resId);
+ mFeedbackView.animate().alpha(1).setDuration(FEEDBACK_ANIMATION_MS).start();
+ mFeedbackView.removeCallbacks(mHideFeedbackRunnable);
+ mFeedbackView.postDelayed(mHideFeedbackRunnable, FEEDBACK_VISIBLE_MS);
+ }
+
+ void hideFeedback() {
+ mFeedbackView.setText(null);
+ mFeedbackView.removeCallbacks(mHideFeedbackRunnable);
+ mFeedbackView.clearAnimation();
+ mFeedbackView.setAlpha(0);
+ }
+
+ void setRippleHotspot(float x, float y) {
+ mRippleDrawable.setHotspot(x, y);
+ }
+
+ void showRippleEffect(@Nullable Runnable onCompleteRunnable) {
+ mRippleDrawable.setState(
+ new int[] {android.R.attr.state_pressed, android.R.attr.state_enabled});
+ mRippleView.postDelayed(() -> {
+ mRippleDrawable.setState(new int[] {});
+ if (onCompleteRunnable != null) {
+ onCompleteRunnable.run();
+ }
+ }, RIPPLE_VISIBLE_MS);
+ }
+
void onActionButtonClicked(View button) {}
void onActionTextButtonClicked(View button) {}
+ void showHandCoachingAnimation() {
+ mHandCoachingAnimation.startLoopedAnimation(mTutorialType);
+ }
+
void hideHandCoachingAnimation() {
mHandCoachingAnimation.stop();
+ mHandCoachingView.setVisibility(View.INVISIBLE);
}
@CallSuper
void transitToController() {
+ hideFeedback();
updateTitles();
updateActionButtons();
}
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index 6346a9b..3a56b0e 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -21,7 +21,9 @@
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
+import android.view.MotionEvent;
import android.view.View;
+import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.WindowInsets;
@@ -31,13 +33,11 @@
import androidx.fragment.app.FragmentActivity;
import com.android.launcher3.R;
-import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureAttemptCallback;
-import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
import com.android.quickstep.interaction.TutorialController.TutorialType;
import java.net.URISyntaxException;
-abstract class TutorialFragment extends Fragment implements BackGestureAttemptCallback {
+abstract class TutorialFragment extends Fragment implements OnTouchListener {
private static final String LOG_TAG = "TutorialFragment";
private static final String SYSTEM_NAVIGATION_SETTING_INTENT =
@@ -52,6 +52,7 @@
View mRootView;
TutorialHandAnimation mHandCoachingAnimation;
EdgeBackGestureHandler mEdgeBackGestureHandler;
+ NavBarGestureHandler mNavBarGestureHandler;
public static TutorialFragment newInstance(TutorialType tutorialType) {
TutorialFragment fragment = getFragmentForTutorialType(tutorialType);
@@ -85,19 +86,22 @@
abstract TutorialController createController(TutorialType type);
+ abstract Class<? extends TutorialController> getControllerClass();
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = savedInstanceState != null ? savedInstanceState : getArguments();
mTutorialType = (TutorialType) args.getSerializable(KEY_TUTORIAL_TYPE);
mEdgeBackGestureHandler = new EdgeBackGestureHandler(getContext());
- mEdgeBackGestureHandler.registerBackGestureAttemptCallback(this);
+ mNavBarGestureHandler = new NavBarGestureHandler(getContext());
}
@Override
public void onDestroy() {
super.onDestroy();
mEdgeBackGestureHandler.unregisterBackGestureAttemptCallback();
+ mNavBarGestureHandler.unregisterNavBarGestureAttemptCallback();
}
@Override
@@ -111,7 +115,7 @@
mEdgeBackGestureHandler.setInsets(systemInsets.left, systemInsets.right);
return insets;
});
- mRootView.setOnTouchListener(mEdgeBackGestureHandler);
+ mRootView.setOnTouchListener(this);
mHandCoachingAnimation = new TutorialHandAnimation(getContext(), mRootView,
getHandAnimationResId());
return mRootView;
@@ -129,6 +133,13 @@
mHandCoachingAnimation.stop();
}
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ // Note: Using logical or to ensure both functions get called.
+ return mEdgeBackGestureHandler.onTouch(view, motionEvent)
+ | mNavBarGestureHandler.onTouch(view, motionEvent);
+ }
+
void onAttachedToWindow() {
mEdgeBackGestureHandler.setViewGroupParent((ViewGroup) getRootView());
}
@@ -138,8 +149,14 @@
}
void changeController(TutorialType tutorialType) {
- mTutorialController = createController(tutorialType);
+ if (getControllerClass().isInstance(mTutorialController)) {
+ mTutorialController.setTutorialType(tutorialType);
+ } else {
+ mTutorialController = createController(tutorialType);
+ }
mTutorialController.transitToController();
+ mEdgeBackGestureHandler.registerBackGestureAttemptCallback(mTutorialController);
+ mNavBarGestureHandler.registerNavBarGestureAttemptCallback(mTutorialController);
mTutorialType = tutorialType;
}
@@ -157,13 +174,6 @@
return mHandCoachingAnimation;
}
- @Override
- public void onBackGestureAttempted(BackGestureResult result) {
- if (mTutorialController != null) {
- mTutorialController.onBackGestureAttempted(result);
- }
- }
-
void closeTutorial() {
FragmentActivity activity = getActivity();
if (activity != null) {
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialHandAnimation.java b/quickstep/src/com/android/quickstep/interaction/TutorialHandAnimation.java
index 5362aaf..c810e43 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialHandAnimation.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialHandAnimation.java
@@ -45,6 +45,7 @@
/** [Re]starts animation for the given tutorial. */
void startLoopedAnimation(TutorialType tutorialType) {
+ mHandCoachingView.setVisibility(View.VISIBLE);
if (mGestureAnimation.isRunning()) {
stop();
}
diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
index 4edf2fb..a2471d8 100644
--- a/quickstep/src/com/android/quickstep/util/LayoutUtils.java
+++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
@@ -16,7 +16,8 @@
package com.android.quickstep.util;
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
-import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
+import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
+import static com.android.quickstep.SysUINavigationMode.getMode;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -60,7 +61,7 @@
} else {
Resources res = context.getResources();
- if (ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(context)) {
+ if (showOverviewActions(context)) {
//TODO: this needs to account for the swipe gesture height and accessibility
// UI when shown.
extraSpace = res.getDimensionPixelSize(R.dimen.overview_actions_height);
@@ -76,7 +77,7 @@
public static void calculateFallbackTaskSize(Context context, DeviceProfile dp, Rect outRect) {
float extraSpace;
- if (ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(context)) {
+ if (showOverviewActions(context)) {
extraSpace = context.getResources()
.getDimensionPixelSize(R.dimen.overview_actions_height);
} else {
@@ -91,7 +92,7 @@
float taskWidth, taskHeight, paddingHorz;
Resources res = context.getResources();
Rect insets = dp.getInsets();
- final boolean overviewActionsEnabled = ENABLE_OVERVIEW_ACTIONS.get();
+ final boolean showLargeTaskSize = showOverviewActions(context);
if (dp.isMultiWindowMode) {
if (multiWindowStrategy == MULTI_WINDOW_STRATEGY_HALF_SCREEN) {
@@ -121,7 +122,7 @@
final int paddingResId;
if (dp.isVerticalBarLayout()) {
paddingResId = R.dimen.landscape_task_card_horz_space;
- } else if (overviewActionsEnabled && removeShelfFromOverview(context)) {
+ } else if (showLargeTaskSize) {
paddingResId = R.dimen.portrait_task_card_horz_space_big_overview;
} else {
paddingResId = R.dimen.portrait_task_card_horz_space;
@@ -130,7 +131,7 @@
}
float topIconMargin = res.getDimension(R.dimen.task_thumbnail_top_margin);
- float paddingVert = overviewActionsEnabled && removeShelfFromOverview(context)
+ float paddingVert = showLargeTaskSize
? 0 : res.getDimension(R.dimen.task_card_vert_space);
// Note this should be same as dp.availableWidthPx and dp.availableHeightPx unless
@@ -156,7 +157,7 @@
public static int getShelfTrackingDistance(Context context, DeviceProfile dp) {
// Track the bottom of the window.
- if (ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(context)) {
+ if (showOverviewActions(context)) {
Rect taskSize = new Rect();
calculateLauncherTaskSize(context, dp, taskSize);
return (dp.heightPx - taskSize.height()) / 2;
@@ -180,4 +181,8 @@
return srcHeight / targetHeight;
}
}
+
+ private static boolean showOverviewActions(Context context) {
+ return ENABLE_OVERVIEW_ACTIONS.get() && getMode(context) != TWO_BUTTONS;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/util/NavBarPosition.java b/quickstep/src/com/android/quickstep/util/NavBarPosition.java
index 74e6b29..0a98e1b 100644
--- a/quickstep/src/com/android/quickstep/util/NavBarPosition.java
+++ b/quickstep/src/com/android/quickstep/util/NavBarPosition.java
@@ -35,6 +35,11 @@
mDisplayRotation = info.rotation;
}
+ public NavBarPosition(SysUINavigationMode.Mode mode, int displayRotation) {
+ mMode = mode;
+ mDisplayRotation = displayRotation;
+ }
+
public boolean isRightEdge() {
return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_90;
}
diff --git a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
index a678cb5..aa6d56a 100644
--- a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
+++ b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
@@ -42,9 +42,6 @@
if (!getBoolean(HOME_BOUNCE_SEEN)) {
mStateManager.addStateListener(new StateListener() {
@Override
- public void onStateTransitionStart(LauncherState toState) { }
-
- @Override
public void onStateTransitionComplete(LauncherState finalState) {
boolean swipeUpEnabled = SysUINavigationMode.INSTANCE
.get(mLauncher).getMode().hasGestures;
@@ -70,9 +67,6 @@
if (!shelfBounceSeen) {
mStateManager.addStateListener(new StateListener() {
@Override
- public void onStateTransitionStart(LauncherState toState) { }
-
- @Override
public void onStateTransitionComplete(LauncherState finalState) {
LauncherState prevState = mStateManager.getLastState();
@@ -88,9 +82,6 @@
if (!hasReachedMaxCount(ALL_APPS_COUNT)) {
mStateManager.addStateListener(new StateListener() {
@Override
- public void onStateTransitionStart(LauncherState toState) { }
-
- @Override
public void onStateTransitionComplete(LauncherState finalState) {
if (finalState == ALL_APPS) {
if (incrementEventCount(ALL_APPS_COUNT)) {
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index 74daeca..c6384d3 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -25,6 +25,7 @@
import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.content.ContentResolver;
@@ -49,6 +50,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.quickstep.SysUINavigationMode;
import java.lang.annotation.Retention;
import java.util.function.IntConsumer;
@@ -154,7 +156,9 @@
if (isFixedRotationTransformEnabled(context)) {
mFlags |= FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_FLAG;
}
- if (mOrientationListener.canDetectOrientation()) {
+ // TODO(b/154665738): Determine if we need animation for 2 button mode or not
+ if (mOrientationListener.canDetectOrientation()
+ && SysUINavigationMode.getMode(context) != TWO_BUTTONS) {
mFlags |= FLAG_ROTATION_WATCHER_SUPPORTED;
}
}
diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
index 21b97ec..4cd0206 100644
--- a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
+++ b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
@@ -62,15 +62,12 @@
static void prepareTargetsForFirstFrame(RemoteAnimationTargetCompat[] targets,
TransactionCompat t, int boostModeTargets) {
for (RemoteAnimationTargetCompat target : targets) {
- t.setLayer(target.leash, getLayer(target, boostModeTargets));
t.show(target.leash);
}
}
public static int getLayer(RemoteAnimationTargetCompat target, int boostModeTarget) {
- return target.mode == boostModeTarget
- ? Z_BOOST_BASE + target.prefixOrderIndex
- : target.prefixOrderIndex;
+ return target.prefixOrderIndex;
}
/**
diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
index f5498c9..af77c62 100644
--- a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
+++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
@@ -165,7 +165,7 @@
if ((OVERVIEW.getVisibleElements(mLauncher) & ALL_APPS_HEADER_EXTRA) == 0) {
mDragHandleProgress = 1;
if (FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get()
- && SysUINavigationMode.removeShelfFromOverview(context)) {
+ && SysUINavigationMode.removeShelfFromOverview(mLauncher)) {
// Fade in all apps background quickly to distinguish from swiping from nav bar.
mMidAlpha = Themes.getAttrInteger(context, R.attr.allAppsInterimScrimAlpha);
mMidProgress = OverviewState.getDefaultVerticalProgress(mLauncher);
diff --git a/res/drawable/gesture_tutorial_ripple.xml b/res/drawable/gesture_tutorial_ripple.xml
new file mode 100644
index 0000000..ca45662
--- /dev/null
+++ b/res/drawable/gesture_tutorial_ripple.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ripple android:color="@color/gesture_tutorial_ripple_color"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@android:id/mask"
+ android:drawable="@color/gesture_tutorial_background_color" />
+</ripple>
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index adcff9a..c9c893e 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -39,8 +39,10 @@
<color name="all_apps_bg_hand_fill_dark">#9AA0A6</color>
<color name="gesture_tutorial_background_color">#FFFFFFFF</color>
- <color name="gesture_tutorial_subtitle_color">#99000000</color> <!-- 60% black -->
<color name="gesture_tutorial_title_color">#FF000000</color>
+ <color name="gesture_tutorial_subtitle_color">#99000000</color> <!-- 60% black -->
+ <color name="gesture_tutorial_feedback_color">#FF000000</color>
+ <color name="gesture_tutorial_ripple_color">#A0C2F9</color> <!-- Light Blue -->
<color name="gesture_tutorial_action_button_label_color">#FFFFFFFF</color>
<color name="gesture_tutorial_primary_color">#1A73E8</color> <!-- Blue -->
diff --git a/src/com/android/launcher3/InsettableFrameLayout.java b/src/com/android/launcher3/InsettableFrameLayout.java
index faa18b8..9a66d32 100644
--- a/src/com/android/launcher3/InsettableFrameLayout.java
+++ b/src/com/android/launcher3/InsettableFrameLayout.java
@@ -91,6 +91,9 @@
@Override
public void onViewAdded(View child) {
super.onViewAdded(child);
+ if (!isAttachedToWindow()) {
+ return;
+ }
setFrameLayoutChildInsets(child, mInsets, new Rect());
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index c4eab8f..49723d5 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -18,7 +18,6 @@
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
-
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
import static com.android.launcher3.AbstractFloatingView.TYPE_SNACKBAR;
@@ -434,9 +433,6 @@
mRotationHelper.initialize();
mStateManager.addStateListener(new LauncherStateManager.StateListener() {
- @Override
- public void onStateTransitionStart(LauncherState toState) {
- }
@Override
public void onStateTransitionComplete(LauncherState finalState) {
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 308d84f..21cd04e 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -407,12 +407,8 @@
return result;
}
case LauncherSettings.Settings.METHOD_REFRESH_BACKUP_TABLE: {
- // TODO(pinyaoting): Update the behavior here.
- if (!MULTI_DB_GRID_MIRATION_ALGO.get()) {
- mOpenHelper.mBackupTableExists =
- tableExists(mOpenHelper.getReadableDatabase(),
- Favorites.BACKUP_TABLE_NAME);
- }
+ mOpenHelper.mBackupTableExists = tableExists(mOpenHelper.getReadableDatabase(),
+ Favorites.BACKUP_TABLE_NAME);
return null;
}
case LauncherSettings.Settings.METHOD_RESTORE_BACKUP_TABLE: {
@@ -454,11 +450,7 @@
}
private void onAddOrDeleteOp(SQLiteDatabase db) {
- if (MULTI_DB_GRID_MIRATION_ALGO.get()) {
- // TODO(pingyaoting): Implement the behavior here.
- } else {
- mOpenHelper.onAddOrDeleteOp(db);
- }
+ mOpenHelper.onAddOrDeleteOp(db);
}
/**
@@ -682,7 +674,7 @@
}
protected void onAddOrDeleteOp(SQLiteDatabase db) {
- if (!MULTI_DB_GRID_MIRATION_ALGO.get() && mBackupTableExists) {
+ if (mBackupTableExists) {
dropTable(db, Favorites.BACKUP_TABLE_NAME);
mBackupTableExists = false;
}
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index e071777..1d2e866 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -600,7 +600,8 @@
public interface StateListener {
- void onStateTransitionStart(LauncherState toState);
- void onStateTransitionComplete(LauncherState finalState);
+ default void onStateTransitionStart(LauncherState toState) { }
+
+ default void onStateTransitionComplete(LauncherState finalState) { }
}
}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 65d3cd2..df30f7b 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -127,7 +127,7 @@
"ENABLE_DEEP_SHORTCUT_ICON_CACHE", true, "R/W deep shortcut in IconCache");
public static final BooleanFlag MULTI_DB_GRID_MIRATION_ALGO = getDebugFlag(
- "MULTI_DB_GRID_MIRATION_ALGO", false, "Use the multi-db grid migration algorithm");
+ "MULTI_DB_GRID_MIRATION_ALGO", true, "Use the multi-db grid migration algorithm");
public static final BooleanFlag ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER = getDebugFlag(
"ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER", true, "Show launcher preview in grid picker");
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index d07635b..1e23bb6 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -176,9 +176,6 @@
}
@Override
- public void onStateTransitionStart(LauncherState toState) { }
-
- @Override
public void onStateTransitionComplete(LauncherState finalState) {
setVisibility((finalState == LauncherState.NORMAL
|| finalState == LauncherState.SPRING_LOADED) ? VISIBLE : INVISIBLE);
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index e290685..dc50053 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -16,6 +16,7 @@
package com.android.launcher3.touch;
+import static android.widget.ListPopupWindow.WRAP_CONTENT;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL;
@@ -30,6 +31,7 @@
import android.view.VelocityTracker;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
+import android.widget.LinearLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.PagedView;
@@ -224,6 +226,33 @@
}
@Override
+ public float getTaskMenuX(float x, View thumbnailView) {
+ return thumbnailView.getMeasuredWidth() + x;
+ }
+
+ @Override
+ public float getTaskMenuY(float y, View thumbnailView) {
+ return y;
+ }
+
+ @Override
+ public int getTaskMenuWidth(View view) {
+ return view.getMeasuredHeight();
+ }
+
+ @Override
+ public int getTaskMenuLayoutOrientation() {
+ return LinearLayout.HORIZONTAL;
+ }
+
+ @Override
+ public void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp) {
+ lp.width = 0;
+ lp.height = WRAP_CONTENT;
+ lp.weight = 1;
+ }
+
+ @Override
public ChildBounds getChildBounds(View child, int childStart, int pageCenter,
boolean layoutChild) {
final int childHeight = child.getMeasuredHeight();
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index b8396e1..cc15f99 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -27,6 +27,7 @@
import android.view.VelocityTracker;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
+import android.widget.LinearLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.PagedView;
@@ -90,6 +91,11 @@
void getCurveProperties(PagedView view, Rect insets, CurveProperties out);
boolean isGoingUp(float displacement);
boolean isLayoutNaturalToLauncher();
+ float getTaskMenuX(float x, View thumbnailView);
+ float getTaskMenuY(float y, View thumbnailView);
+ int getTaskMenuWidth(View view);
+ int getTaskMenuLayoutOrientation();
+ void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp);
/**
* Maps the velocity from the coordinate plane of the foreground app to that
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index dad00a4..7c30e29 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -30,6 +30,7 @@
import android.view.VelocityTracker;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
+import android.widget.LinearLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.PagedView;
@@ -222,6 +223,31 @@
}
@Override
+ public float getTaskMenuX(float x, View thumbnailView) {
+ return x;
+ }
+
+ @Override
+ public float getTaskMenuY(float y, View thumbnailView) {
+ return y;
+ }
+
+ @Override
+ public int getTaskMenuWidth(View view) {
+ return view.getMeasuredWidth();
+ }
+
+ @Override
+ public int getTaskMenuLayoutOrientation() {
+ return LinearLayout.VERTICAL;
+ }
+
+ @Override
+ public void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp) {
+ // no-op, defaults are fine
+ }
+
+ @Override
public ChildBounds getChildBounds(View child, int childStart, int pageCenter,
boolean layoutChild) {
final int childWidth = child.getMeasuredWidth();
diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
index 5ce8a57..7beb7f7 100644
--- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
@@ -20,6 +20,7 @@
import android.graphics.PointF;
import android.graphics.RectF;
import android.view.Surface;
+import android.view.View;
import com.android.launcher3.Utilities;
@@ -64,4 +65,14 @@
float oldY = velocity.y;
velocity.set(oldY, -oldX);
}
+
+ @Override
+ public float getTaskMenuX(float x, View thumbnailView) {
+ return x;
+ }
+
+ @Override
+ public float getTaskMenuY(float y, View thumbnailView) {
+ return y + thumbnailView.getMeasuredHeight();
+ }
}
diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java
index 442c5fd..da874cf 100644
--- a/src/com/android/launcher3/views/ScrimView.java
+++ b/src/com/android/launcher3/views/ScrimView.java
@@ -118,9 +118,6 @@
private final StateListener mAccessibilityLauncherStateListener = new StateListener() {
@Override
- public void onStateTransitionStart(LauncherState toState) {}
-
- @Override
public void onStateTransitionComplete(LauncherState finalState) {
setImportantForAccessibility(finalState == ALL_APPS
? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
diff --git a/src/com/android/launcher3/views/WorkEduView.java b/src/com/android/launcher3/views/WorkEduView.java
index d849138..552f662 100644
--- a/src/com/android/launcher3/views/WorkEduView.java
+++ b/src/com/android/launcher3/views/WorkEduView.java
@@ -189,11 +189,6 @@
LauncherStateManager.StateListener listener = new LauncherStateManager.StateListener() {
@Override
- public void onStateTransitionStart(LauncherState toState) {
-
- }
-
- @Override
public void onStateTransitionComplete(LauncherState finalState) {
if (finalState != LauncherState.ALL_APPS) return;
LayoutInflater layoutInflater = LayoutInflater.from(launcher);