Merge "Removing some dependencies on Activity" into main
diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig
index 7c6d7a8..ace2210 100644
--- a/aconfig/launcher.aconfig
+++ b/aconfig/launcher.aconfig
@@ -48,3 +48,10 @@
description: "Enables taskbar with no recreation from lifecycle changes of TaskbarActivityContext."
bug: "299193589"
}
+
+flag {
+ name: "enable_home_transition_listener"
+ namespace: "launcher"
+ description: "Enables launcher to listen to all transitions that include home activity"
+ bug: "306053414"
+}
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index f8b08f8..dde69e3 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -135,7 +135,7 @@
}
}
-// Next value 52
+// Next value 53
enum Attribute {
option allow_alias = true;
@@ -188,6 +188,7 @@
ALL_APPS_SEARCH_RESULT_EDUCARD = 43;
ALL_APPS_SEARCH_RESULT_LOCATION = 50;
ALL_APPS_SEARCH_RESULT_TEXT_HEADER = 51;
+ ALL_APPS_SEARCH_RESULT_NO_FULFILLMENT = 52;
// Result sources
DATA_SOURCE_APPSEARCH_APP_PREVIEW = 45;
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index c5d0b95..e77d2c6 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -1057,9 +1057,9 @@
boolean allowBlurringLauncher = mLauncher.getStateManager().getState() != OVERVIEW
&& BlurUtils.supportsBlursOnWindows();
- ObjectAnimator backgroundRadiusAnim =
- ObjectAnimator.ofFloat(mLauncher.getDepthController().stateDepth,
- MULTI_PROPERTY_VALUE, BACKGROUND_APP.getDepth(mLauncher))
+ LaunchDepthController depthController = new LaunchDepthController(mLauncher);
+ ObjectAnimator backgroundRadiusAnim = ObjectAnimator.ofFloat(depthController.stateDepth,
+ MULTI_PROPERTY_VALUE, BACKGROUND_APP.getDepth(mLauncher))
.setDuration(APP_LAUNCH_DURATION);
if (allowBlurringLauncher) {
@@ -1085,6 +1085,9 @@
new SurfaceControl.Transaction().remove(dimLayer).apply()));
}
+ backgroundRadiusAnim.addListener(
+ AnimatorListeners.forEndCallback(depthController::dispose));
+
return backgroundRadiusAnim;
}
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index 957db64..882682d 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -94,6 +94,18 @@
}
}
+ /**
+ * Cleans up after this controller so it can be garbage collected without leaving traces.
+ */
+ public void dispose() {
+ removeSecondaryListeners();
+
+ if (mLauncher.getRootView() != null && mOnAttachListener != null) {
+ mLauncher.getRootView().removeOnAttachStateChangeListener(mOnAttachListener);
+ mOnAttachListener = null;
+ }
+ }
+
private void removeSecondaryListeners() {
if (mCrossWindowBlurListener != null) {
CrossWindowBlurListeners.getInstance().removeListener(mCrossWindowBlurListener);
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 445a1bd..09376d7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -16,7 +16,6 @@
package com.android.launcher3.taskbar;
import static com.android.launcher3.QuickstepTransitionManager.TRANSIENT_TASKBAR_TRANSITION_DURATION;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_HOME_TRANSITION_LISTENER;
import static com.android.launcher3.statemanager.BaseState.FLAG_NON_INTERACTIVE;
import static com.android.launcher3.taskbar.TaskbarEduTooltipControllerKt.TOOLTIP_STEP_FEATURES;
import static com.android.launcher3.taskbar.TaskbarLauncherStateController.FLAG_VISIBLE;
@@ -39,6 +38,7 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatedFloat;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.model.data.ItemInfo;
@@ -101,7 +101,7 @@
mLauncher.setTaskbarUIController(this);
- if (!ENABLE_HOME_TRANSITION_LISTENER.get()) {
+ if (!FeatureFlags.enableHomeTransitionListener()) {
onLauncherVisibilityChanged(mLauncher.hasBeenResumed(), true /* fromInit */);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 6aadd65..6ee151b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -129,6 +129,7 @@
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Optional;
+import java.util.function.Consumer;
/**
* The {@link ActivityContext} with which we inflate Taskbar-related Views. This allows UI elements
@@ -299,38 +300,31 @@
* the icon size
*/
private void applyDeviceProfile(DeviceProfile originDeviceProfile) {
- mDeviceProfile = originDeviceProfile.toBuilder(this)
- .withDimensionsOverride(deviceProfile -> {
- // Taskbar should match the number of icons of hotseat
- deviceProfile.numShownHotseatIcons = originDeviceProfile.numShownHotseatIcons;
- // Same QSB width to have a smooth animation
- deviceProfile.hotseatQsbWidth = originDeviceProfile.hotseatQsbWidth;
+ Consumer<DeviceProfile> overrideProvider = deviceProfile -> {
+ // Taskbar should match the number of icons of hotseat
+ deviceProfile.numShownHotseatIcons = originDeviceProfile.numShownHotseatIcons;
+ // Same QSB width to have a smooth animation
+ deviceProfile.hotseatQsbWidth = originDeviceProfile.hotseatQsbWidth;
- // Update icon size
- deviceProfile.iconSizePx = deviceProfile.taskbarIconSize;
- deviceProfile.updateIconSize(1f, getResources());
- }).build();
+ // Update icon size
+ deviceProfile.iconSizePx = deviceProfile.taskbarIconSize;
+ deviceProfile.updateIconSize(1f, getResources());
+ };
+ mDeviceProfile = originDeviceProfile.toBuilder(this)
+ .withDimensionsOverride(overrideProvider).build();
if (DisplayController.isTransientTaskbar(this)) {
mTransientTaskbarDeviceProfile = mDeviceProfile;
mPersistentTaskbarDeviceProfile = mDeviceProfile
.toBuilder(this)
- .withDimensionsOverride(deviceProfile -> {
- // Update icon size
- deviceProfile.iconSizePx = deviceProfile.taskbarIconSize;
- deviceProfile.updateIconSize(1f, getResources());
- })
+ .withDimensionsOverride(overrideProvider)
.setIsTransientTaskbar(false)
.build();
} else {
mPersistentTaskbarDeviceProfile = mDeviceProfile;
mTransientTaskbarDeviceProfile = mDeviceProfile
.toBuilder(this)
- .withDimensionsOverride(deviceProfile -> {
- // Update icon size
- deviceProfile.iconSizePx = deviceProfile.taskbarIconSize;
- deviceProfile.updateIconSize(1f, getResources());
- })
+ .withDimensionsOverride(overrideProvider)
.setIsTransientTaskbar(true)
.build();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt
index e4ebf65..d6016f1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt
@@ -32,6 +32,7 @@
import com.android.launcher3.taskbar.TaskbarPinningController.Companion.PINNING_PERSISTENT
import com.android.launcher3.taskbar.TaskbarPinningController.Companion.PINNING_TRANSIENT
import com.android.launcher3.util.DisplayController
+import kotlin.math.min
/** Helps draw the taskbar background, made up of a rectangle plus two inverted rounded corners. */
class TaskbarBackgroundRenderer(private val context: TaskbarActivityContext) {
@@ -153,9 +154,10 @@
// Draw the background behind taskbar content.
canvas.drawRect(0f, 0f, canvas.width.toFloat(), persistentTaskbarHeight, paint)
} else {
- canvas.translate(0f, canvas.height - maxPersistentTaskbarHeight)
+ val persistentTaskbarHeight = min(maxPersistentTaskbarHeight, backgroundHeight)
+ canvas.translate(0f, canvas.height - persistentTaskbarHeight)
// Draw the background behind taskbar content.
- canvas.drawRect(0f, 0f, canvas.width.toFloat(), maxPersistentTaskbarHeight, paint)
+ canvas.drawRect(0f, 0f, canvas.width.toFloat(), persistentTaskbarHeight, paint)
}
// Draw the inverted rounded corners above the taskbar.
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index d4f42d8..267b15c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -206,7 +206,9 @@
updateStateForFlag(FLAG_LAUNCHER_IN_STATE_TRANSITION, false);
// TODO(b/279514548) Cleans up bad state that can occur when user interacts with
// taskbar on top of transparent activity.
- if (finalState == LauncherState.NORMAL && mLauncher.hasBeenResumed()) {
+ if (!FeatureFlags.enableHomeTransitionListener()
+ && finalState == LauncherState.NORMAL
+ && mLauncher.hasBeenResumed()) {
updateStateForFlag(FLAG_VISIBLE, true);
}
applyState();
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index e1bb8ca..2943db1 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -34,6 +34,7 @@
import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
import static com.android.launcher3.config.FeatureFlags.ENABLE_HOME_TRANSITION_LISTENER;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
import static com.android.launcher3.popup.QuickstepSystemShortcut.getSplitSelectShortcutByPosition;
@@ -264,7 +265,7 @@
mAppTransitionManager.registerRemoteAnimations();
mAppTransitionManager.registerRemoteTransitions();
- if (ENABLE_HOME_TRANSITION_LISTENER.get()) {
+ if (FeatureFlags.enableHomeTransitionListener()) {
mHomeTransitionController = new HomeTransitionController(this);
mHomeTransitionController.registerHomeTransitionListener();
}
@@ -376,7 +377,7 @@
}
if ((changeBits & ACTIVITY_STATE_RESUMED) != 0) {
- if (!ENABLE_HOME_TRANSITION_LISTENER.get() && mTaskbarUIController != null) {
+ if (!FeatureFlags.enableHomeTransitionListener() && mTaskbarUIController != null) {
mTaskbarUIController.onLauncherVisibilityChanged(hasBeenResumed());
}
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index a18db5d..f5dc648 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -90,6 +90,7 @@
import android.widget.Toast;
import android.window.PictureInPictureSurfaceTransaction;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
@@ -313,7 +314,7 @@
private final Runnable mOnDeferredActivityLaunch = this::onDeferredActivityLaunch;
private final Runnable mLauncherOnStartCallback = this::onLauncherStart;
- private SwipePipToHomeAnimator mSwipePipToHomeAnimator;
+ @Nullable private SwipePipToHomeAnimator mSwipePipToHomeAnimator;
protected boolean mIsSwipingPipToHome;
// TODO(b/195473090) no split PIP for now, remove once we have more clarity
// can try to have RectFSpringAnim evaluate multiple rects at once
@@ -672,6 +673,9 @@
if (Arrays.stream(runningTasks).anyMatch(Objects::isNull)) {
return;
}
+ if (mRecentsView == null) {
+ return;
+ }
mRecentsView.onGestureAnimationStart(runningTasks, mDeviceState.getRotationTouchHelper());
}
@@ -1259,8 +1263,8 @@
return isSwipeUp ? ALL_APPS : LAST_TASK;
}
if (!isSwipeUp) {
- final boolean isCenteredOnNewTask =
- mRecentsView.getDestinationPage() != mRecentsView.getRunningTaskIndex();
+ final boolean isCenteredOnNewTask = mRecentsView != null
+ && mRecentsView.getDestinationPage() != mRecentsView.getRunningTaskIndex();
return willGoToNewTask || isCenteredOnNewTask ? NEW_TASK : LAST_TASK;
}
@@ -1536,11 +1540,13 @@
HomeAnimationFactory homeAnimFactory =
createHomeAnimationFactory(cookies, duration, isTranslucent, appCanEnterPip,
runningTaskTarget);
- mIsSwipingPipToHome = !mIsSwipeForSplit && appCanEnterPip;
+ SwipePipToHomeAnimator swipePipToHomeAnimator = !mIsSwipeForSplit && appCanEnterPip
+ ? createWindowAnimationToPip(homeAnimFactory, runningTaskTarget, start)
+ : null;
+ mIsSwipingPipToHome = swipePipToHomeAnimator != null;
final RectFSpringAnim[] windowAnim;
if (mIsSwipingPipToHome) {
- mSwipePipToHomeAnimator = createWindowAnimationToPip(
- homeAnimFactory, runningTaskTarget, start);
+ mSwipePipToHomeAnimator = swipePipToHomeAnimator;
mSwipePipToHomeAnimators[0] = mSwipePipToHomeAnimator;
if (mSwipePipToHomeReleaseCheck != null) {
mSwipePipToHomeReleaseCheck.setCanRelease(false);
@@ -1548,6 +1554,9 @@
// grab a screenshot before the PipContentOverlay gets parented on top of the task
UI_HELPER_EXECUTOR.execute(() -> {
+ if (mRecentsAnimationController == null) {
+ return;
+ }
// Directly use top task, split to pip handled on shell side
final int taskId = mGestureState.getTopRunningTaskId();
mTaskSnapshotCache.put(taskId,
@@ -1665,6 +1674,10 @@
@Nullable
private SwipePipToHomeAnimator createWindowAnimationToPip(HomeAnimationFactory homeAnimFactory,
RemoteAnimationTarget runningTaskTarget, float startProgress) {
+ if (mRecentsView == null) {
+ // Overview was destroyed, bail early.
+ return null;
+ }
// Directly animate the app to PiP (picture-in-picture) mode
final ActivityManager.RunningTaskInfo taskInfo = runningTaskTarget.taskInfo;
final RecentsOrientedState orientationState = mRemoteTargetHandles[0].getTaskViewSimulator()
@@ -1805,7 +1818,8 @@
private void continueComputingRecentsScrollIfNecessary() {
if (!mGestureState.hasState(STATE_RECENTS_SCROLLING_FINISHED)
&& !mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)
- && !mCanceled) {
+ && !mCanceled
+ && mRecentsView != null) {
computeRecentsScrollIfInvisible();
mRecentsView.postOnAnimation(this::continueComputingRecentsScrollIfNecessary);
}
@@ -2109,7 +2123,7 @@
* from Launcher to WM.
*/
private void maybeAbortSwipePipToHome() {
- if (mIsSwipingPipToHome && mSwipePipToHomeAnimators[0] != null) {
+ if (mIsSwipingPipToHome && mSwipePipToHomeAnimator != null) {
SystemUiProxy.INSTANCE.get(mContext).abortSwipePipToHome(
mSwipePipToHomeAnimator.getTaskId(),
mSwipePipToHomeAnimator.getComponentName());
@@ -2123,7 +2137,10 @@
* This should happen before {@link #finishRecentsControllerToHome(Runnable)}.
*/
private void maybeFinishSwipePipToHome() {
- if (mIsSwipingPipToHome && mSwipePipToHomeAnimators[0] != null) {
+ if (mRecentsAnimationController == null) {
+ return;
+ }
+ if (mIsSwipingPipToHome && mSwipePipToHomeAnimator != null) {
mRecentsAnimationController.setFinishTaskTransaction(
mSwipePipToHomeAnimator.getTaskId(),
mSwipePipToHomeAnimator.getFinishTransaction(),
@@ -2147,7 +2164,7 @@
protected abstract void finishRecentsControllerToHome(Runnable callback);
private void setupLauncherUiAfterSwipeUpToRecentsAnimation() {
- if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) {
+ if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED) || mRecentsView == null) {
return;
}
endLauncherTransitionController();
@@ -2181,6 +2198,9 @@
}
protected void linkRecentsViewScroll() {
+ if (mRecentsView == null) {
+ return;
+ }
SurfaceTransactionApplier applier = new SurfaceTransactionApplier(mRecentsView);
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams()
.setSyncTransactionApplier(applier));
@@ -2188,9 +2208,13 @@
mRecentsAnimationTargets.addReleaseCheck(applier));
mRecentsView.addOnScrollChangedListener(mOnRecentsScrollListener);
- runOnRecentsAnimationAndLauncherBound(() ->
- mRecentsView.setRecentsAnimationTargets(mRecentsAnimationController,
- mRecentsAnimationTargets));
+ runOnRecentsAnimationAndLauncherBound(() -> {
+ if (mRecentsView == null) {
+ return;
+ }
+ mRecentsView.setRecentsAnimationTargets(
+ mRecentsAnimationController, mRecentsAnimationTargets);
+ });
// Disable scrolling in RecentsView for trackpad 3-finger swipe up gesture.
if (!mGestureState.isThreeFingerTrackpadGesture()) {
@@ -2297,7 +2321,7 @@
}
@Override
- public void onTasksAppeared(RemoteAnimationTarget[] appearedTaskTargets) {
+ public void onTasksAppeared(@NonNull RemoteAnimationTarget[] appearedTaskTargets) {
if (mRecentsAnimationController != null) {
boolean hasStartedTaskBefore = Arrays.stream(appearedTaskTargets).anyMatch(
mGestureState.mLastStartedTaskIdPredicate);
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 468d96a..038a022 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -17,7 +17,6 @@
import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_HOME_TRANSITION_LISTENER;
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.SplitConfigurationOptions.StagePosition;
@@ -63,6 +62,7 @@
import com.android.internal.logging.InstanceId;
import com.android.internal.util.ScreenshotRequest;
import com.android.internal.view.AppearanceRegion;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.Preconditions;
import com.android.quickstep.util.ActiveGestureLog;
@@ -1048,7 +1048,7 @@
}
public void setHomeTransitionListener(IHomeTransitionListener listener) {
- if (!ENABLE_HOME_TRANSITION_LISTENER.get()) {
+ if (!FeatureFlags.enableHomeTransitionListener()) {
return;
}
diff --git a/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java b/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java
index bb028a7..df5765c 100644
--- a/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java
+++ b/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java
@@ -25,6 +25,8 @@
import android.view.View.OnAttachStateChangeListener;
import android.view.ViewRootImpl;
+import androidx.annotation.NonNull;
+
import com.android.quickstep.RemoteAnimationTargets.ReleaseCheck;
/**
@@ -48,7 +50,7 @@
/**
* @param targetView The view in the surface that acts as synchronization anchor.
*/
- public SurfaceTransactionApplier(View targetView) {
+ public SurfaceTransactionApplier(@NonNull View targetView) {
if (targetView.isAttachedToWindow()) {
initialize(targetView);
} else {
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 767aa15..5d8e53e 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -17,6 +17,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static com.android.launcher3.Flags.enableGridOnlyOverview;
import static com.android.launcher3.states.RotationHelper.deltaRotation;
import static com.android.launcher3.touch.PagedOrientationHandler.MATRIX_POST_TRANSLATE;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
@@ -108,6 +109,7 @@
private boolean mIsDesktopTask;
private int mTaskRectTranslationX;
private int mTaskRectTranslationY;
+ private int mPivotOffsetX;
public TaskViewSimulator(Context context, BaseActivityInterface sizeStrategy) {
mContext = context;
@@ -179,9 +181,10 @@
// Ensure the task rect is inside the full task rect
mTaskRect.offset(fullTaskSize.left, fullTaskSize.top);
} else {
- fullTaskSize = mTaskRect;
+ fullTaskSize = new Rect(mTaskRect);
+ mTaskRect.offset(mTaskRectTranslationX, mTaskRectTranslationY);
}
- fullTaskSize.offset(mTaskRectTranslationX, mTaskRectTranslationY);
+ fullTaskSize.offset(mTaskRectTranslationX + mPivotOffsetX, mTaskRectTranslationY);
return mOrientationState.getFullScreenScaleAndPivot(fullTaskSize, mDp, mPivot);
}
@@ -265,6 +268,11 @@
*/
public void addAppToOverviewAnim(PendingAnimation pa, TimeInterpolator interpolator) {
pa.addFloat(fullScreenProgress, AnimatedFloat.VALUE, 1, 0, interpolator);
+ if (enableGridOnlyOverview() && mDp.isTablet) {
+ int translationXToMiddle = mDp.widthPx / 2 - mTaskRect.centerX();
+ taskPrimaryTranslation.value = translationXToMiddle;
+ mPivotOffsetX = translationXToMiddle;
+ }
pa.addFloat(recentsViewScale, AnimatedFloat.VALUE, getFullScreenScale(), 1, interpolator);
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index b3d8da7..2555ffa 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -2101,11 +2101,15 @@
}
float accumulatedTranslationX = 0;
+ float translateXToMiddle = enableGridOnlyOverview() && mActivity.getDeviceProfile().isTablet
+ ? mActivity.getDeviceProfile().widthPx / 2 - mLastComputedGridTaskSize.centerX()
+ : 0;
for (int i = 0; i < taskCount; i++) {
TaskView taskView = requireTaskViewAt(i);
taskView.updateTaskSize();
taskView.getPrimaryNonGridTranslationProperty().set(taskView, accumulatedTranslationX);
taskView.getSecondaryNonGridTranslationProperty().set(taskView, 0f);
+ taskView.setNonGridPivotTranslationX(translateXToMiddle);
// Compensate space caused by TaskView scaling.
float widthDiff =
taskView.getLayoutParams().width * (1 - taskView.getNonGridScale());
@@ -4322,14 +4326,19 @@
Utilities.getPivotsForScalingRectToRect(mTempRect, selectedTaskPosition,
mTempPointF);
- setPivotX(mTempPointF.x);
- setPivotY(mTempPointF.y);
} else {
+ mTempRect.set(mLastComputedTaskSize);
+ // Only update pivot when it is tablet and not in grid yet, so the pivot is correct
+ // for non-current tasks when swiping up to overview
+ if (enableGridOnlyOverview() && mActivity.getDeviceProfile().isTablet
+ && !mOverviewGridEnabled) {
+ mTempRect.offset(mActivity.getDeviceProfile().widthPx / 2 - mTempRect.centerX(), 0);
+ }
getPagedViewOrientedState().getFullScreenScaleAndPivot(mTempRect,
mActivity.getDeviceProfile(), mTempPointF);
- setPivotX(mTempPointF.x);
- setPivotY(mTempPointF.y);
}
+ setPivotX(mTempPointF.x);
+ setPivotY(mTempPointF.y);
}
private void updatePageOffsets() {
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index fec17b4..b063c91 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -384,6 +384,7 @@
// switch.
private float mNonGridTranslationX;
private float mNonGridTranslationY;
+ private float mNonGridPivotTranslationX;
// Used when in SplitScreenSelectState
private float mSplitSelectTranslationY;
private float mSplitSelectTranslationX;
@@ -1284,8 +1285,8 @@
}
protected void resetPersistentViewTransforms() {
- mNonGridTranslationX = mNonGridTranslationY =
- mGridTranslationX = mGridTranslationY = mBoxTranslationY = 0f;
+ mNonGridTranslationX = mNonGridTranslationY = mGridTranslationX =
+ mGridTranslationY = mBoxTranslationY = mNonGridPivotTranslationX = 0f;
resetViewTransforms();
}
@@ -1487,6 +1488,14 @@
applyTranslationX();
}
+ /**
+ * Set translation X for non-grid pivot
+ */
+ public void setNonGridPivotTranslationX(float nonGridPivotTranslationX) {
+ mNonGridPivotTranslationX = nonGridPivotTranslationX;
+ applyTranslationX();
+ }
+
public float getScrollAdjustment(boolean gridEnabled) {
float scrollAdjustment = 0;
if (gridEnabled) {
@@ -1529,7 +1538,8 @@
* change according to a temporary state (e.g. task offset).
*/
public float getPersistentTranslationX() {
- return getNonGridTrans(mNonGridTranslationX) + getGridTrans(mGridTranslationX);
+ return getNonGridTrans(mNonGridTranslationX) + getGridTrans(mGridTranslationX)
+ + getNonGridTrans(mNonGridPivotTranslationX);
}
/**
diff --git a/src/com/android/launcher3/LauncherPrefs.kt b/src/com/android/launcher3/LauncherPrefs.kt
index c6a9283..4f8caab 100644
--- a/src/com/android/launcher3/LauncherPrefs.kt
+++ b/src/com/android/launcher3/LauncherPrefs.kt
@@ -20,11 +20,12 @@
import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.util.Log
-import android.view.ViewConfiguration
import androidx.annotation.VisibleForTesting
import com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN
import com.android.launcher3.LauncherFiles.DEVICE_PREFERENCES_KEY
import com.android.launcher3.LauncherFiles.SHARED_PREFERENCES_KEY
+import com.android.launcher3.config.FeatureFlags.LPNH_SLOP_PERCENTAGE
+import com.android.launcher3.config.FeatureFlags.LPNH_TIMEOUT_MS
import com.android.launcher3.model.DeviceGridState
import com.android.launcher3.pm.InstallSessionHelper
import com.android.launcher3.provider.RestoreDbTask
@@ -310,16 +311,16 @@
)
@JvmField
val LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE =
- nonRestorableItem(
- "pref_long_press_nav_handle_slop_multiplier",
- 100,
+ nonRestorableItem(
+ "pref_long_press_nav_handle_slop_percentage",
+ LPNH_SLOP_PERCENTAGE.get(),
EncryptionType.MOVE_TO_DEVICE_PROTECTED
- )
+ )
@JvmField
val LONG_PRESS_NAV_HANDLE_TIMEOUT_MS =
nonRestorableItem(
"pref_long_press_nav_handle_timeout_ms",
- ViewConfiguration.getLongPressTimeout(),
+ LPNH_TIMEOUT_MS.get(),
EncryptionType.MOVE_TO_DEVICE_PROTECTED
)
@JvmField
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 4d8166c..4e7ec0b 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -21,8 +21,11 @@
import static com.android.launcher3.config.FeatureFlags.FlagState.ENABLED;
import static com.android.launcher3.config.FeatureFlags.FlagState.TEAMFOOD;
import static com.android.launcher3.uioverrides.flags.FlagsFactory.getDebugFlag;
+import static com.android.launcher3.uioverrides.flags.FlagsFactory.getIntFlag;
import static com.android.launcher3.uioverrides.flags.FlagsFactory.getReleaseFlag;
+import android.view.ViewConfiguration;
+
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.BuildConfig;
@@ -113,9 +116,17 @@
"Allow entering All Apps from Overview (e.g. long swipe up from app)");
public static final BooleanFlag CUSTOM_LPNH_THRESHOLDS =
- getDebugFlag(301680992, "CUSTOM_LPNH_THRESHOLDS", DISABLED,
+ getReleaseFlag(301680992, "CUSTOM_LPNH_THRESHOLDS", DISABLED,
"Add dev options to customize the LPNH trigger slop and milliseconds");
+ public static final IntFlag LPNH_SLOP_PERCENTAGE =
+ getIntFlag(301680992, "LPNH_SLOP_PERCENTAGE", 100,
+ "Controls touch slop percentage for lpnh");
+
+ public static final IntFlag LPNH_TIMEOUT_MS =
+ getIntFlag(301680992, "LPNH_TIMEOUT_MS", ViewConfiguration.getLongPressTimeout(),
+ "Controls lpnh timeout in milliseconds");
+
public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = getReleaseFlag(
270394468, "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", ENABLED,
"Enable option to show keyboard when going to all-apps");
@@ -305,10 +316,15 @@
"ENABLE_DYNAMIC_TASKBAR_THRESHOLDS", ENABLED,
"Enables taskbar thresholds that scale based on screen size.");
+ // Aconfig migration complete for ENABLE_HOME_TRANSITION_LISTENER.
public static final BooleanFlag ENABLE_HOME_TRANSITION_LISTENER = getDebugFlag(306053414,
- "ENABLE_HOME_TRANSITION_LISTENER", DISABLED,
+ "ENABLE_HOME_TRANSITION_LISTENER", TEAMFOOD,
"Enables launcher to listen to all transitions that include home activity.");
+ public static boolean enableHomeTransitionListener() {
+ return ENABLE_HOME_TRANSITION_LISTENER.get() || Flags.enableHomeTransitionListener();
+ }
+
// TODO(Block 21): Clean up flags
public static final BooleanFlag ENABLE_APP_ICON_FOR_INLINE_SHORTCUTS = getDebugFlag(270395087,
"ENABLE_APP_ICON_IN_INLINE_SHORTCUTS", DISABLED, "Show app icon for inline shortcut");
diff --git a/src/com/android/launcher3/model/DatabaseHelper.java b/src/com/android/launcher3/model/DatabaseHelper.java
index 8167b97..1360510 100644
--- a/src/com/android/launcher3/model/DatabaseHelper.java
+++ b/src/com/android/launcher3/model/DatabaseHelper.java
@@ -269,7 +269,6 @@
Favorites.CONTAINER, Favorites.CONTAINER_DESKTOP,
Favorites.CELLY, 0), null);
}
- return;
}
case 31: {
LauncherDbUtils.migrateLegacyShortcuts(mContext, db);
diff --git a/tests/src/com/android/launcher3/DeleteDropTargetTest.kt b/tests/src/com/android/launcher3/DeleteDropTargetTest.kt
index bcfb90b..46e66e4 100644
--- a/tests/src/com/android/launcher3/DeleteDropTargetTest.kt
+++ b/tests/src/com/android/launcher3/DeleteDropTargetTest.kt
@@ -32,9 +32,9 @@
buttonDropTarget.setTextMultiLine(false)
// No space for text
- assertThat(buttonDropTarget.isTextClippedVertically(30)).isTrue()
+ assertThat(buttonDropTarget.isTextClippedVertically(1)).isTrue()
// A lot of space for text so the text should not be clipped
- assertThat(buttonDropTarget.isTextClippedVertically(100)).isFalse()
+ assertThat(buttonDropTarget.isTextClippedVertically(1000)).isFalse()
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
index aa5c770..a85b6bd 100644
--- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
+++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
@@ -366,8 +366,10 @@
}
int focusedTaskHeight = mLauncher.getFocusedTaskHeightForTablet();
for (UiObject2 task : taskViews) {
- if (task.getVisibleBounds().height() == focusedTaskHeight) {
- return new OverviewTask(mLauncher, task, this);
+ OverviewTask overviewTask = new OverviewTask(mLauncher, task, this);
+
+ if (overviewTask.getVisibleHeight() == focusedTaskHeight) {
+ return overviewTask;
}
}
return null;
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
index 95a4802..06fac48 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -36,6 +36,8 @@
*/
public final class OverviewTask {
private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
+ private static final String TASK_SNAPSHOT_1 = "snapshot";
+ private static final String TASK_SNAPSHOT_2 = "bottomright_snapshot";
static final Pattern TASK_START_EVENT = Pattern.compile("startActivityFromRecentsAsync");
static final Pattern SPLIT_SELECT_EVENT = Pattern.compile("enterSplitSelect");
@@ -55,14 +57,64 @@
mOverview.verifyActiveContainer();
}
+ /**
+ * Returns the height of the visible task, or the combined height of two tasks in split with a
+ * divider between.
+ */
int getVisibleHeight() {
+ if (isTaskSplit()) {
+ return getCombinedSplitTaskHeight();
+ }
+
return mTask.getVisibleBounds().height();
}
+ /**
+ * Calculates the visible height for split tasks, containing 2 snapshot tiles and a divider.
+ */
+ private int getCombinedSplitTaskHeight() {
+ UiObject2 taskSnapshot1 =
+ mLauncher.findObjectInContainer(mTask.getParent(), TASK_SNAPSHOT_1);
+ UiObject2 taskSnapshot2 =
+ mLauncher.findObjectInContainer(mTask.getParent(), TASK_SNAPSHOT_2);
+
+ int top = Math.min(
+ taskSnapshot1.getVisibleBounds().top, taskSnapshot2.getVisibleBounds().top);
+ int bottom = Math.max(
+ taskSnapshot1.getVisibleBounds().bottom, taskSnapshot2.getVisibleBounds().bottom);
+
+ return bottom - top;
+ }
+
+ /**
+ * Returns the width of the visible task, or the combined width of two tasks in split with a
+ * divider between.
+ */
int getVisibleWidth() {
+ if (isTaskSplit()) {
+ return getCombinedSplitTaskWidth();
+ }
+
return mTask.getVisibleBounds().width();
}
+ /**
+ * Calculates the visible width for split tasks, containing 2 snapshot tiles and a divider.
+ */
+ private int getCombinedSplitTaskWidth() {
+ UiObject2 taskSnapshot1 =
+ mLauncher.findObjectInContainer(mTask.getParent(), TASK_SNAPSHOT_1);
+ UiObject2 taskSnapshot2 =
+ mLauncher.findObjectInContainer(mTask.getParent(), TASK_SNAPSHOT_2);
+
+ int left = Math.min(
+ taskSnapshot1.getVisibleBounds().left, taskSnapshot2.getVisibleBounds().left);
+ int right = Math.max(
+ taskSnapshot1.getVisibleBounds().right, taskSnapshot2.getVisibleBounds().right);
+
+ return right - left;
+ }
+
int getTaskCenterX() {
return mTask.getVisibleCenter().x;
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Qsb.java b/tests/tapl/com/android/launcher3/tapl/Qsb.java
index 5ca80a3..fe2a63d 100644
--- a/tests/tapl/com/android/launcher3/tapl/Qsb.java
+++ b/tests/tapl/com/android/launcher3/tapl/Qsb.java
@@ -22,6 +22,8 @@
import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.Until;
+import java.util.regex.Pattern;
+
/**
* Operations on qsb from either Home screen or AllApp screen.
*/
@@ -30,7 +32,8 @@
private static final String ASSISTANT_APP_PACKAGE = "com.google.android.googlequicksearchbox";
private static final String ASSISTANT_ICON_RES_ID = "mic_icon";
private static final String LENS_ICON_RES_ID = "lens_icon";
- private static final String LENS_APP_TEXT_RES_ID = "lens_camera_cutout_text";
+ private static final Pattern LENS_APP_RES_PATTERN = Pattern.compile(
+ ASSISTANT_APP_PACKAGE + ":id/lens.*");
protected final LauncherInstrumentation mLauncher;
private final UiObject2 mContainer;
private final String mQsbResName;
@@ -96,8 +99,8 @@
try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
// Package name is not enough to check if the app is launched, because many
// elements are having googlequicksearchbox as package name. So it checks if the
- // corresponding text resource is displayed
- BySelector selector = By.res(ASSISTANT_APP_PACKAGE, LENS_APP_TEXT_RES_ID);
+ // corresponding app resource is displayed
+ BySelector selector = By.res(LENS_APP_RES_PATTERN);
mLauncher.assertTrue(
"Lens app didn't start: (" + selector + ")",
mLauncher.getDevice().wait(Until.hasObject(selector),