diff --git a/quickstep/res/layout/taskbar_all_apps_button.xml b/quickstep/res/layout/taskbar_all_apps_button.xml
index 6b665e5623..c50db2e24b 100644
--- a/quickstep/res/layout/taskbar_all_apps_button.xml
+++ b/quickstep/res/layout/taskbar_all_apps_button.xml
@@ -21,5 +21,4 @@
android:layout_height="@dimen/taskbar_icon_min_touch_size"
android:contentDescription="@string/all_apps_button_label"
android:backgroundTint="@android:color/transparent"
- android:icon="@drawable/ic_all_apps_button"
/>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index bd71a9feb6..126ab7c442 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -286,6 +286,8 @@
48dp
48dp
32dp
+ 6dp
+
72dp
@@ -295,6 +297,7 @@
40dp
10dp
32dp
+ 4dp
16dp
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarAutohideSuspendController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarAutohideSuspendController.java
index 2bfc7dd05f..1a54576a7e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarAutohideSuspendController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarAutohideSuspendController.java
@@ -41,12 +41,15 @@ public class TaskbarAutohideSuspendController implements
public static final int FLAG_AUTOHIDE_SUSPEND_TOUCHING = 1 << 2;
// Taskbar EDU overlay is open above the Taskbar. */
public static final int FLAG_AUTOHIDE_SUSPEND_EDU_OPEN = 1 << 3;
+ // Taskbar in immersive mode in overview
+ public static final int FLAG_AUTOHIDE_SUSPEND_IN_LAUNCHER = 1 << 4;
@IntDef(flag = true, value = {
FLAG_AUTOHIDE_SUSPEND_FULLSCREEN,
FLAG_AUTOHIDE_SUSPEND_DRAGGING,
FLAG_AUTOHIDE_SUSPEND_TOUCHING,
FLAG_AUTOHIDE_SUSPEND_EDU_OPEN,
+ FLAG_AUTOHIDE_SUSPEND_IN_LAUNCHER,
})
@Retention(RetentionPolicy.SOURCE)
public @interface AutohideSuspendFlag {}
@@ -92,6 +95,10 @@ public class TaskbarAutohideSuspendController implements
return mAutohideSuspendFlags != 0;
}
+ public boolean isSuspendedForTransientTaskbarInOverview() {
+ return (mAutohideSuspendFlags & FLAG_AUTOHIDE_SUSPEND_IN_LAUNCHER) != 0;
+ }
+
@Override
public void dumpLogs(String prefix, PrintWriter pw) {
pw.println(prefix + "TaskbarAutohideSuspendController:");
@@ -106,6 +113,8 @@ public class TaskbarAutohideSuspendController implements
appendFlag(str, flags, FLAG_AUTOHIDE_SUSPEND_DRAGGING, "FLAG_AUTOHIDE_SUSPEND_DRAGGING");
appendFlag(str, flags, FLAG_AUTOHIDE_SUSPEND_TOUCHING, "FLAG_AUTOHIDE_SUSPEND_TOUCHING");
appendFlag(str, flags, FLAG_AUTOHIDE_SUSPEND_EDU_OPEN, "FLAG_AUTOHIDE_SUSPEND_EDU_OPEN");
+ appendFlag(str, flags, FLAG_AUTOHIDE_SUSPEND_IN_LAUNCHER,
+ "FLAG_AUTOHIDE_SUSPEND_IN_LAUNCHER");
return str.toString();
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 50f5d9e953..bbf861bd8b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -460,7 +460,9 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
return;
}
- if (stash && mControllers.taskbarAutohideSuspendController.isSuspended()) {
+ if (stash && mControllers.taskbarAutohideSuspendController.isSuspended()
+ && !mControllers.taskbarAutohideSuspendController
+ .isSuspendedForTransientTaskbarInOverview()) {
// Avoid stashing if autohide is currently suspended.
return;
}
@@ -955,6 +957,8 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
if (hasAnyFlag(changedFlags, FLAGS_STASHED_IN_APP | FLAGS_IN_APP)) {
notifyStashChange(/* visible */ hasAnyFlag(FLAGS_IN_APP),
/* stashed */ isStashedInApp());
+ mControllers.taskbarAutohideSuspendController.updateFlag(
+ TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_IN_LAUNCHER, !isInApp());
}
if (hasAnyFlag(changedFlags, FLAG_STASHED_IN_APP_MANUAL)) {
if (hasAnyFlag(FLAG_STASHED_IN_APP_MANUAL)) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index c1e85aac2a..0b275a85ce 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -89,6 +89,8 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
private float mTransientTaskbarMinWidth;
+ private float mTransientTaskbarAllAppsButtonTranslationXOffset;
+
public TaskbarView(@NonNull Context context) {
this(context, null);
}
@@ -108,9 +110,14 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
mActivityContext = ActivityContext.lookupContext(context);
mIconLayoutBounds = mActivityContext.getTransientTaskbarBounds();
Resources resources = getResources();
+ boolean isTransientTaskbar = DisplayController.isTransientTaskbar(mActivityContext);
mIsRtl = Utilities.isRtl(resources);
mTransientTaskbarMinWidth = mContext.getResources().getDimension(
R.dimen.transient_taskbar_min_width);
+ mTransientTaskbarAllAppsButtonTranslationXOffset =
+ resources.getDimension(isTransientTaskbar
+ ? R.dimen.transient_taskbar_all_apps_button_translation_x_offset
+ : R.dimen.taskbar_all_apps_button_translation_x_offset);
int actualMargin = resources.getDimensionPixelSize(R.dimen.taskbar_icon_spacing);
int actualIconSize = mActivityContext.getDeviceProfile().iconSizePx;
@@ -130,9 +137,12 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
if (!mActivityContext.getPackageManager().hasSystemFeature(FEATURE_PC)) {
mAllAppsButton = (IconButtonView) LayoutInflater.from(context)
.inflate(R.layout.taskbar_all_apps_button, this, false);
+ mAllAppsButton.setIconDrawable(resources.getDrawable(isTransientTaskbar
+ ? R.drawable.ic_transient_taskbar_all_apps_button
+ : R.drawable.ic_taskbar_all_apps_button));
mAllAppsButton.setScaleX(mIsRtl ? -1 : 1);
- mAllAppsButton.setForegroundTint(mActivityContext.getColor(
- DisplayController.isTransientTaskbar(mActivityContext)
+ mAllAppsButton.setPadding(mItemPadding, mItemPadding, mItemPadding, mItemPadding);
+ mAllAppsButton.setForegroundTint(mActivityContext.getColor(isTransientTaskbar
? R.color.all_apps_button_color
: R.color.all_apps_button_color_dark));
@@ -276,6 +286,8 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
}
if (mAllAppsButton != null) {
+ mAllAppsButton.setTranslationXForTaskbarAllAppsIcon(getChildCount() > 0
+ ? mTransientTaskbarAllAppsButtonTranslationXOffset : 0f);
addView(mAllAppsButton, mIsRtl ? getChildCount() : 0);
// if only all apps button present, don't include divider view.
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index e8e83288cd..07fcf48a07 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -121,8 +121,7 @@ public final class RecentsViewStateController extends
private void handleSplitSelectionState(@NonNull LauncherState toState,
@NonNull PendingAnimation builder, boolean animate) {
if (toState != OVERVIEW_SPLIT_SELECT) {
- // Not going to split, nothing to do but ensure taskviews are at correct offset
- mRecentsView.resetSplitPrimaryScrollOffset();
+ // Not going to split
return;
}
@@ -153,8 +152,6 @@ public final class RecentsViewStateController extends
as.start();
as.end();
}
-
- mRecentsView.applySplitPrimaryScrollOffset();
}
private void setAlphas(PropertySetter propertySetter, StateAnimationConfig config,
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 933fb49371..ceb7d4bdab 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -677,7 +677,7 @@ public abstract class AbsSwipeUpHandler,
@Override
public void onMotionPauseDetected() {
mHasMotionEverBeenPaused = true;
- maybeUpdateRecentsAttachedState(true/* animate */, true/* moveFocusedTask */);
+ maybeUpdateRecentsAttachedState(true/* animate */, true/* moveRunningTask */);
Optional.ofNullable(mActivityInterface.getTaskbarController())
.ifPresent(TaskbarUIController::startTranslationSpring);
performHapticFeedback();
@@ -695,7 +695,7 @@ public abstract class AbsSwipeUpHandler,
}
private void maybeUpdateRecentsAttachedState(boolean animate) {
- maybeUpdateRecentsAttachedState(animate, false /* moveFocusedTask */);
+ maybeUpdateRecentsAttachedState(animate, false /* moveRunningTask */);
}
/**
@@ -705,9 +705,9 @@ public abstract class AbsSwipeUpHandler,
*
* Note this method has no effect unless the navigation mode is NO_BUTTON.
* @param animate whether to animate when attaching RecentsView
- * @param moveFocusedTask whether to move focused task to front when attaching
+ * @param moveRunningTask whether to move running task to front when attaching
*/
- private void maybeUpdateRecentsAttachedState(boolean animate, boolean moveFocusedTask) {
+ private void maybeUpdateRecentsAttachedState(boolean animate, boolean moveRunningTask) {
if (!mDeviceState.isFullyGesturalNavMode() || mRecentsView == null) {
return;
}
@@ -726,11 +726,11 @@ public abstract class AbsSwipeUpHandler,
} else {
recentsAttachedToAppWindow = mHasMotionEverBeenPaused || mIsLikelyToStartNewTask;
}
- if (moveFocusedTask && !mAnimationFactory.hasRecentsEverAttachedToAppWindow()
+ if (moveRunningTask && !mAnimationFactory.hasRecentsEverAttachedToAppWindow()
&& recentsAttachedToAppWindow) {
- // Only move focused task if RecentsView has never been attached before, to avoid
+ // Only move running task if RecentsView has never been attached before, to avoid
// TaskView jumping to new position as we move the tasks.
- mRecentsView.moveFocusedTaskToFront();
+ mRecentsView.moveRunningTaskToFront();
}
mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate);
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 998439e891..d7ff8ab3fc 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -231,17 +231,20 @@ public abstract class BaseActivityInterface visibleRecentsView = activityInterface.getVisibleRecentsView();
if (visibleRecentsView != null) {
- visibleRecentsView.moveFocusedTaskToFront();
+ visibleRecentsView.moveRunningTaskToFront();
}
if (mTaskAnimationManager.isRecentsAnimationRunning()) {
cmd.mActiveCallbacks = mTaskAnimationManager.continueRecentsAnimation(gestureState);
diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
index 54e4a0d3f1..5391f4d46c 100644
--- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
+++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
@@ -59,7 +59,7 @@ public class QuickstepTestInformationHandler extends TestInformationHandler {
}
Rect focusedTaskRect = new Rect();
LauncherActivityInterface.INSTANCE.calculateTaskSize(mContext, mDeviceProfile,
- focusedTaskRect);
+ focusedTaskRect, PagedOrientationHandler.PORTRAIT);
response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, focusedTaskRect.height());
return response;
}
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
index 062e50e30b..11b1ab8ec9 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
@@ -130,15 +130,9 @@ public class FallbackRecentsStateController implements StateHandler extends FrameLayo
requestLayout();
- mSplitButton.setCompoundDrawablesWithIntrinsicBounds(
+ mSplitButton.setCompoundDrawablesRelativeWithIntrinsicBounds(
(dp.isLandscape ? R.drawable.ic_split_horizontal : R.drawable.ic_split_vertical),
0, 0, 0);
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index b237f8315f..752c3d505e 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -53,8 +53,6 @@ import static com.android.launcher3.touch.PagedOrientationHandler.CANVAS_TRANSLA
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
import static com.android.quickstep.views.ClearAllButton.DISMISS_ALPHA;
@@ -80,7 +78,6 @@ import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.WindowConfiguration;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.LocusId;
@@ -518,6 +515,7 @@ public abstract class RecentsView 0) {
TaskView taskView = requireTaskViewAt(0);
@@ -1733,12 +1720,12 @@ public abstract class RecentsView setCurrentPage(getRunningTaskIndex()));
setRunningTaskViewShowScreenshot(false);
setRunningTaskHidden(runningTaskTileHidden);
@@ -2721,7 +2709,8 @@ public abstract class RecentsView 0 && mTopRowIdSet.size() >= (taskCount - 1) / 2f;
- // Pick the next focused task from the preferred row.
- for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
- if (taskView == dismissedTaskView) {
- continue;
+ if (isFocusedTaskDismissed) {
+ if (isSplitSelectionActive()) {
+ isStagingFocusedTask = true;
+ } else {
+ nextFocusedTaskFromTop =
+ mTopRowIdSet.size() > 0 && mTopRowIdSet.size() >= (taskCount - 1) / 2f;
+ // Pick the next focused task from the preferred row.
+ for (int i = 0; i < taskCount; i++) {
+ TaskView taskView = requireTaskViewAt(i);
+ if (taskView == dismissedTaskView) {
+ continue;
+ }
+ boolean isTopRow = mTopRowIdSet.contains(taskView.getTaskViewId());
+ if ((nextFocusedTaskFromTop && isTopRow
+ || (!nextFocusedTaskFromTop && !isTopRow))) {
+ nextFocusedTaskView = taskView;
+ break;
+ }
}
- boolean isTopRow = mTopRowIdSet.contains(taskView.getTaskViewId());
- if ((nextFocusedTaskFromTop && isTopRow
- || (!nextFocusedTaskFromTop && !isTopRow))) {
- nextFocusedTaskView = taskView;
- break;
+ if (nextFocusedTaskView != null) {
+ nextFocusedTaskWidth =
+ nextFocusedTaskView.getLayoutParams().width + mPageSpacing;
}
}
- if (nextFocusedTaskView != null) {
- nextFocusedTaskWidth =
- nextFocusedTaskView.getLayoutParams().width + mPageSpacing;
- }
}
} else {
getPageScrolls(oldScroll, false, SIMPLE_SCROLL_LOGIC);
@@ -3246,8 +3254,6 @@ public abstract class RecentsView bottomGridRowSize;
boolean bottomRowLonger = bottomGridRowSize > topGridRowSize;
boolean dismissedTaskFromTop = mTopRowIdSet.contains(dismissedTaskViewId);
boolean dismissedTaskFromBottom = !dismissedTaskFromTop && !isFocusedTaskDismissed;
+ if (dismissedTaskFromTop || (isFocusedTaskDismissed && nextFocusedTaskFromTop)) {
+ topGridRowSize--;
+ }
+ if (dismissedTaskFromBottom || (isFocusedTaskDismissed && !nextFocusedTaskFromTop)) {
+ bottomGridRowSize--;
+ }
+ int longRowWidth = Math.max(topGridRowSize, bottomGridRowSize)
+ * (mLastComputedGridTaskSize.width() + mPageSpacing);
+ if (!ENABLE_GRID_ONLY_OVERVIEW.get() && !isStagingFocusedTask) {
+ longRowWidth += mLastComputedTaskSize.width() + mPageSpacing;
+ }
+
float gapWidth = 0;
if ((topRowLonger && dismissedTaskFromTop)
|| (bottomRowLonger && dismissedTaskFromBottom)) {
gapWidth = dismissedTaskWidth;
- } else if ((topRowLonger && nextFocusedTaskFromTop)
- || (bottomRowLonger && !nextFocusedTaskFromTop)) {
+ } else if (nextFocusedTaskView != null
+ && ((topRowLonger && nextFocusedTaskFromTop)
+ || (bottomRowLonger && !nextFocusedTaskFromTop))) {
gapWidth = nextFocusedTaskWidth;
}
if (gapWidth > 0) {
- if (taskCount > 2) {
- // Compensate the removed gap.
- longGridRowWidthDiff += mIsRtl ? -gapWidth : gapWidth;
- if (isClearAllHidden) {
- // If ClearAllButton isn't fully shown, snap to the last task.
- snapToLastTask = true;
+ if (mClearAllShortTotalWidthTranslation == 0) {
+ // Compensate the removed gap if we don't already have shortTotalCompensation,
+ // and adjust accordingly to the new shortTotalCompensation after dismiss.
+ int newClearAllShortTotalWidthTranslation = 0;
+ if (longRowWidth < mLastComputedGridSize.width()) {
+ DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+ newClearAllShortTotalWidthTranslation =
+ (mIsRtl
+ ? mLastComputedTaskSize.right
+ : deviceProfile.widthPx - mLastComputedTaskSize.left)
+ - longRowWidth - deviceProfile.overviewGridSideMargin;
}
- } else {
- // If only focused task will be left, snap to focused task instead.
- longGridRowWidthDiff += getSnapToFocusedTaskScrollDiff(isClearAllHidden);
+ float gapCompensation = gapWidth - newClearAllShortTotalWidthTranslation;
+ longGridRowWidthDiff += mIsRtl ? -gapCompensation : gapCompensation;
+ }
+ if (isClearAllHidden) {
+ // If ClearAllButton isn't fully shown, snap to the last task.
+ snapToLastTask = true;
}
}
- if (mClearAllButton.getAlpha() != 0f && isLandscapeSplit) {
- // ClearAllButton will not be available in split select, snap to last task instead.
- snapToLastTask = true;
+ if (isLandscapeSplit && !isStagingFocusedTask) {
+ // LastTask's scroll is the minimum scroll in split select, if current scroll is
+ // beyond that, we'll need to snap to last task instead.
+ TaskView lastTask = getLastGridTaskView();
+ if (lastTask != null) {
+ int primaryScroll = mOrientationHandler.getPrimaryScroll(this);
+ int lastTaskScroll = getScrollForPage(indexOfChild(lastTask));
+ if ((mIsRtl && primaryScroll < lastTaskScroll)
+ || (!mIsRtl && primaryScroll > lastTaskScroll)) {
+ snapToLastTask = true;
+ }
+ }
}
if (snapToLastTask) {
longGridRowWidthDiff += getSnapToLastTaskScrollDiff();
- if (isSplitPlaceholderLastInGrid) {
- // Shift all the tasks to make space for split placeholder.
- longGridRowWidthDiff += mIsRtl ? mSplitPlaceholderSize : -mSplitPlaceholderSize;
- }
} else if (isLandscapeSplit && currentPageSnapsToEndOfGrid) {
// Use last task as reference point for scroll diff and snapping calculation as it's
// the only invariant point in landscape split screen.
@@ -3452,8 +3485,6 @@ public abstract class RecentsView lastTaskScroll)) {
pageScroll = lastTaskScroll;
@@ -5283,8 +5258,7 @@ public abstract class RecentsView= 0
&& (mIsRtl
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index fb856058db..b9aaef63ca 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -375,7 +375,6 @@ public class TaskView extends FrameLayout implements Reusable {
// Used when in SplitScreenSelectState
private float mSplitSelectTranslationY;
private float mSplitSelectTranslationX;
- private float mSplitSelectScrollOffsetPrimary;
@Nullable
private ObjectAnimator mIconAndDimAnimator;
@@ -1297,10 +1296,6 @@ public class TaskView extends FrameLayout implements Reusable {
applyTranslationY();
}
- public void setSplitScrollOffsetPrimary(float splitSelectScrollOffsetPrimary) {
- mSplitSelectScrollOffsetPrimary = splitSelectScrollOffsetPrimary;
- }
-
private void setDismissTranslationX(float x) {
mDismissTranslationX = x;
applyTranslationX();
@@ -1364,19 +1359,18 @@ public class TaskView extends FrameLayout implements Reusable {
applyTranslationX();
}
- public float getScrollAdjustment(boolean fullscreenEnabled, boolean gridEnabled) {
+ public float getScrollAdjustment(boolean gridEnabled) {
float scrollAdjustment = 0;
if (gridEnabled) {
scrollAdjustment += mGridTranslationX;
} else {
scrollAdjustment += getPrimaryNonGridTranslationProperty().get(this);
}
- scrollAdjustment += mSplitSelectScrollOffsetPrimary;
return scrollAdjustment;
}
- public float getOffsetAdjustment(boolean fullscreenEnabled, boolean gridEnabled) {
- return getScrollAdjustment(fullscreenEnabled, gridEnabled);
+ public float getOffsetAdjustment(boolean gridEnabled) {
+ return getScrollAdjustment(gridEnabled);
}
public float getSizeAdjustment(boolean fullscreenEnabled) {
diff --git a/res/drawable-sw600dp/ic_transient_taskbar_all_apps_button.xml b/res/drawable-sw600dp/ic_transient_taskbar_all_apps_button.xml
new file mode 100644
index 0000000000..6e740aed4f
--- /dev/null
+++ b/res/drawable-sw600dp/ic_transient_taskbar_all_apps_button.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/ic_all_apps_button.xml b/res/drawable-sw720dp/ic_transient_taskbar_all_apps_button.xml
similarity index 100%
rename from res/drawable/ic_all_apps_button.xml
rename to res/drawable-sw720dp/ic_transient_taskbar_all_apps_button.xml
diff --git a/res/drawable/ic_taskbar_all_apps_button.xml b/res/drawable/ic_taskbar_all_apps_button.xml
new file mode 100644
index 0000000000..82fbbea617
--- /dev/null
+++ b/res/drawable/ic_taskbar_all_apps_button.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 9e28608d8b..df38c26a1b 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -113,6 +113,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
private float mScaleForReorderBounce = 1f;
+ private float mTranslationXForTaskbarAllAppsIcon = 0f;
+
private static final Property DOT_SCALE_PROPERTY
= new Property(Float.TYPE, "dotScale") {
@Override
@@ -961,6 +963,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
private void updateTranslation() {
super.setTranslationX(mTranslationForReorderBounce.x
+ mTranslationForReorderPreview.x
+ + mTranslationXForTaskbarAllAppsIcon
+ mTranslationForMoveFromCenterAnimation.x
+ mTranslationXForTaskbarAlignmentAnimation
+ mTranslationXForTaskbarRevealAnimation
@@ -972,6 +975,14 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
+ mTranslationYForTaskbarRevealAnimation);
}
+ /**
+ * Sets translationX for taskbar all apps icon
+ */
+ public void setTranslationXForTaskbarAllAppsIcon(float translationX) {
+ mTranslationXForTaskbarAllAppsIcon = translationX;
+ updateTranslation();
+ }
+
public void setReorderBounceOffset(float x, float y) {
mTranslationForReorderBounce.set(x, y);
updateTranslation();
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 06ea72c7ee..de60d05b3f 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1860,6 +1860,9 @@ public class Launcher extends StatefulActivity
}
private void setWorkspaceLoading(boolean value) {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.FLAKY_BINDING, "running: setWorkspaceLoading=" + value);
+ }
mWorkspaceLoading = value;
}
@@ -2306,6 +2309,9 @@ public class Launcher extends StatefulActivity
*/
public void startBinding() {
Object traceToken = TraceHelper.INSTANCE.beginSection("startBinding");
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.FLAKY_BINDING, "running: startBinding");
+ }
// Floating panels (except the full widget sheet) are associated with individual icons. If
// we are starting a fresh bind, close all such panels as all the icons are about
// to go away.
@@ -2778,6 +2784,9 @@ public class Launcher extends StatefulActivity
*/
public void finishBindingItems(IntSet pagesBoundFirst) {
Object traceToken = TraceHelper.INSTANCE.beginSection("finishBindingItems");
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.FLAKY_BINDING, "running: finishBindingItems");
+ }
mWorkspace.restoreInstanceStateForRemainingPages();
setWorkspaceLoading(false);
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 13efa674f3..7b9f605d87 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -134,10 +134,10 @@ public final class Utilities {
/**
* 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.
+ * @deprecated Use {@link BuildConfig#IS_DEBUG_DEVICE} directly
*/
- public static final boolean IS_DEBUG_DEVICE =
- Build.TYPE.toLowerCase(Locale.ROOT).contains("debug") ||
- Build.TYPE.toLowerCase(Locale.ROOT).equals("eng");
+ @Deprecated
+ public static final boolean IS_DEBUG_DEVICE = BuildConfig.IS_DEBUG_DEVICE;
/**
* Returns true if theme is dark.
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index a9e3d8d4bd..0037283e62 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -42,18 +42,22 @@ public final class FeatureFlags {
}
public static boolean showFlagTogglerUi(Context context) {
- return Utilities.IS_DEBUG_DEVICE && Utilities.isDevelopersOptionsEnabled(context);
+ return BuildConfig.IS_DEBUG_DEVICE && Utilities.isDevelopersOptionsEnabled(context);
}
/**
* True when the build has come from Android Studio and is being used for local debugging.
+ * @deprecated Use {@link BuildConfig#IS_STUDIO_BUILD} directly
*/
- public static final boolean IS_STUDIO_BUILD = BuildConfig.DEBUG;
+ @Deprecated
+ public static final boolean IS_STUDIO_BUILD = BuildConfig.IS_STUDIO_BUILD;
/**
* Enable moving the QSB on the 0th screen of the workspace. This is not a configuration feature
* and should be modified at a project level.
+ * @deprecated Use {@link BuildConfig#QSB_ON_FIRST_SCREEN} directly
*/
+ @Deprecated
public static final boolean QSB_ON_FIRST_SCREEN = BuildConfig.QSB_ON_FIRST_SCREEN;
/**
diff --git a/src/com/android/launcher3/model/BaseLauncherBinder.java b/src/com/android/launcher3/model/BaseLauncherBinder.java
index 9f8db51629..8519a3ef52 100644
--- a/src/com/android/launcher3/model/BaseLauncherBinder.java
+++ b/src/com/android/launcher3/model/BaseLauncherBinder.java
@@ -246,6 +246,9 @@ public abstract class BaseLauncherBinder {
sortWorkspaceItemsSpatially(idp, otherWorkspaceItems);
// Tell the workspace that we're about to start binding items
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.FLAKY_BINDING, "scheduling: startBinding");
+ }
executeCallbacksTask(c -> {
c.clearPendingBinds();
c.startBinding();
@@ -264,6 +267,9 @@ public abstract class BaseLauncherBinder {
Executor pendingExecutor = pendingTasks::add;
bindWorkspaceItems(otherWorkspaceItems, pendingExecutor);
bindAppWidgets(otherAppWidgets, pendingExecutor);
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.FLAKY_BINDING, "scheduling: finishBindingItems");
+ }
executeCallbacksTask(c -> c.finishBindingItems(currentScreenIds), pendingExecutor);
pendingExecutor.execute(
() -> {
diff --git a/src/com/android/launcher3/views/IconButtonView.java b/src/com/android/launcher3/views/IconButtonView.java
index 64e9327dfa..9969eebe06 100644
--- a/src/com/android/launcher3/views/IconButtonView.java
+++ b/src/com/android/launcher3/views/IconButtonView.java
@@ -31,6 +31,7 @@ import android.os.Build;
import android.util.AttributeSet;
import androidx.annotation.ColorInt;
+import androidx.annotation.NonNull;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.icons.BaseIconFactory;
@@ -70,6 +71,15 @@ public class IconButtonView extends BubbleTextView {
}
}
+ /** Sets given Drawable as icon */
+ public void setIconDrawable(@NonNull Drawable drawable) {
+ ColorStateList tintList = getBackgroundTintList();
+ int tint = tintList == null ? Color.WHITE : tintList.getDefaultColor();
+ try (BaseIconFactory factory = LauncherIcons.obtain(getContext())) {
+ setIcon(new IconDrawable(factory.getWhiteShadowLayer(), tint, drawable));
+ }
+ }
+
/** Updates the color of the icon's foreground layer. */
public void setForegroundTint(@ColorInt int tintColor) {
FastBitmapDrawable icon = getIcon();
diff --git a/src_build_config/com/android/launcher3/BuildConfig.java b/src_build_config/com/android/launcher3/BuildConfig.java
index 9a81d3f54c..1f2e0e5387 100644
--- a/src_build_config/com/android/launcher3/BuildConfig.java
+++ b/src_build_config/com/android/launcher3/BuildConfig.java
@@ -18,10 +18,16 @@ package com.android.launcher3;
public final class BuildConfig {
public static final String APPLICATION_ID = "com.android.launcher3";
- public static final boolean DEBUG = false;
+
+ public static final boolean IS_STUDIO_BUILD = false;
/**
* Flag to state if the QSB is on the first screen and placed on the top,
* this can be overwritten in other launchers with a different value, if needed.
*/
public static final boolean QSB_ON_FIRST_SCREEN = true;
+
+ /**
+ * Flag to control various developer centric features
+ */
+ public static final boolean IS_DEBUG_DEVICE = false;
}
diff --git a/tests/Android.bp b/tests/Android.bp
index 7144d65d64..dfbaf86a50 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -44,6 +44,7 @@ filegroup {
srcs: [
"src/com/android/launcher3/ui/AbstractLauncherUiTest.java",
"src/com/android/launcher3/ui/PortraitLandscapeRunner.java",
+ "src/com/android/launcher3/ui/TaplTestsLauncher3.java",
"src/com/android/launcher3/util/TestUtil.java",
"src/com/android/launcher3/util/Wait.java",
"src/com/android/launcher3/util/WidgetUtils.java",
@@ -54,7 +55,7 @@ filegroup {
"src/com/android/launcher3/util/rule/ShellCommandRule.java",
"src/com/android/launcher3/util/rule/SimpleActivityRule.java",
"src/com/android/launcher3/util/rule/TestStabilityRule.java",
- "src/com/android/launcher3/ui/TaplTestsLauncher3.java",
+ "src/com/android/launcher3/util/rule/TISBindRule.java",
"src/com/android/launcher3/testcomponent/BaseTestingActivity.java",
"src/com/android/launcher3/testcomponent/OtherBaseTestingActivity.java",
"src/com/android/launcher3/testcomponent/CustomShortcutConfigActivity.java",
diff --git a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
index 65873f199e..cc6fa33609 100644
--- a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
@@ -154,6 +154,7 @@ public final class TestProtocol {
public static final String MISSING_PROMISE_ICON = "b/202985412";
public static final String TASKBAR_IN_APP_STATE = "b/227657604";
public static final String NPE_TRANSIENT_TASKBAR = "b/257549303";
+ public static final String FLAKY_BINDING = "b/270216650";
public static final String REQUEST_EMULATE_DISPLAY = "emulate-display";
public static final String REQUEST_STOP_EMULATE_DISPLAY = "stop-emulate-display";
diff --git a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
index 77fca96f04..c2fe3de407 100644
--- a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
+++ b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
@@ -33,6 +33,7 @@ import com.android.launcher3.celllayout.testcases.ReorderTestCase;
import com.android.launcher3.celllayout.testcases.SimpleReorderCase;
import com.android.launcher3.tapl.Widget;
import com.android.launcher3.tapl.WidgetResizeFrame;
+import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.ui.TaplTestsLauncher3;
import com.android.launcher3.util.rule.ShellCommandRule;
@@ -118,7 +119,14 @@ public class ReorderWidgets extends AbstractLauncherUiTest {
// waitForLauncherCondition to wait for that condition, otherwise the condition would
// always be true and it wouldn't wait for the changes to be applied.
resetLoaderState();
- waitForLauncherCondition("Workspace didn't finish loading", l -> !l.isWorkspaceLoading());
+ Log.d(TestProtocol.FLAKY_BINDING, "waiting for: isWorkspaceLoading=false");
+ waitForLauncherCondition("Workspace didn't finish loading", l -> {
+ boolean isWorkspaceLoading = l.isWorkspaceLoading();
+
+ Log.d(TestProtocol.FLAKY_BINDING, "checking: isWorkspaceLoading=" + isWorkspaceLoading);
+
+ return !isWorkspaceLoading;
+ });
Widget widget = mLauncher.getWorkspace().getWidgetAtCell(mainWidgetCellPos.getCellX(),
mainWidgetCellPos.getCellY());
assertNotNull(widget);
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 393c54f2f0..66187659db 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -52,11 +52,13 @@ import com.android.launcher3.tapl.Widgets;
import com.android.launcher3.tapl.Workspace;
import com.android.launcher3.util.TestUtil;
import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
+import com.android.launcher3.util.rule.TISBindRule;
import com.android.launcher3.widget.picker.WidgetsFullSheet;
import com.android.launcher3.widget.picker.WidgetsRecyclerView;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -72,6 +74,9 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
private static final String STORE_APP_NAME = "Play Store";
private static final String GMAIL_APP_NAME = "Gmail";
+ @Rule
+ public TISBindRule mTISBindRule = new TISBindRule();
+
@Before
public void setUp() throws Exception {
super.setUp();
@@ -215,7 +220,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
false /* tapRight */);
}
- @IwTest(focusArea="launcher")
+ @IwTest(focusArea = "launcher")
@Test
@ScreenRecord // b/202433017
public void testWorkspace() throws Exception {
@@ -342,7 +347,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
}
}
- @IwTest(focusArea="launcher")
+ @IwTest(focusArea = "launcher")
@Test
@PortraitLandscape
@ScreenRecord // b/256898879
@@ -614,16 +619,16 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
/**
* @return List of workspace grid coordinates. Those are not pixels. See {@link
- * Workspace#getIconGridDimensions()}
+ * Workspace#getIconGridDimensions()}
*/
private Point[] getCornersAndCenterPositions() {
final Point dimensions = mLauncher.getWorkspace().getIconGridDimensions();
- return new Point[] {
- new Point(0, 1),
- new Point(0, dimensions.y - 2),
- new Point(dimensions.x - 1, 1),
- new Point(dimensions.x - 1, dimensions.y - 2),
- new Point(dimensions.x / 2, dimensions.y / 2)
+ return new Point[]{
+ new Point(0, 1),
+ new Point(0, dimensions.y - 2),
+ new Point(dimensions.x - 1, 1),
+ new Point(dimensions.x - 1, dimensions.y - 2),
+ new Point(dimensions.x / 2, dimensions.y / 2)
};
}
diff --git a/tests/src/com/android/launcher3/util/rule/TISBindRule.java b/tests/src/com/android/launcher3/util/rule/TISBindRule.java
new file mode 100644
index 0000000000..3ec4a29cdf
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/rule/TISBindRule.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util.rule;
+
+import android.app.UiAutomation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+public class TISBindRule implements TestRule {
+ public static String TAG = "TISBindRule";
+ public static String INTENT_FILTER = "android.intent.action.QUICKSTEP_SERVICE";
+ public static String TIS_PERMISSIONS = "android.permission.STATUS_BAR_SERVICE";
+
+ private String getLauncherPackageName(Context context) {
+ return ComponentName.unflattenFromString(context.getString(
+ com.android.internal.R.string.config_recentsComponentName)).getPackageName();
+ }
+
+ private ServiceConnection createConnection() {
+ return new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
+ Log.d(TAG, "Connected to TouchInteractionService");
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName componentName) {
+ Log.d(TAG, "Disconnected from TouchInteractionService");
+ }
+ };
+ }
+
+ @NonNull
+ @Override
+ public Statement apply(@NonNull Statement base, @NonNull Description description) {
+ return new Statement() {
+
+ @Override
+ public void evaluate() throws Throwable {
+ Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ final ServiceConnection connection = createConnection();
+ UiAutomation uiAutomation =
+ InstrumentationRegistry.getInstrumentation().getUiAutomation();
+ uiAutomation.adoptShellPermissionIdentity(TIS_PERMISSIONS);
+ Intent launchIntent = new Intent(INTENT_FILTER);
+ launchIntent.setPackage(getLauncherPackageName(context));
+ context.bindService(launchIntent, connection, Context.BIND_AUTO_CREATE);
+ uiAutomation.dropShellPermissionIdentity();
+ try {
+ base.evaluate();
+ } finally {
+ context.unbindService(connection);
+ }
+ }
+ };
+ }
+}