Merge changes If11fea2d,Ia7e1eebe,Iafa89db1 into ub-launcher3-master
* changes:
Remove redundant resumeLastTaskForQuickstep() and use resumeLastTask() directly
Fix some state issues with home and quick switch gestures
Apply spring forces to animate to the final position for swipe home
diff --git a/go/quickstep/res/layout/task_item_view.xml b/go/quickstep/res/layout/task_item_view.xml
index ee67d49..048e9c5 100644
--- a/go/quickstep/res/layout/task_item_view.xml
+++ b/go/quickstep/res/layout/task_item_view.xml
@@ -21,15 +21,15 @@
android:orientation="horizontal">
<FrameLayout
android:id="@+id/task_icon_and_thumbnail"
- android:layout_width="@dimen/task_item_height"
- android:layout_height="@dimen/task_item_height"
+ android:layout_width="@dimen/task_thumbnail_and_icon_view_size"
+ android:layout_height="@dimen/task_thumbnail_and_icon_view_size"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="@dimen/task_item_half_vert_margin">
<ImageView
android:id="@+id/task_thumbnail"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_width="@dimen/task_thumbnail_width"
+ android:layout_height="@dimen/task_thumbnail_height"
android:layout_gravity="top|start"/>
<ImageView
android:id="@+id/task_icon"
diff --git a/go/quickstep/res/values/dimens.xml b/go/quickstep/res/values/dimens.xml
index 28cc1eb..7269704 100644
--- a/go/quickstep/res/values/dimens.xml
+++ b/go/quickstep/res/values/dimens.xml
@@ -15,7 +15,9 @@
limitations under the License.
-->
<resources>
- <dimen name="task_item_height">60dp</dimen>
<dimen name="task_item_half_vert_margin">8dp</dimen>
+ <dimen name="task_thumbnail_and_icon_view_size">60dp</dimen>
+ <dimen name="task_thumbnail_height">60dp</dimen>
+ <dimen name="task_thumbnail_width">36dp</dimen>
<dimen name="task_icon_size">36dp</dimen>
</resources>
\ No newline at end of file
diff --git a/go/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java b/go/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
index 5382607..cec12a8 100644
--- a/go/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
+++ b/go/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
@@ -43,7 +43,7 @@
}
@Override
- public float[] getOverviewScaleAndTranslationYFactor(Launcher launcher) {
+ public float[] getOverviewScaleAndTranslationY(Launcher launcher) {
return new float[] {1f, 0f};
}
diff --git a/go/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/go/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index 784af7d..0b12ab0 100644
--- a/go/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/go/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -16,16 +16,15 @@
package com.android.launcher3.uioverrides;
import static com.android.quickstep.views.IconRecentsView.CONTENT_ALPHA;
-import static com.android.quickstep.views.IconRecentsView.TRANSLATION_Y_FACTOR;
import android.util.FloatProperty;
-import androidx.annotation.NonNull;
-
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherRecentsToActivityHelper;
import com.android.quickstep.views.IconRecentsView;
+import androidx.annotation.NonNull;
+
/**
* State handler for Go's {@link IconRecentsView}.
*/
@@ -39,11 +38,6 @@
}
@Override
- FloatProperty<IconRecentsView> getTranslationYFactorProperty() {
- return TRANSLATION_Y_FACTOR;
- }
-
- @Override
FloatProperty<IconRecentsView> getContentAlphaProperty() {
return CONTENT_ALPHA;
}
diff --git a/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index f199643..defed84 100644
--- a/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -15,15 +15,29 @@
*/
package com.android.quickstep;
+import static com.android.launcher3.anim.Interpolators.ACCEL_2;
+import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
+import static com.android.quickstep.util.RemoteAnimationProvider.getLayer;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
+import android.graphics.Matrix;
+import android.graphics.Rect;
import android.util.Log;
+import android.view.View;
+
+import androidx.annotation.NonNull;
import com.android.launcher3.BaseDraggingActivity;
+import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.util.RemoteAnimationProvider;
+import com.android.quickstep.views.IconRecentsView;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
/**
* Provider for the atomic remote window animation from the app to the overview.
@@ -33,13 +47,17 @@
final class AppToOverviewAnimationProvider<T extends BaseDraggingActivity> implements
RemoteAnimationProvider {
- private static final long RECENTS_LAUNCH_DURATION = 250;
+ private static final long APP_TO_THUMBNAIL_FADE_DURATION = 50;
+ private static final long APP_SCALE_DOWN_DURATION = 400;
private static final String TAG = "AppToOverviewAnimationProvider";
private final ActivityControlHelper<T> mHelper;
+ private final int mTargetTaskId;
+ private IconRecentsView mRecentsView;
AppToOverviewAnimationProvider(ActivityControlHelper<T> helper, int targetTaskId) {
mHelper = helper;
+ mTargetTaskId = targetTaskId;
}
/**
@@ -54,35 +72,157 @@
false /* animate activity */, (controller) -> {
controller.dispatchOnStart();
ValueAnimator anim = controller.getAnimationPlayer()
- .setDuration(RECENTS_LAUNCH_DURATION);
+ .setDuration(getRecentsLaunchDuration());
anim.setInterpolator(FAST_OUT_SLOW_IN);
anim.start();
});
factory.onRemoteAnimationReceived(null);
- factory.createActivityController(RECENTS_LAUNCH_DURATION);
+ factory.createActivityController(getRecentsLaunchDuration());
+ mRecentsView = activity.getOverviewPanel();
return false;
}
/**
- * Create remote window animation from the currently running app to the overview panel.
+ * Create remote window animation from the currently running app to the overview panel. Should
+ * be called after {@link #onActivityReady}.
*
* @param targetCompats the target apps
* @return animation from app to overview
*/
@Override
public AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] targetCompats) {
- //TODO: Implement the overview to app window animation for Go.
AnimatorSet anim = new AnimatorSet();
- anim.play(ValueAnimator.ofInt(0, 1).setDuration(RECENTS_LAUNCH_DURATION));
+ if (mRecentsView == null) {
+ if (Log.isLoggable(TAG, Log.WARN)) {
+ Log.w(TAG, "No recents view. Using stub animation.");
+ }
+ anim.play(ValueAnimator.ofInt(0, 1).setDuration(getRecentsLaunchDuration()));
+ return anim;
+ }
+
+ RemoteAnimationTargetCompat recentsTarget = null;
+ RemoteAnimationTargetCompat closingAppTarget = null;
+
+ for (RemoteAnimationTargetCompat target : targetCompats) {
+ if (target.mode == MODE_OPENING) {
+ recentsTarget = target;
+ } else if (target.mode == MODE_CLOSING && target.taskId == mTargetTaskId) {
+ closingAppTarget = target;
+ }
+ }
+
+ if (closingAppTarget == null) {
+ if (Log.isLoggable(TAG, Log.WARN)) {
+ Log.w(TAG, "No closing app target. Using stub animation.");
+ }
+ anim.play(ValueAnimator.ofInt(0, 1).setDuration(getRecentsLaunchDuration()));
+ return anim;
+ }
+ if (recentsTarget == null) {
+ if (Log.isLoggable(TAG, Log.WARN)) {
+ Log.w(TAG, "No recents target. Using stub animation.");
+ }
+ anim.play(ValueAnimator.ofInt(0, 1).setDuration(getRecentsLaunchDuration()));
+ return anim;
+ }
+
+ View thumbnailView = mRecentsView.getThumbnailViewForTask(mTargetTaskId);
+ if (thumbnailView == null) {
+ // TODO: We should either 1) guarantee the view is loaded before attempting this
+ // or 2) have a backup animation.
+ if (Log.isLoggable(TAG, Log.WARN)) {
+ Log.w(TAG, "No thumbnail view for running task. Using stub animation.");
+ }
+ anim.play(ValueAnimator.ofInt(0, 1).setDuration(getRecentsLaunchDuration()));
+ return anim;
+ }
+
+ playAppScaleDownAnim(anim, closingAppTarget, recentsTarget, thumbnailView);
+
return anim;
}
/**
+ * Animate a closing app to scale down to the location of the thumbnail view in recents.
+ *
+ * @param anim animator set
+ * @param appTarget the app surface thats closing
+ * @param recentsTarget the surface containing recents
+ * @param thumbnailView the thumbnail view to animate to
+ */
+ private void playAppScaleDownAnim(@NonNull AnimatorSet anim,
+ @NonNull RemoteAnimationTargetCompat appTarget,
+ @NonNull RemoteAnimationTargetCompat recentsTarget, @NonNull View thumbnailView) {
+
+ // Identify where the entering remote app should animate to.
+ Rect endRect = new Rect();
+ thumbnailView.getGlobalVisibleRect(endRect);
+
+ Rect appBounds = appTarget.sourceContainerBounds;
+
+ ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 1);
+ valueAnimator.setDuration(APP_SCALE_DOWN_DURATION);
+
+ SyncRtSurfaceTransactionApplierCompat surfaceApplier =
+ new SyncRtSurfaceTransactionApplierCompat(thumbnailView);
+
+ // Keep recents visible throughout the animation.
+ SurfaceParams[] params = new SurfaceParams[2];
+ params[0] = new SurfaceParams(recentsTarget.leash, 1f, null /* matrix */,
+ null /* windowCrop */, getLayer(recentsTarget, MODE_OPENING), 0 /* cornerRadius */);
+
+ valueAnimator.addUpdateListener(new MultiValueUpdateListener() {
+ private final FloatProp mScaleX;
+ private final FloatProp mScaleY;
+ private final FloatProp mTranslationX;
+ private final FloatProp mTranslationY;
+ private final FloatProp mAlpha;
+
+ {
+ // Scale down and move to view location.
+ float endScaleX = ((float) endRect.width()) / appBounds.width();
+ mScaleX = new FloatProp(1f, endScaleX, 0, APP_SCALE_DOWN_DURATION,
+ ACCEL_DEACCEL);
+ float endScaleY = ((float) endRect.height()) / appBounds.height();
+ mScaleY = new FloatProp(1f, endScaleY, 0, APP_SCALE_DOWN_DURATION,
+ ACCEL_DEACCEL);
+ float endTranslationX = endRect.left -
+ (appBounds.width() - thumbnailView.getWidth()) / 2.0f;
+ mTranslationX = new FloatProp(0, endTranslationX, 0, APP_SCALE_DOWN_DURATION,
+ ACCEL_DEACCEL);
+ float endTranslationY = endRect.top -
+ (appBounds.height() - thumbnailView.getHeight()) / 2.0f;
+ mTranslationY = new FloatProp(0, endTranslationY, 0, APP_SCALE_DOWN_DURATION,
+ ACCEL_DEACCEL);
+
+ // Fade out quietly near the end to be replaced by the real view.
+ mAlpha = new FloatProp(1.0f, 0,
+ APP_SCALE_DOWN_DURATION - APP_TO_THUMBNAIL_FADE_DURATION,
+ APP_TO_THUMBNAIL_FADE_DURATION, ACCEL_2);
+ }
+
+ @Override
+ public void onUpdate(float percent) {
+ Matrix m = new Matrix();
+ m.setScale(mScaleX.value, mScaleY.value,
+ appBounds.width() / 2.0f, appBounds.height() / 2.0f);
+ m.postTranslate(mTranslationX.value, mTranslationY.value);
+
+ params[1] = new SurfaceParams(appTarget.leash, mAlpha.value, m,
+ null /* windowCrop */, getLayer(appTarget, MODE_CLOSING),
+ 0 /* cornerRadius */);
+ surfaceApplier.scheduleApply(params);
+ }
+ });
+ anim.play(valueAnimator);
+ }
+
+ /**
* Get duration of animation from app to overview.
*
* @return duration of animation
*/
long getRecentsLaunchDuration() {
- return RECENTS_LAUNCH_DURATION;
+ return APP_SCALE_DOWN_DURATION;
}
}
diff --git a/go/quickstep/src/com/android/quickstep/LauncherActivityControllerHelper.java b/go/quickstep/src/com/android/quickstep/LauncherActivityControllerHelper.java
index d55d2e5..40db7dd 100644
--- a/go/quickstep/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/go/quickstep/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -21,6 +21,7 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherInitListener;
+import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.views.IconRecentsView;
@@ -38,10 +39,14 @@
public AnimationFactory prepareRecentsUI(Launcher activity,
boolean activityVisible, boolean animateActivity,
Consumer<AnimatorPlaybackController> callback) {
+ LauncherState fromState = activity.getStateManager().getState();
//TODO: Implement this based off where the recents view needs to be for app => recents anim.
return new AnimationFactory() {
@Override
- public void createActivityController(long transitionLength) {}
+ public void createActivityController(long transitionLength) {
+ callback.accept(activity.getStateManager().createAnimationToNewWorkspace(
+ fromState, OVERVIEW, transitionLength));
+ }
@Override
public void onTransitionCancelled() {}
diff --git a/go/quickstep/src/com/android/quickstep/TaskAdapter.java b/go/quickstep/src/com/android/quickstep/TaskAdapter.java
index 4f3d1e4..9a2c0f8 100644
--- a/go/quickstep/src/com/android/quickstep/TaskAdapter.java
+++ b/go/quickstep/src/com/android/quickstep/TaskAdapter.java
@@ -15,10 +15,12 @@
*/
package com.android.quickstep;
+import android.util.ArrayMap;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView.Adapter;
import com.android.launcher3.R;
@@ -36,6 +38,7 @@
private static final int MAX_TASKS_TO_DISPLAY = 6;
private static final String TAG = "TaskAdapter";
private final TaskListLoader mLoader;
+ private final ArrayMap<Integer, TaskItemView> mTaskIdToViewMap = new ArrayMap<>();
private TaskInputController mInputController;
public TaskAdapter(@NonNull TaskListLoader loader) {
@@ -46,6 +49,16 @@
mInputController = inputController;
}
+ /**
+ * Get task item view for a given task id if it's attached to the view.
+ *
+ * @param taskId task id to search for
+ * @return corresponding task item view if it's attached, null otherwise
+ */
+ public @Nullable TaskItemView getTaskItemView(int taskId) {
+ return mTaskIdToViewMap.get(taskId);
+ }
+
@Override
public TaskHolder onCreateViewHolder(ViewGroup parent, int viewType) {
TaskItemView itemView = (TaskItemView) LayoutInflater.from(parent.getContext())
@@ -63,6 +76,17 @@
return;
}
holder.bindTask(tasks.get(position));
+
+ }
+
+ @Override
+ public void onViewAttachedToWindow(@NonNull TaskHolder holder) {
+ mTaskIdToViewMap.put(holder.getTask().key.id, (TaskItemView) holder.itemView);
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(@NonNull TaskHolder holder) {
+ mTaskIdToViewMap.remove(holder.getTask().key.id);
}
@Override
diff --git a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
index e294282..504f640 100644
--- a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
+++ b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
@@ -27,6 +27,7 @@
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -45,20 +46,6 @@
*/
public final class IconRecentsView extends FrameLayout {
- public static final FloatProperty<IconRecentsView> TRANSLATION_Y_FACTOR =
- new FloatProperty<IconRecentsView>("translationYFactor") {
-
- @Override
- public void setValue(IconRecentsView view, float v) {
- view.setTranslationYFactor(v);
- }
-
- @Override
- public Float get(IconRecentsView view) {
- return view.mTranslationYFactor;
- }
- };
-
public static final FloatProperty<IconRecentsView> CONTENT_ALPHA =
new FloatProperty<IconRecentsView>("contentAlpha") {
@Override
@@ -90,7 +77,6 @@
private final TaskInputController mTaskInputController;
private RecentsToActivityHelper mActivityHelper;
- private float mTranslationYFactor;
private RecyclerView mTaskRecyclerView;
private View mEmptyView;
@@ -155,13 +141,18 @@
});
}
- public void setTranslationYFactor(float translationFactor) {
- mTranslationYFactor = translationFactor;
- setTranslationY(computeTranslationYForFactor(mTranslationYFactor));
- }
-
- private float computeTranslationYForFactor(float translationYFactor) {
- return translationYFactor * (getPaddingBottom() - getPaddingTop());
+ /**
+ * Get the thumbnail view associated with a task for the purposes of animation.
+ *
+ * @param taskId task id of thumbnail view to get
+ * @return the thumbnail view for the task if attached, null otherwise
+ */
+ public @Nullable View getThumbnailViewForTask(int taskId) {
+ TaskItemView view = mTaskAdapter.getTaskItemView(taskId);
+ if (view == null) {
+ return null;
+ }
+ return view.getThumbnailView();
}
/**
diff --git a/go/quickstep/src/com/android/quickstep/views/TaskItemView.java b/go/quickstep/src/com/android/quickstep/views/TaskItemView.java
index 3818965..373f107 100644
--- a/go/quickstep/src/com/android/quickstep/views/TaskItemView.java
+++ b/go/quickstep/src/com/android/quickstep/views/TaskItemView.java
@@ -19,6 +19,7 @@
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
+import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -76,4 +77,8 @@
public void setThumbnail(Bitmap thumbnail) {
mThumbnailView.setImageBitmap(thumbnail);
}
+
+ public View getThumbnailView() {
+ return mThumbnailView;
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/BackgroundAppState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/BackgroundAppState.java
index fdb80da..f712753 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/BackgroundAppState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/BackgroundAppState.java
@@ -52,7 +52,7 @@
}
@Override
- public float[] getOverviewScaleAndTranslationYFactor(Launcher launcher) {
+ public float[] getOverviewScaleAndTranslationY(Launcher launcher) {
// Initialize the recents view scale to what it would be when starting swipe up
RecentsView recentsView = launcher.getOverviewPanel();
recentsView.getTaskSize(sTempRect);
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/OverviewState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/OverviewState.java
index 79e127a..2360eeb 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/OverviewState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/OverviewState.java
@@ -69,7 +69,7 @@
}
@Override
- public float[] getOverviewScaleAndTranslationYFactor(Launcher launcher) {
+ public float[] getOverviewScaleAndTranslationY(Launcher launcher) {
return new float[] {1f, 0f};
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index 0b3bd6c..0d5574f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -15,7 +15,6 @@
*/
package com.android.launcher3.uioverrides;
-import static com.android.quickstep.views.LauncherRecentsView.TRANSLATION_Y_FACTOR;
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
import android.animation.ValueAnimator;
@@ -23,8 +22,6 @@
import android.os.Build;
import android.util.FloatProperty;
-import androidx.annotation.NonNull;
-
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager.AnimationConfig;
@@ -32,6 +29,8 @@
import com.android.quickstep.views.LauncherRecentsView;
import com.android.quickstep.views.RecentsView;
+import androidx.annotation.NonNull;
+
/**
* State handler for handling UI changes for {@link LauncherRecentsView}. In addition to managing
* the basic view properties, this class also manages changes in the task visuals.
@@ -80,11 +79,6 @@
}
@Override
- FloatProperty<LauncherRecentsView> getTranslationYFactorProperty() {
- return TRANSLATION_Y_FACTOR;
- }
-
- @Override
FloatProperty<RecentsView> getContentAlphaProperty() {
return CONTENT_ALPHA;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java
index 109a4c5..c00b4dc 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java
@@ -22,59 +22,70 @@
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;
+import android.animation.ValueAnimator;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.PointF;
-import android.graphics.Rect;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
-import android.view.Display;
import android.view.MotionEvent;
-import android.view.Surface;
-import android.view.ViewConfiguration;
-import android.view.WindowManager;
+import com.android.launcher3.anim.Interpolators;
+import com.android.quickstep.util.MotionPauseDetector;
import com.android.systemui.shared.recents.ISystemUiProxy;
-import com.android.systemui.shared.system.NavigationBarCompat;
-import com.android.systemui.shared.system.WindowManagerWrapper;
import com.android.launcher3.R;
+import com.android.systemui.shared.system.NavigationBarCompat;
/**
* Touch consumer for handling events to launch assistant from launcher
*/
public class AssistantTouchConsumer implements InputConsumer {
private static final String TAG = "AssistantTouchConsumer";
+ private static final long RETRACT_ANIMATION_DURATION_MS = 300;
+
+ /* The assistant touch consume competes with quick switch InputConsumer gesture. The delegate
+ * can be chosen to run if the angle passing the slop is lower than the threshold angle. When
+ * this occurs, the state changes to {@link #STATE_DELEGATE_ACTIVE} where the next incoming
+ * motion events are handled by the delegate instead of the assistant touch consumer. If the
+ * angle is higher than the threshold, the state will change to {@link #STATE_ASSISTANT_ACTIVE}.
+ */
+ private static final int STATE_INACTIVE = 0;
+ private static final int STATE_ASSISTANT_ACTIVE = 1;
+ private static final int STATE_DELEGATE_ACTIVE = 2;
private final PointF mDownPos = new PointF();
private final PointF mLastPos = new PointF();
+ private final PointF mStartDragPos = new PointF();
+
private int mActivePointerId = -1;
-
- private final int mDisplayRotation;
- private final Rect mStableInsets = new Rect();
-
- private final float mDragSlop;
- private final float mTouchSlop;
- private final float mThreshold;
-
- private float mStartDisplacement;
- private boolean mPassedDragSlop;
- private boolean mPassedTouchSlop;
- private long mPassedTouchSlopTime;
+ private boolean mPassedSlop;
private boolean mLaunchedAssistant;
+ private float mDistance;
+ private float mTimeFraction;
+ private long mDragTime;
private float mLastProgress;
+ private int mState;
+ private final float mDistThreshold;
+ private final long mTimeThreshold;
+ private final int mAngleThreshold;
+ private final float mSlop;
+ private final MotionPauseDetector mMotionPauseDetector;
private final ISystemUiProxy mSysUiProxy;
+ private final InputConsumer mConsumerDelegate;
- public AssistantTouchConsumer(Context context, ISystemUiProxy systemUiProxy) {
+ public AssistantTouchConsumer(Context context, ISystemUiProxy systemUiProxy,
+ InputConsumer delegate) {
+ final Resources res = context.getResources();
mSysUiProxy = systemUiProxy;
-
- mDragSlop = NavigationBarCompat.getQuickStepDragSlopPx();
- mTouchSlop = NavigationBarCompat.getQuickStepTouchSlopPx();
- mThreshold = context.getResources().getDimension(R.dimen.gestures_assistant_threshold);
-
- Display display = context.getSystemService(WindowManager.class).getDefaultDisplay();
- mDisplayRotation = display.getRotation();
- WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
+ mConsumerDelegate = delegate;
+ mMotionPauseDetector = new MotionPauseDetector(context);
+ mDistThreshold = res.getDimension(R.dimen.gestures_assistant_drag_threshold);
+ mTimeThreshold = res.getInteger(R.integer.assistant_gesture_min_time_threshold);
+ mAngleThreshold = res.getInteger(R.integer.assistant_gesture_corner_deg_threshold);
+ mSlop = NavigationBarCompat.getQuickScrubTouchSlopPx();
+ mState = STATE_INACTIVE;
}
@Override
@@ -83,14 +94,28 @@
}
@Override
+ public boolean isActive() {
+ return mState != STATE_INACTIVE;
+ }
+
+ @Override
public void onMotionEvent(MotionEvent ev) {
// TODO add logging
+
switch (ev.getActionMasked()) {
case ACTION_DOWN: {
mActivePointerId = ev.getPointerId(0);
mDownPos.set(ev.getX(), ev.getY());
mLastPos.set(mDownPos);
- mLastProgress = -1;
+ mTimeFraction = 0;
+
+ // Detect when the gesture decelerates to start the assistant
+ mMotionPauseDetector.setOnMotionPauseListener(isPaused -> {
+ if (isPaused && mState == STATE_ASSISTANT_ACTIVE) {
+ mTimeFraction = 1;
+ updateAssistantProgress();
+ }
+ });
break;
}
case ACTION_POINTER_UP: {
@@ -107,94 +132,101 @@
break;
}
case ACTION_MOVE: {
+ if (mState == STATE_DELEGATE_ACTIVE) {
+ break;
+ }
int pointerIndex = ev.findPointerIndex(mActivePointerId);
if (pointerIndex == -1) {
break;
}
mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
- float displacement = getDisplacement(ev);
- if (!mPassedDragSlop) {
- // Normal gesture, ensure we pass the drag slop before we start tracking
- // the gesture
- if (Math.abs(displacement) > mDragSlop) {
- mPassedDragSlop = true;
- mStartDisplacement = displacement;
- mPassedTouchSlopTime = SystemClock.uptimeMillis();
- }
- }
+ if (!mPassedSlop) {
+ // Normal gesture, ensure we pass the slop before we start tracking the gesture
+ if (Math.hypot(mLastPos.x - mDownPos.x, mLastPos.y - mDownPos.y) > mSlop) {
+ mPassedSlop = true;
+ mStartDragPos.set(mLastPos.x, mLastPos.y);
+ mDragTime = SystemClock.uptimeMillis();
- if (!mPassedTouchSlop) {
- if (Math.hypot(mLastPos.x - mDownPos.x, mLastPos.y - mDownPos.y) >=
- mTouchSlop) {
- mPassedTouchSlop = true;
- if (!mPassedDragSlop) {
- mPassedDragSlop = true;
- mStartDisplacement = displacement;
- mPassedTouchSlopTime = SystemClock.uptimeMillis();
+ // Determine if angle is larger than threshold for assistant detection
+ float angle = (float) Math.toDegrees(
+ Math.atan2(mDownPos.y - mLastPos.y, mDownPos.x - mLastPos.x));
+ angle = angle > 90 ? 180 - angle : angle;
+ if (angle > mAngleThreshold) {
+ mState = STATE_ASSISTANT_ACTIVE;
+
+ if (mConsumerDelegate != null) {
+ // Send cancel event
+ MotionEvent event = MotionEvent.obtain(ev);
+ event.setAction(MotionEvent.ACTION_CANCEL);
+ mConsumerDelegate.onMotionEvent(event);
+ event.recycle();
+ }
+ } else {
+ mState = STATE_DELEGATE_ACTIVE;
}
}
- }
-
- if (mPassedDragSlop) {
- // Move
- float distance = mStartDisplacement - displacement;
- if (distance >= 0) {
- onAssistantProgress(distance / mThreshold);
+ } else {
+ // Movement
+ mDistance = (float) Math.hypot(mLastPos.x - mStartDragPos.x,
+ mLastPos.y - mStartDragPos.y);
+ mMotionPauseDetector.addPosition(mDistance, 0);
+ if (mDistance >= 0) {
+ final long diff = SystemClock.uptimeMillis() - mDragTime;
+ mTimeFraction = Math.min(diff * 1f / mTimeThreshold, 1);
+ updateAssistantProgress();
}
}
break;
}
case ACTION_CANCEL:
- break;
- case ACTION_UP: {
- if (ev.getEventTime() - mPassedTouchSlopTime < ViewConfiguration.getTapTimeout()) {
- onAssistantProgress(1);
+ case ACTION_UP:
+ if (mState != STATE_DELEGATE_ACTIVE && !mLaunchedAssistant) {
+ ValueAnimator animator = ValueAnimator.ofFloat(mLastProgress, 0)
+ .setDuration(RETRACT_ANIMATION_DURATION_MS);
+ animator.addUpdateListener(valueAnimator -> {
+ float progress = (float) valueAnimator.getAnimatedValue();
+ try {
+ mSysUiProxy.onAssistantProgress(progress);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to send SysUI start/send assistant progress: "
+ + progress, e);
+ }
+ });
+ animator.setInterpolator(Interpolators.DEACCEL_2);
+ animator.start();
}
-
+ mMotionPauseDetector.clear();
break;
- }
+ }
+
+ if (mState != STATE_ASSISTANT_ACTIVE && mConsumerDelegate != null) {
+ mConsumerDelegate.onMotionEvent(ev);
}
}
- private void onAssistantProgress(float progress) {
- if (mLastProgress == progress) {
- return;
- }
- try {
- mSysUiProxy.onAssistantProgress(Math.max(0, Math.min(1, progress)));
- if (progress >= 1 && !mLaunchedAssistant) {
- mSysUiProxy.startAssistant(new Bundle());
- mLaunchedAssistant = true;
- }
+ private void updateAssistantProgress() {
+ if (!mLaunchedAssistant) {
+ float progress = Math.min(mDistance * 1f / mDistThreshold, 1) * mTimeFraction;
mLastProgress = progress;
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to notify SysUI to start/send assistant progress: " + progress, e);
+ try {
+ mSysUiProxy.onAssistantProgress(progress);
+
+ if (mDistance >= mDistThreshold && mTimeFraction >= 1) {
+ mSysUiProxy.startAssistant(new Bundle());
+ mLaunchedAssistant = true;
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to send SysUI start/send assistant progress: " + progress, e);
+ }
}
}
- private boolean isNavBarOnRight() {
- return mDisplayRotation == Surface.ROTATION_90 && mStableInsets.right > 0;
- }
-
- private boolean isNavBarOnLeft() {
- return mDisplayRotation == Surface.ROTATION_270 && mStableInsets.left > 0;
- }
-
- private float getDisplacement(MotionEvent ev) {
- float eventX = ev.getX();
- float eventY = ev.getY();
- float displacement = eventY - mDownPos.y;
- if (isNavBarOnRight()) {
- displacement = eventX - mDownPos.x;
- } else if (isNavBarOnLeft()) {
- displacement = mDownPos.x - eventX;
- }
- return displacement;
- }
-
- static boolean withinTouchRegion(Context context, float x) {
- return x > context.getResources().getDisplayMetrics().widthPixels
- - context.getResources().getDimension(R.dimen.gestures_assistant_width);
+ static boolean withinTouchRegion(Context context, MotionEvent ev) {
+ final Resources res = context.getResources();
+ final int width = res.getDisplayMetrics().widthPixels;
+ final int height = res.getDisplayMetrics().heightPixels;
+ final int size = res.getDimensionPixelSize(R.dimen.gestures_assistant_size);
+ return (ev.getX() > width - size || ev.getX() < size) && ev.getY() > height - size;
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
index b0bd71b..279b83c 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -56,9 +56,7 @@
import com.android.launcher3.anim.SpringObjectAnimator;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.userevent.nano.LauncherLogProto;
-import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.launcher3.views.FloatingIconView;
import com.android.quickstep.util.ClipAnimationHelper;
import com.android.quickstep.util.LayoutUtils;
@@ -307,7 +305,7 @@
// starting to line up the side pages during swipe up)
float prevRvScale = recentsView.getScaleX();
float prevRvTransY = recentsView.getTranslationY();
- float targetRvScale = endState.getOverviewScaleAndTranslationYFactor(launcher)[0];
+ float targetRvScale = endState.getOverviewScaleAndTranslationY(launcher)[0];
SCALE_PROPERTY.set(recentsView, targetRvScale);
recentsView.setTranslationY(0);
ClipAnimationHelper clipHelper = new ClipAnimationHelper(launcher);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
index 9506bfa..c8dcf80 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
@@ -23,7 +23,7 @@
import static android.view.MotionEvent.INVALID_POINTER_ID;
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
-import static com.android.quickstep.TouchInteractionService.EDGE_NAV_BAR;
+import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewInputConsumer.java
index cce5cb3..02ffdb3 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewInputConsumer.java
@@ -30,6 +30,7 @@
import android.view.ViewConfiguration;
import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.Utilities;
import com.android.launcher3.views.BaseDragLayer;
import com.android.quickstep.util.CachedEventDispatcher;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -139,7 +140,7 @@
return;
}
int flags = ev.getEdgeFlags();
- ev.setEdgeFlags(flags | TouchInteractionService.EDGE_NAV_BAR);
+ ev.setEdgeFlags(flags | Utilities.EDGE_NAV_BAR);
ev.offsetLocation(-mLocationOnScreen[0], -mLocationOnScreen[1]);
if (ev.getAction() == ACTION_DOWN) {
mTarget.onInterceptTouchEvent(ev);
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 6d608ee..8fe0461 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -74,8 +74,6 @@
public static final EventLogArray TOUCH_INTERACTION_LOG =
new EventLogArray("touch_interaction_log", 40);
- public static final int EDGE_NAV_BAR = 1 << 8;
-
private static final String TAG = "TouchInteractionService";
private final IBinder mMyBinder = new IOverviewProxy.Stub() {
@@ -313,31 +311,36 @@
mSwipeSharedState.clearAllState();
}
+ final ActivityControlHelper activityControl =
+ mOverviewComponentObserver.getActivityControlHelper();
if (runningTaskInfo == null && !mSwipeSharedState.goingToLauncher) {
return InputConsumer.NO_OP;
} else if (mAssistantAvailable && mOverviewInteractionState.isSwipeUpGestureEnabled()
&& FeatureFlags.ENABLE_ASSISTANT_GESTURE.get()
- && AssistantTouchConsumer.withinTouchRegion(this, event.getX())) {
- return new AssistantTouchConsumer(this, mRecentsModel.getSystemUiProxy());
- } else if (mSwipeSharedState.goingToLauncher ||
- mOverviewComponentObserver.getActivityControlHelper().isResumed()) {
- return OverviewInputConsumer.newInstance(
- mOverviewComponentObserver.getActivityControlHelper(), false);
+ && AssistantTouchConsumer.withinTouchRegion(this, event)) {
+ return new AssistantTouchConsumer(this, mISystemUiProxy, !activityControl.isResumed()
+ ? createOtherActivityInputConsumer(event, runningTaskInfo) : null);
+ } else if (mSwipeSharedState.goingToLauncher || activityControl.isResumed()) {
+ return OverviewInputConsumer.newInstance(activityControl, false);
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
- mOverviewComponentObserver.getActivityControlHelper().isInLiveTileMode()) {
- return OverviewInputConsumer.newInstance(
- mOverviewComponentObserver.getActivityControlHelper(), false);
+ activityControl.isInLiveTileMode()) {
+ return OverviewInputConsumer.newInstance(activityControl, false);
} else {
- ActivityControlHelper activityControl =
- mOverviewComponentObserver.getActivityControlHelper();
- boolean shouldDefer = activityControl.deferStartingActivity(mActiveNavBarRegion, event);
- return new OtherActivityInputConsumer(this, runningTaskInfo, mRecentsModel,
- mOverviewComponentObserver.getOverviewIntent(), activityControl,
- shouldDefer, mOverviewCallbacks, mTaskOverlayFactory, mInputConsumer,
- this::onConsumerInactive, mSwipeSharedState);
+ return createOtherActivityInputConsumer(event, runningTaskInfo);
}
}
+ private OtherActivityInputConsumer createOtherActivityInputConsumer(MotionEvent event,
+ RunningTaskInfo runningTaskInfo) {
+ final ActivityControlHelper activityControl =
+ mOverviewComponentObserver.getActivityControlHelper();
+ boolean shouldDefer = activityControl.deferStartingActivity(mActiveNavBarRegion, event);
+ return new OtherActivityInputConsumer(this, runningTaskInfo, mRecentsModel,
+ mOverviewComponentObserver.getOverviewIntent(), activityControl,
+ shouldDefer, mOverviewCallbacks, mTaskOverlayFactory, mInputConsumer,
+ this::onConsumerInactive, mSwipeSharedState);
+ }
+
/**
* To be called by the consumer when it's no longer active.
*/
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
index 97bce5e..8f2a2d7 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -56,27 +56,6 @@
@TargetApi(Build.VERSION_CODES.O)
public class LauncherRecentsView extends RecentsView<Launcher> {
- public static final FloatProperty<LauncherRecentsView> TRANSLATION_Y_FACTOR =
- new FloatProperty<LauncherRecentsView>("translationYFactor") {
-
- @Override
- public void setValue(LauncherRecentsView view, float v) {
- view.setTranslationYFactor(v);
- }
-
- @Override
- public Float get(LauncherRecentsView view) {
- return view.mTranslationYFactor;
- }
- };
-
- /**
- * A ratio representing the view's relative placement within its padded space. For example, 0
- * is top aligned and 0.5 is centered vertically.
- */
- @ViewDebug.ExportedProperty(category = "launcher")
- private float mTranslationYFactor;
-
private final TransformParams mTransformParams = new TransformParams();
private ChipsContainer mChipsContainer;
@@ -104,12 +83,6 @@
}
@Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- setTranslationYFactor(mTranslationYFactor);
- }
-
- @Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mChipsContainer = mActivity.findViewById(R.id.hints);
@@ -117,9 +90,9 @@
params.bottomMargin = mActivity.getDeviceProfile().chipHintBottomMarginPx;
}
- public void setTranslationYFactor(float translationFactor) {
- mTranslationYFactor = translationFactor;
- setTranslationY(computeTranslationYForFactor(mTranslationYFactor));
+ @Override
+ public void setTranslationY(float translationY) {
+ super.setTranslationY(translationY);
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
LauncherState state = mActivity.getStateManager().getState();
if (state == OVERVIEW || state == ALL_APPS) {
@@ -128,10 +101,6 @@
}
}
- public float computeTranslationYForFactor(float translationYFactor) {
- return translationYFactor * (getPaddingBottom() - getPaddingTop());
- }
-
public void setHintVisibility(float v) {
if (mChipsContainer != null && ENABLE_HINTS_IN_OVERVIEW.get()) {
mChipsContainer.setHintVisibility(v);
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 b7a708f..37febf9a 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
@@ -27,7 +27,7 @@
import static com.android.launcher3.uioverrides.TaskViewTouchController.SUCCESS_TRANSITION_PROGRESS;
import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
-import static com.android.quickstep.TouchInteractionService.EDGE_NAV_BAR;
+import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
import static com.android.quickstep.util.ClipAnimationHelper.TransformParams;
import android.animation.Animator;
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
index 3fbfcdd..a966698 100644
--- a/quickstep/res/values/config.xml
+++ b/quickstep/res/values/config.xml
@@ -26,4 +26,8 @@
determines how many thumbnails will be fetched in the background. -->
<integer name="recentsThumbnailCacheSize">3</integer>
<integer name="recentsIconCacheSize">12</integer>
+
+ <!-- Assistant Gesture -->
+ <integer name="assistant_gesture_min_time_threshold">200</integer>
+ <integer name="assistant_gesture_corner_deg_threshold">30</integer>
</resources>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index f5e5dd3..9c97c8c 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -66,6 +66,6 @@
<dimen name="shelf_surface_offset">24dp</dimen>
<!-- Assistant Gestures -->
- <dimen name="gestures_assistant_width">70dp</dimen>
- <dimen name="gestures_assistant_threshold">200dp</dimen>
+ <dimen name="gestures_assistant_size">28dp</dimen>
+ <dimen name="gestures_assistant_drag_threshold">70dp</dimen>
</resources>
diff --git a/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
index 1eaa8bc..5ae562e 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
@@ -78,8 +78,9 @@
}
@Override
- public float[] getOverviewScaleAndTranslationYFactor(Launcher launcher) {
- return new float[] {0.9f, -0.2f};
+ public float[] getOverviewScaleAndTranslationY(Launcher launcher) {
+ float slightParallax = -launcher.getDeviceProfile().allAppsCellHeightPx * 0.3f;
+ return new float[] {0.9f, slightParallax};
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index df9dbe4..e74d84d 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -26,8 +26,6 @@
import android.view.View;
import android.view.animation.Interpolator;
-import androidx.annotation.NonNull;
-
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager.AnimationConfig;
@@ -35,6 +33,8 @@
import com.android.launcher3.anim.AnimatorSetBuilder;
import com.android.launcher3.anim.PropertySetter;
+import androidx.annotation.NonNull;
+
/**
* State handler for recents view. Manages UI changes and animations for recents view based off the
* current {@link LauncherState}.
@@ -53,9 +53,9 @@
@Override
public void setState(@NonNull LauncherState state) {
- float[] scaleTranslationYFactor = state.getOverviewScaleAndTranslationYFactor(mLauncher);
- SCALE_PROPERTY.set(mRecentsView, scaleTranslationYFactor[0]);
- getTranslationYFactorProperty().set(mRecentsView, scaleTranslationYFactor[1]);
+ float[] scaleTranslationY = state.getOverviewScaleAndTranslationY(mLauncher);
+ SCALE_PROPERTY.set(mRecentsView, scaleTranslationY[0]);
+ mRecentsView.setTranslationY(scaleTranslationY[1]);
getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0);
}
@@ -79,11 +79,11 @@
void setStateWithAnimationInternal(@NonNull final LauncherState toState,
@NonNull AnimatorSetBuilder builder, @NonNull AnimationConfig config) {
PropertySetter setter = config.getPropertySetter(builder);
- float[] scaleTranslationYFactor = toState.getOverviewScaleAndTranslationYFactor(mLauncher);
+ float[] scaleTranslationY = toState.getOverviewScaleAndTranslationY(mLauncher);
Interpolator scaleAndTransYInterpolator = getScaleAndTransYInterpolator(toState, builder);
- setter.setFloat(mRecentsView, SCALE_PROPERTY, scaleTranslationYFactor[0],
+ setter.setFloat(mRecentsView, SCALE_PROPERTY, scaleTranslationY[0],
scaleAndTransYInterpolator);
- setter.setFloat(mRecentsView, getTranslationYFactorProperty(), scaleTranslationYFactor[1],
+ setter.setFloat(mRecentsView, View.TRANSLATION_Y, scaleTranslationY[1],
scaleAndTransYInterpolator);
setter.setFloat(mRecentsView, getContentAlphaProperty(), toState.overviewUi ? 1 : 0,
builder.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
@@ -102,13 +102,6 @@
}
/**
- * Get property for translation Y factor for the recents view.
- *
- * @return the float property for the recents view
- */
- abstract FloatProperty getTranslationYFactorProperty();
-
- /**
* Get property for content alpha for the recents view.
*
* @return the float property for the view's content alpha
diff --git a/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java
index fd4bf9b..086cbdb 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java
@@ -2,7 +2,7 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.quickstep.TouchInteractionService.EDGE_NAV_BAR;
+import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
import android.view.MotionEvent;
diff --git a/quickstep/src/com/android/quickstep/TestInformationProvider.java b/quickstep/src/com/android/quickstep/TestInformationProvider.java
index 0c478d2..e57d3ec 100644
--- a/quickstep/src/com/android/quickstep/TestInformationProvider.java
+++ b/quickstep/src/com/android/quickstep/TestInformationProvider.java
@@ -25,6 +25,9 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherState;
import com.android.launcher3.TestProtocol;
import com.android.launcher3.Utilities;
import com.android.launcher3.uioverrides.OverviewState;
@@ -68,6 +71,9 @@
final Context context = getContext();
final DeviceProfile deviceProfile = InvariantDeviceProfile.INSTANCE.
get(context).getDeviceProfile(context);
+ final LauncherAppState launcherAppState = LauncherAppState.getInstanceNoCreate();
+ final Launcher launcher = launcherAppState != null ?
+ (Launcher) launcherAppState.getModel().getCallback() : null;
switch (method) {
case TestProtocol.REQUEST_HOME_TO_OVERVIEW_SWIPE_HEIGHT: {
@@ -76,12 +82,35 @@
response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) swipeHeight);
break;
}
+
case TestProtocol.REQUEST_BACKGROUND_TO_OVERVIEW_SWIPE_HEIGHT: {
final float swipeHeight =
LayoutUtils.getShelfTrackingDistance(context, deviceProfile);
response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) swipeHeight);
break;
}
+
+ case TestProtocol.REQUEST_ALL_APPS_TO_OVERVIEW_SWIPE_HEIGHT: {
+ if (launcher == null) return null;
+
+ final float progress = LauncherState.OVERVIEW.getVerticalProgress(launcher)
+ - LauncherState.ALL_APPS.getVerticalProgress(launcher);
+ final float distance =
+ launcher.getAllAppsController().getShiftRange() * progress;
+ response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) distance);
+ break;
+ }
+
+ case TestProtocol.REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT: {
+ if (launcher == null) return null;
+
+ final float progress = LauncherState.NORMAL.getVerticalProgress(launcher)
+ - LauncherState.ALL_APPS.getVerticalProgress(launcher);
+ final float distance =
+ launcher.getAllAppsController().getShiftRange() * progress;
+ response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) distance);
+ break;
+ }
}
return response;
}
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 6582df2..f081303 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -20,7 +20,10 @@
import static com.android.launcher3.Utilities.getDevicePrefs;
import android.annotation.TargetApi;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -114,6 +117,7 @@
private final ArrayList<OnIDPChangeListener> mChangeListeners = new ArrayList<>();
private ConfigMonitor mConfigMonitor;
+ private OverlayMonitor mOverlayMonitor;
@VisibleForTesting
public InvariantDeviceProfile() {}
@@ -131,6 +135,7 @@
defaultLayoutId = p.defaultLayoutId;
demoModeLayoutId = p.demoModeLayoutId;
mExtraAttrs = p.mExtraAttrs;
+ mOverlayMonitor = p.mOverlayMonitor;
}
@TargetApi(23)
@@ -138,8 +143,12 @@
initGrid(context, Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null));
mConfigMonitor = new ConfigMonitor(context,
APPLY_CONFIG_AT_RUNTIME.get() ? this::onConfigChanged : this::killProcess);
+ mOverlayMonitor = new OverlayMonitor(context);
}
+ /**
+ * This constructor should NOT have any monitors by design.
+ */
public InvariantDeviceProfile(Context context, String gridName) {
String newName = initGrid(context, gridName);
if (newName == null || !newName.equals(gridName)) {
@@ -555,4 +564,20 @@
return this;
}
}
+
+ private class OverlayMonitor extends BroadcastReceiver {
+
+ private final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
+
+ OverlayMonitor(Context context) {
+ IntentFilter filter = new IntentFilter(ACTION_OVERLAY_CHANGED);
+ filter.addDataScheme("package");
+ context.registerReceiver(this, filter);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ onConfigChanged(context);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index cee1c26..875288a 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -192,13 +192,7 @@
return getWorkspaceScaleAndTranslation(launcher);
}
- /**
- * Returns 2 floats designating how to transition overview:
- * scale for the current and adjacent pages
- * translationY factor where 0 is top aligned and 0.5 is centered vertically
- */
- public float[] getOverviewScaleAndTranslationYFactor(Launcher launcher) {
- // TODO: Simplify to use a constant value instead of a factor.
+ public float[] getOverviewScaleAndTranslationY(Launcher launcher) {
return new float[] {1.1f, 0f};
}
diff --git a/src/com/android/launcher3/TestProtocol.java b/src/com/android/launcher3/TestProtocol.java
index 5f752cc..4eb3627 100644
--- a/src/com/android/launcher3/TestProtocol.java
+++ b/src/com/android/launcher3/TestProtocol.java
@@ -36,4 +36,8 @@
"home-to-overview-swipe-height";
public static final String REQUEST_BACKGROUND_TO_OVERVIEW_SWIPE_HEIGHT =
"background-to-overview-swipe-height";
+ public static final String REQUEST_ALL_APPS_TO_OVERVIEW_SWIPE_HEIGHT =
+ "all-apps-to-overview-swipe-height";
+ public static final String REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT =
+ "home-to-all-apps-swipe-height";
}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 7036639..dd755cb 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -54,6 +54,7 @@
import android.util.Log;
import android.util.Pair;
import android.util.TypedValue;
+import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
@@ -115,6 +116,11 @@
public static final int SINGLE_FRAME_MS = 16;
/**
+ * Set on a motion event dispatched from the nav bar. See {@link MotionEvent#setEdgeFlags(int)}.
+ */
+ public static final int EDGE_NAV_BAR = 1 << 8;
+
+ /**
* Indicates if the device has a debug build. Should only be used to store additional info or
* add extra logging and not for changing the app behavior.
*/
diff --git a/src/com/android/launcher3/anim/SpringObjectAnimator.java b/src/com/android/launcher3/anim/SpringObjectAnimator.java
index cc70e32..f74590b 100644
--- a/src/com/android/launcher3/anim/SpringObjectAnimator.java
+++ b/src/com/android/launcher3/anim/SpringObjectAnimator.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.anim;
+import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
@@ -32,8 +34,6 @@
import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce;
-import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
-
/**
* This animator allows for an object's property to be be controlled by an {@link ObjectAnimator} or
* a {@link SpringAnimation}. It extends ValueAnimator so it can be used in an AnimatorSet.
@@ -51,9 +51,9 @@
private SpringProperty<T> mProperty;
private ArrayList<AnimatorListener> mListeners;
- private boolean mSpringEnded = false;
- private boolean mAnimatorEnded = false;
- private boolean mEnded = false;
+ private boolean mSpringEnded = true;
+ private boolean mAnimatorEnded = true;
+ private boolean mEnded = true;
private static final FloatPropertyCompat<ProgressInterface> sFloatProperty =
new FloatPropertyCompat<ProgressInterface>("springObjectAnimator") {
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index b0af4c6..10ecc4f 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -22,6 +22,7 @@
import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import static com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
import static com.android.launcher3.userevent.nano.LauncherLogProto.Target;
+import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
import android.animation.AnimatorSet;
import android.animation.LayoutTransition;
@@ -167,7 +168,8 @@
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
BaseDragLayer dl = getPopupContainer();
- if (!dl.isEventOverView(this, ev)) {
+ final boolean cameFromNavBar = (ev.getEdgeFlags() & EDGE_NAV_BAR) != 0;
+ if (!cameFromNavBar && !dl.isEventOverView(this, ev)) {
mLauncher.getUserEventDispatcher().logActionTapOutside(
LoggerUtils.newContainerTarget(ContainerType.DEEPSHORTCUTS));
close(true);
diff --git a/src/com/android/launcher3/util/ConfigMonitor.java b/src/com/android/launcher3/util/ConfigMonitor.java
index 12280f8..12d35e9 100644
--- a/src/com/android/launcher3/util/ConfigMonitor.java
+++ b/src/com/android/launcher3/util/ConfigMonitor.java
@@ -41,8 +41,6 @@
private static final String TAG = "ConfigMonitor";
- private final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
-
private final Point mTmpPoint1 = new Point();
private final Point mTmpPoint2 = new Point();
@@ -78,11 +76,6 @@
// Listen for configuration change
mContext.registerReceiver(this, new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
- // Listen for {@link OverlayManager} change
- IntentFilter filter = new IntentFilter(ACTION_OVERLAY_CHANGED);
- filter.addDataScheme("package");
- mContext.registerReceiver(this, filter);
-
// Listen for display manager change
mContext.getSystemService(DisplayManager.class)
.registerDisplayListener(this, new Handler(UiThreadHelper.getBackgroundLooper()));
@@ -91,12 +84,6 @@
@Override
public void onReceive(Context context, Intent intent) {
Configuration config = context.getResources().getConfiguration();
- // TODO: when overlay manager service encodes more information to the Uri such as category
- // of the overlay, only listen to the ones that are of interest to launcher.
- if (intent != null && ACTION_OVERLAY_CHANGED.equals(intent.getAction())) {
- Log.d(TAG, "Overlay changed.");
- notifyChange();
- }
if (mFontScale != config.fontScale || mDensity != config.densityDpi) {
Log.d(TAG, "Configuration changed.");
notifyChange();
diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java
index 48cf9e8..e259cfe 100644
--- a/src/com/android/launcher3/views/OptionsPopupView.java
+++ b/src/com/android/launcher3/views/OptionsPopupView.java
@@ -18,8 +18,10 @@
import static com.android.launcher3.Utilities.EXTRA_WALLPAPER_FLAVOR;
import static com.android.launcher3.Utilities.EXTRA_WALLPAPER_OFFSET;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ResolveInfo;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.TextUtils;
@@ -150,7 +152,7 @@
RectF target = new RectF(x - halfSize, y - halfSize, x + halfSize, y + halfSize);
ArrayList<OptionItem> options = new ArrayList<>();
- int res = FeatureFlags.STYLE_WALLPAPER.get() ?
+ int res = FeatureFlags.STYLE_WALLPAPER.get() && existsStyleWallpapers(launcher) ?
R.string.styles_wallpaper_button_text : R.string.wallpaper_button_text;
options.add(new OptionItem(res, R.drawable.ic_wallpaper,
ControlType.WALLPAPER_BUTTON, OptionsPopupView::startWallpaperPicker));
@@ -164,6 +166,14 @@
show(launcher, target, options);
}
+ private static boolean existsStyleWallpapers(Launcher launcher) {
+ Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER);
+ intent.setComponent(new ComponentName(launcher.getString(R.string.wallpaper_picker_package),
+ "com.android.customization.picker.CustomizationPickerActivity"));
+ ResolveInfo ri = launcher.getPackageManager().resolveActivity(intent, 0);
+ return ri != null;
+ }
+
public static boolean onWidgetsClicked(View view) {
return openWidgets(Launcher.getLauncher(view.getContext()));
}
diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java
index 1353a23..122151e 100644
--- a/tests/tapl/com/android/launcher3/tapl/AllApps.java
+++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java
@@ -44,6 +44,13 @@
return LauncherInstrumentation.ContainerType.ALL_APPS;
}
+ private boolean hasClickableIcon(UiObject2 allAppsContainer, BySelector appIconSelector) {
+ final UiObject2 icon = allAppsContainer.findObject(appIconSelector);
+ if (icon == null) return false;
+ final UiObject2 navBar = mLauncher.waitForSystemUiObject("navigation_bar_frame");
+ return icon.getVisibleBounds().bottom < navBar.getVisibleBounds().top;
+ }
+
/**
* Finds an icon. Fails if the icon doesn't exist. Scrolls the app list when needed to make
* sure the icon is visible.
@@ -55,10 +62,10 @@
public AppIcon getAppIcon(String appName) {
final UiObject2 allAppsContainer = verifyActiveContainer();
final BySelector appIconSelector = AppIcon.getAppIconSelector(appName, mLauncher);
- if (!allAppsContainer.hasObject(appIconSelector)) {
+ if (!hasClickableIcon(allAppsContainer, appIconSelector)) {
scrollBackToBeginning();
int attempts = 0;
- while (!allAppsContainer.hasObject(appIconSelector) &&
+ while (!hasClickableIcon(allAppsContainer, appIconSelector) &&
allAppsContainer.scroll(Direction.DOWN, 0.8f)) {
LauncherInstrumentation.assertTrue(
"Exceeded max scroll attempts: " + MAX_SCROLL_ATTEMPTS,
diff --git a/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java b/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java
index 2642815..dcc51b5 100644
--- a/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java
+++ b/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java
@@ -23,6 +23,8 @@
import androidx.annotation.NonNull;
import androidx.test.uiautomator.UiObject2;
+import com.android.launcher3.TestProtocol;
+
/**
* Operations on AllApps opened from Overview.
*/
@@ -45,7 +47,11 @@
final UiObject2 qsb = mLauncher.waitForObjectInContainer(
allAppsContainer, "search_container_all_apps");
final Point start = qsb.getVisibleCenter();
- final int endY = (int) (mLauncher.getDevice().getDisplayHeight() * 0.6);
+ final int swipeHeight = mLauncher.getTestInfo(
+ TestProtocol.REQUEST_ALL_APPS_TO_OVERVIEW_SWIPE_HEIGHT).
+ getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+
+ final int endY = start.y + swipeHeight + mLauncher.getTouchSlop();
LauncherInstrumentation.log("AllAppsFromOverview.switchBackToOverview before swipe");
mLauncher.swipe(start.x, start.y, start.x, endY, OVERVIEW_STATE_ORDINAL);
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index 3220691..2cde8ec 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -22,8 +22,6 @@
import static org.junit.Assert.assertTrue;
-import android.view.ViewConfiguration;
-
import androidx.annotation.NonNull;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.Until;
@@ -67,11 +65,13 @@
final int swipeHeight = mLauncher.getTestInfo(
getSwipeHeightRequestName()).
getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
- final int slop = ViewConfiguration.get(mLauncher.getContext()).getScaledTouchSlop();
- mLauncher.swipe(centerX, startY, centerX, startY - swipeHeight - slop, expectedState);
+ mLauncher.swipe(
+ centerX, startY, centerX,
+ startY - swipeHeight - mLauncher.getTouchSlop(),
+ expectedState);
} else {
- mLauncher.getSystemUiObject("recent_apps").click();
+ mLauncher.waitForSystemUiObject("recent_apps").click();
}
}
@@ -80,6 +80,6 @@
}
protected int getSwipeStartY() {
- return mLauncher.getSystemUiObject("home").getVisibleBounds().centerY();
+ return mLauncher.waitForSystemUiObject("home").getVisibleBounds().centerY();
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 926e470..e3850ff 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -32,6 +32,7 @@
import android.util.Log;
import android.view.MotionEvent;
import android.view.Surface;
+import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
import androidx.annotation.NonNull;
@@ -288,7 +289,7 @@
executeAndWaitForEvent(
() -> {
log("LauncherInstrumentation.pressHome before clicking");
- getSystemUiObject("home").click();
+ waitForSystemUiObject("home").click();
},
event -> true,
"Pressing Home didn't produce any events");
@@ -298,7 +299,7 @@
executeAndWaitForEvent(
() -> {
log("LauncherInstrumentation.pressHome before clicking");
- getSystemUiObject("home").click();
+ waitForSystemUiObject("home").click();
},
event -> true,
"Pressing Home didn't produce any events");
@@ -394,8 +395,9 @@
}
@NonNull
- UiObject2 getSystemUiObject(String resId) {
- final UiObject2 object = mDevice.findObject(By.res(SYSTEMUI_PACKAGE, resId));
+ UiObject2 waitForSystemUiObject(String resId) {
+ final UiObject2 object = mDevice.wait(
+ Until.findObject(By.res(SYSTEMUI_PACKAGE, resId)), WAIT_TIME_MS);
assertNotNull("Can't find a systemui object with id: " + resId, object);
return object;
}
@@ -467,4 +469,8 @@
float getDisplayDensity() {
return mInstrumentation.getTargetContext().getResources().getDisplayMetrics().density;
}
+
+ int getTouchSlop() {
+ return ViewConfiguration.get(getContext()).getScaledTouchSlop();
+ }
}
\ No newline at end of file
diff --git a/tests/tapl/com/android/launcher3/tapl/Overview.java b/tests/tapl/com/android/launcher3/tapl/Overview.java
index 0208144..5c8d5eb 100644
--- a/tests/tapl/com/android/launcher3/tapl/Overview.java
+++ b/tests/tapl/com/android/launcher3/tapl/Overview.java
@@ -50,7 +50,7 @@
verifyActiveContainer();
// Swipe from navbar to the top.
- final UiObject2 navBar = mLauncher.getSystemUiObject("navigation_bar_frame");
+ final UiObject2 navBar = mLauncher.waitForSystemUiObject("navigation_bar_frame");
final Point start = navBar.getVisibleCenter();
LauncherInstrumentation.log("Overview.switchToAllApps before swipe");
mLauncher.swipe(start.x, start.y, start.x, 0, ALL_APPS_STATE_ORDINAL);
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 819e10d..e3ef74a 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -51,15 +51,16 @@
@NonNull
public AllApps switchToAllApps() {
verifyActiveContainer();
- // Swipe from the hotseat to near the top, e.g. 10% of the screen.
final UiObject2 hotseat = mHotseat;
final Point start = hotseat.getVisibleCenter();
- final int endY = (int) (mLauncher.getDevice().getDisplayHeight() * 0.1f);
+ final int swipeHeight = mLauncher.getTestInfo(
+ TestProtocol.REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT).
+ getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
mLauncher.swipe(
start.x,
start.y,
start.x,
- endY,
+ start.y - swipeHeight - mLauncher.getTouchSlop(),
ALL_APPS_STATE_ORDINAL
);