Merge "Always place notification dots directly on adaptive icon path" into ub-launcher3-qt-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index 624b3dc..5e77e0a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -68,7 +68,7 @@
* @param wasVisible true if it was visible before
*/
boolean onActivityReady(T activity, Boolean wasVisible) {
- activity.<RecentsView>getOverviewPanel().setCurrentTask(mTargetTaskId);
+ activity.<RecentsView>getOverviewPanel().showCurrentTask(mTargetTaskId);
AbstractFloatingView.closeAllOpenViews(activity, wasVisible);
ActivityControlHelper.AnimationFactory factory =
mHelper.prepareRecentsUI(activity, wasVisible,
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 7fc5d50..db377b0 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
@@ -21,7 +21,6 @@
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;
import static android.view.MotionEvent.INVALID_POINTER_ID;
-
import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
@@ -44,6 +43,8 @@
import android.view.ViewConfiguration;
import android.view.WindowManager;
+import androidx.annotation.UiThread;
+
import com.android.launcher3.R;
import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.util.Preconditions;
@@ -62,8 +63,6 @@
import java.util.function.Consumer;
-import androidx.annotation.UiThread;
-
/**
* Input consumer for handling events originating from an activity other than Launcher
*/
@@ -108,7 +107,6 @@
// Might be displacement in X or Y, depending on the direction we are swiping from the nav bar.
private float mStartDisplacement;
- private float mStartDisplacementX;
private Handler mMainThreadHandler;
private Runnable mCancelRecentsAnimationRunnable = () -> {
@@ -227,7 +225,6 @@
if (Math.abs(displacement) > mDragSlop) {
mPassedDragSlop = true;
mStartDisplacement = displacement;
- mStartDisplacementX = displacementX;
}
}
}
@@ -244,19 +241,20 @@
if (!mPassedDragSlop) {
mPassedDragSlop = true;
mStartDisplacement = displacement;
- mStartDisplacementX = displacementX;
}
notifyGestureStarted();
}
}
- if (mPassedDragSlop && mInteractionHandler != null) {
- // Move
- mInteractionHandler.updateDisplacement(displacement - mStartDisplacement);
+ if (mInteractionHandler != null) {
+ if (mPassedDragSlop) {
+ // Move
+ mInteractionHandler.updateDisplacement(displacement - mStartDisplacement);
+ }
if (mMode == Mode.NO_BUTTON) {
- float horizontalDist = Math.abs(displacementX - mStartDisplacementX);
- float upDist = -(displacement - mStartDisplacement);
+ float horizontalDist = Math.abs(displacementX);
+ float upDist = -displacement;
boolean isLikelyToStartNewTask = horizontalDist > upDist;
mMotionPauseDetector.setDisallowPause(upDist < mMotionPauseMinDisplacement
|| isLikelyToStartNewTask);
@@ -382,7 +380,7 @@
mSwipeSharedState.canGestureBeContinued = endTarget != null && endTarget.canBeContinued;
mSwipeSharedState.goingToLauncher = endTarget != null && endTarget.isLauncher;
if (mSwipeSharedState.canGestureBeContinued) {
- mInteractionHandler.cancelCurrentAnimation();
+ mInteractionHandler.cancelCurrentAnimation(mSwipeSharedState);
} else {
mInteractionHandler.reset();
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
index ced9afa..96d2dca 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
@@ -59,6 +59,10 @@
mInputProxySupplier = inputProxySupplier;
}
+ public boolean hasTargets() {
+ return targetSet != null && targetSet.hasTargets();
+ }
+
@UiThread
public synchronized void setController(SwipeAnimationTargetSet targetSet) {
Preconditions.assertUIThread();
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java
index f393387..194d073 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java
@@ -38,6 +38,8 @@
public boolean canGestureBeContinued;
public boolean goingToLauncher;
+ public boolean recentsAnimationFinishInterrupted;
+ public int nextRunningTaskId = -1;
public SwipeSharedState(OverviewComponentObserver overviewComponentObserver) {
mOverviewComponentObserver = overviewComponentObserver;
@@ -114,9 +116,22 @@
}
}
+ /**
+ * Called when a recents animation has finished, but was interrupted before the next task was
+ * launched. The given {@param runningTaskId} should be used as the running task for the
+ * continuing input consumer.
+ */
+ public void setRecentsAnimationFinishInterrupted(int runningTaskId) {
+ recentsAnimationFinishInterrupted = true;
+ nextRunningTaskId = runningTaskId;
+ mLastAnimationTarget = mLastAnimationTarget.cloneWithoutTargets();
+ }
+
public void clearAllState() {
clearListenerState();
canGestureBeContinued = false;
+ recentsAnimationFinishInterrupted = false;
+ nextRunningTaskId = -1;
goingToLauncher = false;
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
index f95f9c2..d0ea73a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
@@ -150,6 +150,7 @@
@Override
public void onUpdate(float percent) {
+ // TODO: Take into account the current fullscreen progress for animating the insets
params.setProgress(1 - percent);
RectF taskBounds = inOutHelper.applyTransform(targetSet, params);
if (!skipViewChanges) {
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 b25865e..61ae880 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -26,6 +26,7 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
import android.annotation.TargetApi;
+import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.KeyguardManager;
import android.app.Service;
@@ -456,7 +457,7 @@
return new DeviceLockedInputConsumer(this);
}
- RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
+ final RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
if (!useSharedState) {
mSwipeSharedState.clearAllState();
}
@@ -465,8 +466,15 @@
mOverviewComponentObserver.getActivityControlHelper();
InputConsumer base;
- if (runningTaskInfo == null && !mSwipeSharedState.goingToLauncher) {
+ if (runningTaskInfo == null && !mSwipeSharedState.goingToLauncher
+ && !mSwipeSharedState.recentsAnimationFinishInterrupted) {
base = InputConsumer.NO_OP;
+ } else if (mSwipeSharedState.recentsAnimationFinishInterrupted) {
+ // If the finish animation was interrupted, then continue using the other activity input
+ // consumer but with the next task as the running task
+ RunningTaskInfo info = new ActivityManager.RunningTaskInfo();
+ info.id = mSwipeSharedState.nextRunningTaskId;
+ base = createOtherActivityInputConsumer(event, info);
} else if (mSwipeSharedState.goingToLauncher || activityControl.isResumed()) {
base = OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false);
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 0caef6f..936f0aa 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -256,7 +256,9 @@
private AnimationFactory mAnimationFactory = (t) -> { };
private LiveTileOverlay mLiveTileOverlay = new LiveTileOverlay();
+ private boolean mCanceled;
private boolean mWasLauncherAlreadyVisible;
+ private int mFinishingRecentsAnimationForNewTaskId = -1;
private boolean mPassedOverviewThreshold;
private boolean mGestureStarted;
@@ -412,7 +414,6 @@
mRecentsAnimationWrapper.runOnInit(() ->
mRecentsAnimationWrapper.targetSet.addDependentTransactionApplier(applier));
});
- mRecentsView.setEnableFreeScroll(false);
mRecentsView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
if (mGestureEndTarget != HOME) {
@@ -500,10 +501,7 @@
if (mContinuingLastGesture) {
return;
}
- mRecentsView.setEnableDrawingLiveTile(false);
- mRecentsView.showTask(mRunningTaskId);
- mRecentsView.setRunningTaskHidden(true);
- mRecentsView.setRunningTaskIconScaledDown(true);
+ mRecentsView.onGestureAnimationStart(mRunningTaskId);
}
private void launcherFrameDrawn() {
@@ -679,7 +677,7 @@
int runningTaskIndex = mRecentsView == null ? -1 : mRecentsView.getRunningTaskIndex();
if (runningTaskIndex >= 0) {
for (int i = 0; i < mRecentsView.getTaskViewCount(); i++) {
- if (i != runningTaskIndex) {
+ if (i != runningTaskIndex || !mRecentsAnimationWrapper.hasTargets()) {
mRecentsView.getTaskViewAt(i).setFullscreenProgress(1 - mCurrentShift.value);
}
}
@@ -838,9 +836,15 @@
Interpolator interpolator = DEACCEL;
final boolean goingToNewTask;
if (mRecentsView != null) {
- final int runningTaskIndex = mRecentsView.getRunningTaskIndex();
- final int taskToLaunch = mRecentsView.getNextPage();
- goingToNewTask = runningTaskIndex >= 0 && taskToLaunch != runningTaskIndex;
+ if (!mRecentsAnimationWrapper.hasTargets()) {
+ // If there are no running tasks, then we can assume that this is a continuation of
+ // the last gesture, but after the recents animation has finished
+ goingToNewTask = true;
+ } else {
+ final int runningTaskIndex = mRecentsView.getRunningTaskIndex();
+ final int taskToLaunch = mRecentsView.getNextPage();
+ goingToNewTask = runningTaskIndex >= 0 && taskToLaunch != runningTaskIndex;
+ }
} else {
goingToNewTask = false;
}
@@ -1124,14 +1128,22 @@
mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).launchTask(false /* animate */,
true /* freezeTaskList */);
} else {
+ int taskId = mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).getTask().key.id;
+ mFinishingRecentsAnimationForNewTaskId = taskId;
mRecentsAnimationWrapper.finish(true /* toRecents */, () -> {
- mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).launchTask(
- false /* animate */, true /* freezeTaskList */);
+ if (!mCanceled) {
+ TaskView nextTask = mRecentsView.getTaskView(taskId);
+ if (nextTask != null) {
+ nextTask.launchTask(false /* animate */, true /* freezeTaskList */);
+ doLogGesture(NEW_TASK);
+ }
+ reset();
+ }
+ mCanceled = false;
+ mFinishingRecentsAnimationForNewTaskId = -1;
});
}
TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", true);
- doLogGesture(NEW_TASK);
- reset();
}
public void reset() {
@@ -1142,12 +1154,26 @@
* Cancels any running animation so that the active target can be overriden by a new swipe
* handle (in case of quick switch).
*/
- public void cancelCurrentAnimation() {
+ public void cancelCurrentAnimation(SwipeSharedState sharedState) {
+ mCanceled = true;
mCurrentShift.cancelAnimation();
if (mLauncherTransitionController != null && mLauncherTransitionController
.getAnimationPlayer().isStarted()) {
mLauncherTransitionController.getAnimationPlayer().cancel();
}
+
+ if (mFinishingRecentsAnimationForNewTaskId != -1) {
+ // If we are canceling mid-starting a new task, switch to the screenshot since the
+ // recents animation has finished
+ switchToScreenshot();
+ TaskView newRunningTaskView = mRecentsView.getTaskView(
+ mFinishingRecentsAnimationForNewTaskId);
+ int newRunningTaskId = newRunningTaskView != null
+ ? newRunningTaskView.getTask().key.id
+ : -1;
+ mRecentsView.setCurrentTask(newRunningTaskId);
+ sharedState.setRecentsAnimationFinishInterrupted(newRunningTaskId);
+ }
}
private void invalidateHandler() {
@@ -1169,11 +1195,7 @@
mLauncherTransitionController = null;
}
- mRecentsView.setEnableFreeScroll(true);
- mRecentsView.setRunningTaskIconScaledDown(false);
- mRecentsView.setOnScrollChangeListener(null);
- mRecentsView.setRunningTaskHidden(false);
- mRecentsView.setEnableDrawingLiveTile(true);
+ mRecentsView.onGestureAnimationEnd();
mActivity.getRootView().setOnApplyWindowInsetsListener(null);
mActivity.getRootView().getOverlay().remove(mLiveTileOverlay);
@@ -1194,6 +1216,9 @@
private void switchToScreenshot() {
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
+ } else if (!mRecentsAnimationWrapper.hasTargets()) {
+ // If there are no targets, then we don't need to capture anything
+ setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
} else {
boolean finishTransitionPosted = false;
SwipeAnimationTargetSet controller = mRecentsAnimationWrapper.getController();
@@ -1241,6 +1266,9 @@
private void finishCurrentTransitionToRecents() {
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
setStateOnUiThread(STATE_CURRENT_TASK_FINISHED);
+ } else if (!mRecentsAnimationWrapper.hasTargets()) {
+ // If there are no targets, then there is nothing to finish
+ setStateOnUiThread(STATE_CURRENT_TASK_FINISHED);
} else {
synchronized (mRecentsAnimationWrapper) {
mRecentsAnimationWrapper.finish(true /* toRecents */,
@@ -1267,10 +1295,7 @@
}
mActivityControlHelper.onSwipeUpComplete(mActivity);
mRecentsAnimationWrapper.setCancelWithDeferredScreenshot(true);
-
- // Animate the first icon.
- mRecentsView.animateUpRunningTaskIconScale(mLiveTileOverlay.cancelIconAnimation());
- mRecentsView.setSwipeDownShouldLaunchApp(true);
+ mRecentsView.onSwipeUpAnimationSuccess();
RecentsModel.INSTANCE.get(mContext).onOverviewShown(false, TAG);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java
index 83973fa..f5a9e8a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java
@@ -53,6 +53,20 @@
this.mOnFinishListener = onFinishListener;
}
+ public boolean hasTargets() {
+ return unfilteredApps.length != 0;
+ }
+
+ /**
+ * Clones the target set without any actual targets. Used only when continuing a gesture after
+ * the actual recents animation has finished.
+ */
+ public SwipeAnimationTargetSet cloneWithoutTargets() {
+ return new SwipeAnimationTargetSet(controller, new RemoteAnimationTargetCompat[0],
+ homeContentInsets, minimizedHomeBounds, mShouldMinimizeSplitScreen,
+ mOnFinishListener);
+ }
+
public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint) {
mOnFinishListener.accept(this);
BACKGROUND_EXECUTOR.execute(() -> {
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 b5f90a5..525ead8 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
@@ -744,9 +744,7 @@
public abstract void startHome();
public void reset() {
- setRunningTaskViewShowScreenshot(false);
- mRunningTaskId = -1;
- mRunningTaskTileHidden = false;
+ setCurrentTask(-1);
mIgnoreResetTaskId = -1;
mTaskListChangeId = -1;
@@ -757,6 +755,15 @@
setCurrentPage(0);
}
+ public @Nullable TaskView getRunningTaskView() {
+ return getTaskView(mRunningTaskId);
+ }
+
+ public int getRunningTaskIndex() {
+ TaskView tv = getRunningTaskView();
+ return tv == null ? -1 : indexOfChild(tv);
+ }
+
/**
* Reloads the view if anything in recents changed.
*/
@@ -767,14 +774,50 @@
}
/**
- * Ensures that the first task in the view represents {@param task} and reloads the view
- * if needed. This allows the swipe-up gesture to assume that the first tile always
- * corresponds to the correct task.
- * All subsequent calls to reload will keep the task as the first item until {@link #reset()}
- * is called.
- * Also scrolls the view to this task
+ * Called when a gesture from an app is starting.
*/
- public void showTask(int runningTaskId) {
+ public void onGestureAnimationStart(int runningTaskId) {
+ // This needs to be called before the other states are set since it can create the task view
+ showCurrentTask(runningTaskId);
+ setEnableFreeScroll(false);
+ setEnableDrawingLiveTile(false);
+ setRunningTaskHidden(true);
+ setRunningTaskIconScaledDown(true);
+ }
+
+ /**
+ * Called only when a swipe-up gesture from an app has completed. Only called after
+ * {@link #onGestureAnimationStart} and {@link #onGestureAnimationEnd()}.
+ */
+ public void onSwipeUpAnimationSuccess() {
+ if (getRunningTaskView() != null) {
+ float startProgress = ENABLE_QUICKSTEP_LIVE_TILE.get()
+ ? mLiveTileOverlay.cancelIconAnimation()
+ : 0f;
+ animateUpRunningTaskIconScale(startProgress);
+ }
+ setSwipeDownShouldLaunchApp(true);
+ }
+
+ /**
+ * Called when a gesture from an app has finished.
+ */
+ public void onGestureAnimationEnd() {
+ setEnableFreeScroll(true);
+ setEnableDrawingLiveTile(true);
+ setOnScrollChangeListener(null);
+ setRunningTaskViewShowScreenshot(true);
+ setRunningTaskHidden(false);
+ animateUpRunningTaskIconScale();
+ }
+
+ /**
+ * Creates a task view (if necessary) to represent the task with the {@param runningTaskId}.
+ *
+ * All subsequent calls to reload will keep the task as the first item until {@link #reset()}
+ * is called. Also scrolls the view to this task.
+ */
+ public void showCurrentTask(int runningTaskId) {
if (getChildCount() == 0) {
// Add an empty view for now until the task plan is loaded and applied
final TaskView taskView = mTaskViewPool.getView();
@@ -789,16 +832,33 @@
new ComponentName("", ""), false);
taskView.bind(mTmpRunningTask);
}
+
+ boolean runningTaskTileHidden = mRunningTaskTileHidden;
setCurrentTask(runningTaskId);
+ setCurrentPage(getRunningTaskIndex());
+ setRunningTaskViewShowScreenshot(false);
+ setRunningTaskHidden(runningTaskTileHidden);
+
+ // Reload the task list
+ mTaskListChangeId = mModel.getTasks(this::applyLoadPlan);
}
- public @Nullable TaskView getRunningTaskView() {
- return getTaskView(mRunningTaskId);
- }
+ /**
+ * Sets the running task id, cleaning up the old running task if necessary.
+ * @param runningTaskId
+ */
+ public void setCurrentTask(int runningTaskId) {
+ if (mRunningTaskId == runningTaskId) {
+ return;
+ }
- public int getRunningTaskIndex() {
- TaskView tv = getRunningTaskView();
- return tv == null ? -1 : indexOfChild(tv);
+ if (mRunningTaskId != -1) {
+ // Reset the state on the old running task view
+ setRunningTaskIconScaledDown(false);
+ setRunningTaskViewShowScreenshot(true);
+ setRunningTaskHidden(false);
+ }
+ mRunningTaskId = runningTaskId;
}
/**
@@ -812,27 +872,6 @@
}
}
- /**
- * Similar to {@link #showTask(int)} but does not put any restrictions on the first tile.
- */
- public void setCurrentTask(int runningTaskId) {
- boolean runningTaskTileHidden = mRunningTaskTileHidden;
- boolean runningTaskIconScaledDown = mRunningTaskIconScaledDown;
-
- setRunningTaskIconScaledDown(false);
- setRunningTaskHidden(false);
- setRunningTaskViewShowScreenshot(true);
- mRunningTaskId = runningTaskId;
- setRunningTaskViewShowScreenshot(false);
- setRunningTaskIconScaledDown(runningTaskIconScaledDown);
- setRunningTaskHidden(runningTaskTileHidden);
-
- setCurrentPage(getRunningTaskIndex());
-
- // Load the tasks (if the loading is already
- mTaskListChangeId = mModel.getTasks(this::applyLoadPlan);
- }
-
private void setRunningTaskViewShowScreenshot(boolean showScreenshot) {
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
TaskView runningTaskView = getRunningTaskView();
@@ -1520,7 +1559,9 @@
public abstract boolean shouldUseMultiWindowTaskSizeStrategy();
protected void onTaskLaunched(boolean success) {
- resetTaskVisuals();
+ if (success) {
+ resetTaskVisuals();
+ }
}
@Override
diff --git a/res/layout/hotseat.xml b/res/layout/hotseat.xml
new file mode 100644
index 0000000..82b0b8d
--- /dev/null
+++ b/res/layout/hotseat.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<com.android.launcher3.Hotseat
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/hotseat"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:theme="@style/HomeScreenElementTheme"
+ android:importantForAccessibility="no"
+ launcher:containerType="hotseat" />
\ No newline at end of file
diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml
index 6ecc1f5..cca899b 100644
--- a/res/layout/launcher.xml
+++ b/res/layout/launcher.xml
@@ -39,13 +39,9 @@
launcher:pageIndicator="@+id/page_indicator" />
<!-- DO NOT CHANGE THE ID -->
- <com.android.launcher3.Hotseat
+ <include
android:id="@+id/hotseat"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:theme="@style/HomeScreenElementTheme"
- android:importantForAccessibility="no"
- launcher:containerType="hotseat" />
+ layout="@layout/hotseat" />
<include
android:id="@+id/overview_panel"
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index b640430..80e17c9 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -1072,6 +1072,10 @@
public void setEnableFreeScroll(boolean freeScroll) {
+ if (mFreeScroll == freeScroll) {
+ return;
+ }
+
boolean wasFreeScroll = mFreeScroll;
mFreeScroll = freeScroll;
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index f5c5a8d..87ef044 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -374,16 +374,6 @@
event -> true,
"Pressing Home didn't produce any events");
mDevice.waitForIdle();
-
- // Temporarily press home twice as the first click sometimes gets ignored (b/124239413)
- executeAndWaitForEvent(
- () -> {
- log("LauncherInstrumentation.pressHome before clicking");
- waitForSystemUiObject("home").click();
- },
- event -> true,
- "Pressing Home didn't produce any events");
- mDevice.waitForIdle();
}
try (LauncherInstrumentation.Closable c = addContextLayer(
"performed action to switch to Home - " + action)) {