Merge changes I9749124a,Ic59b877c,Ibe8734e8 into sc-dev
* changes:
Fix running task damped by overscroll when other tasks are offscreen
When overview appears from motion pause, come up from bottom
Align home/back button from overview with tap outside
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 10384a8..fe10908 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -338,6 +338,10 @@
}
protected boolean onActivityInit(Boolean alreadyOnHome) {
+ if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) {
+ return false;
+ }
+
T createdActivity = mActivityInterface.getCreatedActivity();
if (createdActivity != null) {
initTransitionEndpoints(createdActivity.getDeviceProfile());
@@ -567,6 +571,8 @@
}
});
reapplyWindowTransformAnim.setDuration(RECENTS_ATTACH_DURATION).start();
+ mStateCallback.runOnceAtState(STATE_HANDLER_INVALIDATED,
+ reapplyWindowTransformAnim::cancel);
} else {
applyWindowTransform();
}
@@ -1376,12 +1382,6 @@
mActivityInitListener.unregister();
ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mActivityRestartListener);
mTaskSnapshot = null;
- mHandler.post(() -> {
- // Defer clearing the activity since invalidation can happen over multiple callbacks
- // ie. invalidateHandlerWithLauncher()
- mActivity = null;
- mRecentsView = null;
- });
}
private void invalidateHandlerWithLauncher() {
@@ -1392,6 +1392,12 @@
mRecentsView.removeOnScrollChangedListener(mOnRecentsScrollListener);
resetLauncherListeners();
+
+ mHandler.post(() -> {
+ // Defer clearing the activity since invalidation can happen over multiple callbacks.
+ mActivity = null;
+ mRecentsView = null;
+ });
}
private void endLauncherTransitionController() {
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 4fc9770..338a6ef 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -496,6 +496,13 @@
Point sz = new Point();
display.getRealSize(sz);
if (rotation != Surface.ROTATION_0) {
+ if ((rotation % 2) != 0) {
+ // via display-manager, the display size is unrotated, so "rotate" its size
+ // to match the rotation we are transforming the event into.
+ final int tmpX = sz.x;
+ sz.x = sz.y;
+ sz.y = tmpX;
+ }
event.transform(InputChannelCompat.createRotationMatrix(rotation, sz.x, sz.y));
}
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 23f7200..7b2e16e 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1687,8 +1687,7 @@
if (endTarget == GestureState.GestureEndTarget.NEW_TASK
|| endTarget == GestureState.GestureEndTarget.LAST_TASK) {
// When switching to tasks in quick switch, ensures the snapped page's scroll maintain
- // invariant between quick switch and overview grid, to ensure a smooth animation
- // transition.
+ // invariant between quick switch and overview, to ensure a smooth animation transition.
updateGridProperties();
}
}
@@ -3196,6 +3195,11 @@
return new PendingAnimation(duration);
}
+ // When swiping down from overview to tasks, ensures the snapped page's scroll maintain
+ // invariant between quick switch and overview, to ensure a smooth animation transition.
+ updateGridProperties();
+ updateScrollSynchronously();
+
int targetSysUiFlags = tv.getThumbnail().getSysUiStatusNavFlags();
final boolean[] passedOverviewThreshold = new boolean[] {false};
ValueAnimator progressAnim = ValueAnimator.ofFloat(0, 1);
diff --git a/res/layout/widgets_full_sheet_search_and_recommendations.xml b/res/layout/widgets_full_sheet_search_and_recommendations.xml
index bfce01d..ce7a682 100644
--- a/res/layout/widgets_full_sheet_search_and_recommendations.xml
+++ b/res/layout/widgets_full_sheet_search_and_recommendations.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<LinearLayout
+<com.android.launcher3.widget.picker.SearchAndRecommendationsView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/search_and_recommendations_container"
android:layout_width="match_parent"
@@ -49,4 +49,4 @@
android:paddingVertical="@dimen/recommended_widgets_table_vertical_padding"
android:layout_marginTop="16dp"
android:visibility="gone"/>
-</LinearLayout>
+</com.android.launcher3.widget.picker.SearchAndRecommendationsView>
diff --git a/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java b/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
index 7f84077..d09cb8a 100644
--- a/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
+++ b/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.widget.picker;
+import android.graphics.Point;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
import android.widget.RelativeLayout;
@@ -33,9 +35,11 @@
RecyclerViewFastScroller.OnFastScrollChangeListener {
private final boolean mHasWorkProfile;
private final SearchAndRecommendationViewHolder mViewHolder;
+ private final View mSearchAndRecommendationViewParent;
private final WidgetsRecyclerView mPrimaryRecyclerView;
private final WidgetsRecyclerView mSearchRecyclerView;
private final int mTabsHeight;
+ private final Point mTempOffset = new Point();
// The following are only non null if mHasWorkProfile is true.
@Nullable private final WidgetsRecyclerView mWorkRecyclerView;
@@ -62,6 +66,8 @@
*/
private int mCollapsibleHeightForTabs = 0;
+ private boolean mShouldForwardToRecyclerView = false;
+
SearchAndRecommendationsScrollController(
boolean hasWorkProfile,
int tabsHeight,
@@ -73,6 +79,8 @@
@Nullable PersonalWorkPagedView primaryWorkViewPager) {
mHasWorkProfile = hasWorkProfile;
mViewHolder = viewHolder;
+ mViewHolder.mContainer.setSearchAndRecommendationScrollController(this);
+ mSearchAndRecommendationViewParent = (View) mViewHolder.mContainer.getParent();
mPrimaryRecyclerView = primaryRecyclerView;
mCurrentRecyclerView = mPrimaryRecyclerView;
mWorkRecyclerView = workRecyclerView;
@@ -245,6 +253,43 @@
}
}
+ /**
+ * Returns {@code true} if a touch event should be intercepted by this controller.
+ */
+ public boolean onInterceptTouchEvent(MotionEvent event) {
+ calculateMotionEventOffset(mTempOffset);
+ event.offsetLocation(mTempOffset.x, mTempOffset.y);
+ try {
+ mShouldForwardToRecyclerView = mCurrentRecyclerView.onInterceptTouchEvent(event);
+ return mShouldForwardToRecyclerView;
+ } finally {
+ event.offsetLocation(-mTempOffset.x, -mTempOffset.y);
+ }
+ }
+
+ /**
+ * Returns {@code true} if this controller has intercepted and consumed a touch event.
+ */
+ public boolean onTouchEvent(MotionEvent event) {
+ if (mShouldForwardToRecyclerView) {
+ calculateMotionEventOffset(mTempOffset);
+ event.offsetLocation(mTempOffset.x, mTempOffset.y);
+ try {
+ return mCurrentRecyclerView.onTouchEvent(event);
+ } finally {
+ event.offsetLocation(-mTempOffset.x, -mTempOffset.y);
+ }
+ }
+ return false;
+ }
+
+ private void calculateMotionEventOffset(Point p) {
+ p.x = mViewHolder.mContainer.getLeft() - mCurrentRecyclerView.getLeft()
+ - mSearchAndRecommendationViewParent.getLeft();
+ p.y = mViewHolder.mContainer.getTop() - mCurrentRecyclerView.getTop()
+ - mSearchAndRecommendationViewParent.getTop();
+ }
+
/** private the height, in pixel, + the vertical margins of a given view. */
private static int measureHeightWithVerticalMargins(View view) {
if (view.getVisibility() != View.VISIBLE) {
diff --git a/src/com/android/launcher3/widget/picker/SearchAndRecommendationsView.java b/src/com/android/launcher3/widget/picker/SearchAndRecommendationsView.java
new file mode 100644
index 0000000..0d7d2b5
--- /dev/null
+++ b/src/com/android/launcher3/widget/picker/SearchAndRecommendationsView.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2021 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.launcher3.widget.picker;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.widget.LinearLayout;
+
+/**
+ * A {@link LinearLayout} container for holding search and widgets recommendation.
+ *
+ * <p>This class intercepts touch events and dispatch them to the right view.
+ */
+public class SearchAndRecommendationsView extends LinearLayout {
+ private SearchAndRecommendationsScrollController mController;
+
+ public SearchAndRecommendationsView(Context context) {
+ this(context, /* attrs= */ null);
+ }
+
+ public SearchAndRecommendationsView(Context context, AttributeSet attrs) {
+ this(context, attrs, /* defStyleAttr= */ 0);
+ }
+
+ public SearchAndRecommendationsView(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, /* defStyleRes= */ 0);
+ }
+
+ public SearchAndRecommendationsView(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public void setSearchAndRecommendationScrollController(
+ SearchAndRecommendationsScrollController controller) {
+ mController = controller;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent event) {
+ return mController.onInterceptTouchEvent(event) || super.onInterceptTouchEvent(event);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ return mController.onTouchEvent(event) || super.onTouchEvent(event);
+ }
+}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index b4d4856..b1c5ffc 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -709,13 +709,14 @@
}
final class SearchAndRecommendationViewHolder {
- final ViewGroup mContainer;
+ final SearchAndRecommendationsView mContainer;
final View mCollapseHandle;
final WidgetsSearchBar mSearchBar;
final TextView mHeaderTitle;
final WidgetsRecommendationTableLayout mRecommendedWidgetsTable;
- SearchAndRecommendationViewHolder(ViewGroup searchAndRecommendationContainer) {
+ SearchAndRecommendationViewHolder(
+ SearchAndRecommendationsView searchAndRecommendationContainer) {
mContainer = searchAndRecommendationContainer;
mCollapseHandle = mContainer.findViewById(R.id.collapse_handle);
mSearchBar = mContainer.findViewById(R.id.widgets_search_bar);