diff --git a/aconfig/launcher_overview.aconfig b/aconfig/launcher_overview.aconfig index 853faf8167..c59978f002 100644 --- a/aconfig/launcher_overview.aconfig +++ b/aconfig/launcher_overview.aconfig @@ -36,7 +36,7 @@ flag { name: "enable_large_desktop_windowing_tile" namespace: "launcher_overview" description: "Makes the desktop tiles larger and moves them to the front of the list in Overview." - bug: "353947137" + bug: "357860832" } flag { diff --git a/go/quickstep/src/com/android/launcher3/AppSharing.java b/go/quickstep/src/com/android/launcher3/AppSharing.java index e15b132f94..a97feccfe1 100644 --- a/go/quickstep/src/com/android/launcher3/AppSharing.java +++ b/go/quickstep/src/com/android/launcher3/AppSharing.java @@ -37,12 +37,13 @@ import android.widget.Toast; import androidx.core.content.FileProvider; +import com.android.internal.annotations.VisibleForTesting; +import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.model.AppShareabilityChecker; import com.android.launcher3.model.AppShareabilityJobService; import com.android.launcher3.model.AppShareabilityManager; import com.android.launcher3.model.AppShareabilityManager.ShareabilityStatus; import com.android.launcher3.model.data.ItemInfo; -import com.android.launcher3.popup.PopupDataProvider; import com.android.launcher3.popup.SystemShortcut; import com.android.launcher3.views.ActivityContext; @@ -114,17 +115,17 @@ public final class AppSharing { * The Share App system shortcut, used to initiate p2p sharing of a given app */ public final class Share extends SystemShortcut { - private final PopupDataProvider mPopupDataProvider; private final boolean mSharingEnabledForUser; private final Set mBoundViews = Collections.newSetFromMap(new WeakHashMap<>()); private boolean mIsEnabled = true; + private StatsLogManager mStatsLogManager; public Share(Launcher target, ItemInfo itemInfo, View originalView) { super(R.drawable.ic_share, R.string.app_share_drop_target_label, target, itemInfo, originalView); - mPopupDataProvider = target.getPopupDataProvider(); - + mStatsLogManager = ActivityContext.lookupContext(originalView.getContext()) + .getStatsLogManager(); mSharingEnabledForUser = bluetoothSharingEnabled(target); if (!mSharingEnabledForUser) { setEnabled(false); @@ -150,8 +151,7 @@ public final class AppSharing { @Override public void onClick(View view) { - ActivityContext.lookupContext(view.getContext()) - .getStatsLogManager().logger().log(LAUNCHER_SYSTEM_SHORTCUT_APP_SHARE_TAP); + mStatsLogManager.logger().log(LAUNCHER_SYSTEM_SHORTCUT_APP_SHARE_TAP); if (!mIsEnabled) { showCannotShareToast(view.getContext()); return; @@ -240,6 +240,11 @@ public final class AppSharing { public boolean isEnabled() { return mIsEnabled; } + + @VisibleForTesting + void setStatsLogManager(StatsLogManager statsLogManager) { + mStatsLogManager = statsLogManager; + } } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index 895535e5c7..d1725bc59b 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -406,6 +406,12 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT } }; mSeparateWindowParent.recreateControllers(); + if (BubbleBarController.isBubbleBarEnabled()) { + mNavButtonsView.addOnLayoutChangeListener( + (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> + onLayoutsUpdated() + ); + } } private void initButtons(ViewGroup navContainer, ViewGroup endContainer, @@ -1180,15 +1186,20 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT /** Adjusts navigation buttons layout accordingly to the bubble bar position. */ @Override public void onBubbleBarLocationUpdated(BubbleBarLocation location) { - cancelExistingNavBarAnimation(); - mBubbleBarTargetLocation = location; + boolean locationUpdated = location != mBubbleBarTargetLocation; + if (locationUpdated) { + cancelExistingNavBarAnimation(); + } else { + endExistingAnimation(); + } mNavButtonContainer.setTranslationX(getNavBarTranslationX(location)); - mNavButtonContainer.setAlpha(1); + mBubbleBarTargetLocation = location; } /** Animates navigation buttons accordingly to the bubble bar position. */ @Override public void onBubbleBarLocationAnimated(BubbleBarLocation location) { + if (location == mBubbleBarTargetLocation) return; cancelExistingNavBarAnimation(); mBubbleBarTargetLocation = location; int finalX = getNavBarTranslationX(location); @@ -1199,6 +1210,13 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT mNavBarLocationAnimator.start(); } + private void endExistingAnimation() { + if (mNavBarLocationAnimator != null) { + mNavBarLocationAnimator.end(); + mNavBarLocationAnimator = null; + } + } + private void cancelExistingNavBarAnimation() { if (mNavBarLocationAnimator != null) { mNavBarLocationAnimator.cancel(); @@ -1240,12 +1258,18 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT } /** Adjusts the navigation buttons layout position according to the bubble bar location. */ - public void onTaskbarLayoutChanged() { - if (mControllers.taskbarViewController.getIconLayoutBounds().isEmpty()) return; + public void onLayoutsUpdated() { + // no need to do anything if on phone, or if taskbar or navbar views were not placed on + // screen. + if (mContext.getDeviceProfile().isPhone + || mControllers.taskbarViewController.getIconLayoutBounds().isEmpty() + || mNavButtonsView.getWidth() == 0) { + return; + } if (enableBubbleBarInPersistentTaskBar() && mControllers.bubbleControllers.isPresent()) { if (mBubbleBarTargetLocation == null) { - // only set bubble bar location if it was not set before, e.g. at device boot + // only set bubble bar location if it was not set before mBubbleBarTargetLocation = mControllers.bubbleControllers.get() .bubbleBarViewController.getBubbleBarLocation(); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index a59445b9f6..46d063b0f3 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -278,7 +278,10 @@ public class TaskbarActivityContext extends BaseTaskbarContext { // If Bubble bar is present, TaskbarControllers depends on it so build it first. Optional bubbleControllersOptional = Optional.empty(); BubbleBarController.onTaskbarRecreated(); - if (BubbleBarController.isBubbleBarEnabled() && bubbleBarView != null) { + if (BubbleBarController.isBubbleBarEnabled() + && !mDeviceProfile.isPhone + && bubbleBarView != null + ) { Optional bubbleHandleController = Optional.empty(); Optional bubbleBarSwipeController = Optional.empty(); if (isTransientTaskbar) { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java index 59746751a5..219a24a702 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java @@ -220,11 +220,12 @@ public class TaskbarControllers { uiController = newUiController; uiController.init(this); uiController.updateStateForSysuiFlags(mSharedState.sysuiStateFlags); - bubbleControllers.ifPresent(bubbleControllers -> { + // if bubble controllers are present take bubble bar location, else set it to null + bubbleControllers.ifPresentOrElse(bubbleControllers -> { BubbleBarLocation location = bubbleControllers.bubbleBarViewController.getBubbleBarLocation(); uiController.onBubbleBarLocationUpdated(location); - }); + }, () -> uiController.onBubbleBarLocationUpdated(null)); // Notify that the ui controller has changed navbarButtonsViewController.onUiControllerChanged(); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index 8f722f42dd..8a1d71ac4b 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -866,43 +866,49 @@ public class TaskbarLauncherStateController { } /** Updates launcher home screen appearance accordingly to the bubble bar location. */ - public void onBubbleBarLocationChanged(BubbleBarLocation location, boolean animate) { - DeviceProfile deviceProfile = mLauncher.getDeviceProfile(); - if (mBubbleBarLocation == location) return; + public void onBubbleBarLocationChanged(@Nullable BubbleBarLocation location, boolean animate) { mBubbleBarLocation = location; + if (location == null) { + // bubble bar is not present, hence no location, resetting the hotseat + updateHotseatAndQsbTranslationX(0, animate); + mBubbleBarLocation = null; + return; + } + DeviceProfile deviceProfile = mLauncher.getDeviceProfile(); if (!deviceProfile.shouldAdjustHotseatOnBubblesLocationUpdate( mControllers.taskbarActivityContext)) { return; } - int targetX = 0; - if (mBubbleBarLocation != null) { - boolean isBubblesOnLeft = location.isOnLeft(isRtl(mLauncher.getResources())); - targetX = deviceProfile.getHotseatTranslationXForBubbleBar(/* isNavbarOnRight= */ - isBubblesOnLeft); - } + boolean isBubblesOnLeft = location.isOnLeft(isRtl(mLauncher.getResources())); + int targetX = deviceProfile + .getHotseatTranslationXForBubbleBar(/* isNavbarOnRight= */ isBubblesOnLeft); updateHotseatAndQsbTranslationX(targetX, animate); } + /** Used to translate hotseat and QSB to make room for bubbles. */ private void updateHotseatAndQsbTranslationX(float targetValue, boolean animate) { // cancel existing animation if (mHotseatTranslationXAnimation != null) { mHotseatTranslationXAnimation.cancel(); + mHotseatTranslationXAnimation = null; } - Runnable alignTaskbar = new Runnable() { + Runnable postAnimationAction = new Runnable() { @Override public void run() { + mHotseatTranslationXAnimation = null; // We only need to align the task bar when on launcher home screen if (mControllers.taskbarStashController.isOnHome()) { - DeviceProfile dp = mLauncher.getDeviceProfile(); - mControllers.taskbarViewController - .setLauncherIconAlignment(/* alignmentRatio = */ 1, dp); + mControllers.taskbarViewController.setLauncherIconAlignment( + /* alignmentRatio = */ 1, + mLauncher.getDeviceProfile() + ); } } }; Hotseat hotseat = mLauncher.getHotseat(); AnimatorSet translationXAnimation = new AnimatorSet(); - MultiProperty iconsTranslationX = hotseat.getIconsTranslationX( - Hotseat.ICONS_TRANSLATION_X_NAV_BAR_ALIGNMENT); + MultiProperty iconsTranslationX = mLauncher.getHotseat() + .getIconsTranslationX(Hotseat.ICONS_TRANSLATION_X_NAV_BAR_ALIGNMENT); if (animate) { translationXAnimation.playTogether(iconsTranslationX.animateToValue(targetValue)); } else { @@ -921,18 +927,17 @@ public class TaskbarLauncherStateController { } } if (!animate) { - alignTaskbar.run(); + postAnimationAction.run(); return; } mHotseatTranslationXAnimation = translationXAnimation; translationXAnimation.setStartDelay(FADE_OUT_ANIM_POSITION_DURATION_MS); translationXAnimation.setDuration(FADE_IN_ANIM_ALPHA_DURATION_MS); translationXAnimation.setInterpolator(Interpolators.EMPHASIZED); - translationXAnimation.addListener(AnimatorListeners.forEndCallback(alignTaskbar)); + translationXAnimation.addListener(AnimatorListeners.forEndCallback(postAnimationAction)); translationXAnimation.start(); } - private final class TaskBarRecentsAnimationListener implements RecentsAnimationCallbacks.RecentsAnimationListener { private final RecentsAnimationCallbacks mCallbacks; diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index e5220359d1..21d0cda43b 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -159,7 +159,9 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar private final View.OnLayoutChangeListener mTaskbarViewLayoutChangeListener = (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { updateTaskbarIconTranslationXForPinning(); - mControllers.navbarButtonsViewController.onTaskbarLayoutChanged(); + if (BubbleBarController.isBubbleBarEnabled()) { + mControllers.navbarButtonsViewController.onLayoutsUpdated(); + } }; // Animation to align icons with Launcher, created lazily. This allows the controller to be diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt index a33e5c0fd2..461f963dc1 100644 --- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt +++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt @@ -27,6 +27,7 @@ import androidx.annotation.BinderThread import androidx.annotation.UiThread import androidx.annotation.VisibleForTesting import com.android.internal.jank.Cuj +import com.android.launcher3.Flags.enableLargeDesktopWindowingTile import com.android.launcher3.Flags.enableOverviewCommandHelperTimeout import com.android.launcher3.PagedView import com.android.launcher3.logger.LauncherAtom @@ -215,13 +216,12 @@ constructor( } } TOGGLE -> { - val taskView = - if (recentsView.runningTaskView == null) { - recentsView.getTaskViewAt(0) - } else { - recentsView.nextTaskView ?: recentsView.runningTaskView - } - launchTask(recentsView, taskView, command, onCallbackResult) + launchTask( + recentsView, + getNextToggledTaskView(recentsView), + command, + onCallbackResult, + ) } HOME -> { recentsView.startHome() @@ -229,6 +229,27 @@ constructor( } } + private fun getNextToggledTaskView(recentsView: RecentsView<*, *>): TaskView? { + // When running task view is null we return last large taskView - typically focusView when + // grid only is not enabled else last desktop task view. + return if (recentsView.runningTaskView == null) { + recentsView.lastLargeTaskView ?: recentsView.getTaskViewAt(0) + } else { + if ( + enableLargeDesktopWindowingTile() && + recentsView.getTaskViewCount() == recentsView.largeTilesCount && + recentsView.runningTaskView === recentsView.lastLargeTaskView + ) { + // Enables the toggle when only large tiles are in recents view. + // We return previous because unlike small tiles, large tiles are always + // on the right hand side. + recentsView.previousTaskView ?: recentsView.runningTaskView + } else { + recentsView.nextTaskView ?: recentsView.runningTaskView + } + } + } + private fun launchTask( recents: RecentsView<*, *>, taskView: TaskView?, diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java index 8f579e2371..511c989928 100644 --- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java @@ -77,6 +77,7 @@ import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.statehandlers.DepthController; import com.android.launcher3.statemanager.StateManager; +import com.android.launcher3.taskbar.LauncherTaskbarUIController; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.shared.TestProtocol; import com.android.launcher3.uioverrides.QuickstepLauncher; @@ -943,7 +944,16 @@ public class SplitSelectStateController { anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { - controller.finish(true /* toRecents */, null /* onFinishComplete */, + controller.finish( + true /* toRecents */, + () -> { + LauncherTaskbarUIController controller = + mLauncher.getTaskbarUIController(); + if (controller != null) { + controller.updateTaskbarLauncherStateGoingHome(); + } + + }, false /* sendUserLeaveHint */); } @Override @@ -951,7 +961,16 @@ public class SplitSelectStateController { SystemUiProxy.INSTANCE.get(mLauncher.getApplicationContext()) .onDesktopSplitSelectAnimComplete(mTaskInfo); } + @Override + public void onAnimationCancel(Animator animation) { + mLauncher.getDragLayer().removeView(floatingTaskView); + getSplitAnimationController() + .removeSplitInstructionsView(mLauncher); + resetState(); + } }); + anim.add(getSplitAnimationController() + .getShowSplitInstructionsAnim(mLauncher).buildAnim()); anim.buildAnim().start(); } } diff --git a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java index bdca596a92..b719ee5b73 100644 --- a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java +++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java @@ -18,6 +18,7 @@ package com.android.quickstep.views; import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.annotation.TargetApi; +import android.app.TaskInfo; import android.content.Context; import android.graphics.Matrix; import android.graphics.RectF; @@ -333,11 +334,16 @@ public class FloatingWidgetView extends FrameLayout implements AnimatorListener, * context's theme background color. */ public static int getDefaultBackgroundColor( - Context context, RemoteAnimationTarget target) { - return (target != null && target.taskInfo != null - && target.taskInfo.taskDescription != null) - ? target.taskInfo.taskDescription.getBackgroundColor() - : Themes.getColorBackground(context); + Context context, @Nullable RemoteAnimationTarget target) { + final int fallbackColor = Themes.getColorBackground(context); + if (target == null) { + return fallbackColor; + } + final TaskInfo taskInfo = target.taskInfo; + if (taskInfo == null) { + return fallbackColor; + } + return taskInfo.taskDescription.getBackgroundColor(); } private static void getRelativePosition(View descendant, View ancestor, RectF position) { diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 82f08e58e5..c405080828 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -3141,7 +3141,9 @@ public abstract class RecentsView< // Horizontal grid translation for each task float[] gridTranslations = new float[taskCount]; - int lastLargeTaskIndex = Integer.MAX_VALUE; + TaskView lastLargeTaskView = mUtils.getLastLargeTaskView(getTaskViews()); + int lastLargeTaskIndex = + (lastLargeTaskView == null) ? Integer.MAX_VALUE : indexOfChild(lastLargeTaskView); Set largeTasksIndices = new HashSet<>(); int focusedTaskShift = 0; int largeTaskWidthAndSpacing = 0; @@ -3177,7 +3179,6 @@ public abstract class RecentsView< taskView.setGridTranslationY((mLastComputedTaskSize.height() + taskTopMargin - taskView.getLayoutParams().height) / 2f); - lastLargeTaskIndex = i; largeTasksIndices.add(i); largeTaskWidthAndSpacing = taskWidthAndSpacing; @@ -4571,6 +4572,20 @@ public abstract class RecentsView< return getTaskViewAt(getRunningTaskIndex() + 1); } + @Nullable + public TaskView getPreviousTaskView() { + return getTaskViewAt(getRunningTaskIndex() - 1); + } + + @Nullable + public TaskView getLastLargeTaskView() { + return mUtils.getLastLargeTaskView(getTaskViews()); + } + + public int getLargeTilesCount() { + return mUtils.getLargeTileCount(getTaskViews()); + } + @Nullable public TaskView getCurrentPageTaskView() { return getTaskViewAt(getCurrentPage()); @@ -5404,6 +5419,7 @@ public abstract class RecentsView< int taskIndex = indexOfChild(taskView); int centerTaskIndex = getCurrentPage(); + boolean isRunningTask = taskView.isRunningTask(); float toScale = getMaxScaleForFullScreen(); boolean showAsGrid = showAsGrid(); @@ -5422,13 +5438,16 @@ public abstract class RecentsView< mTempPointF); setPivotX(mTempPointF.x); setPivotY(mTempPointF.y); - runActionOnRemoteHandles( - remoteTargetHandle -> { - remoteTargetHandle.getTaskViewSimulator().setPivotOverride( - mTempPointF); - remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents( - false); - }); + + if (!isRunningTask) { + runActionOnRemoteHandles( + remoteTargetHandle -> { + remoteTargetHandle.getTaskViewSimulator().setPivotOverride( + mTempPointF); + remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents( + false); + }); + } } }); } else if (!showAsGrid) { diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java index 87a7cdae14..3483723097 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java @@ -20,7 +20,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -38,14 +37,13 @@ import android.view.SurfaceControl; import android.view.ViewTreeObserver; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.test.platform.app.InstrumentationRegistry; import com.android.launcher3.DeviceProfile; -import com.android.launcher3.Flags; import com.android.launcher3.LauncherRootView; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.statemanager.BaseState; -import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.statemanager.StatefulContainer; import com.android.launcher3.util.SystemUiController; import com.android.quickstep.fallback.window.RecentsWindowManager; @@ -65,11 +63,11 @@ import java.util.Collections; import java.util.HashMap; public abstract class AbsSwipeUpHandlerTestCase< - RECENTS_CONTAINER extends Context & RecentsViewContainer & StatefulContainer, - STATE extends BaseState, RECENTS_VIEW extends RecentsView, - ACTIVITY_TYPE extends StatefulActivity & RecentsViewContainer, - ACTIVITY_INTERFACE extends BaseActivityInterface, - SWIPE_HANDLER extends AbsSwipeUpHandler> { + STATE_TYPE extends BaseState, + RECENTS_CONTAINER extends Context & RecentsViewContainer & StatefulContainer, + RECENTS_VIEW extends RecentsView, + SWIPE_HANDLER extends AbsSwipeUpHandler, + CONTAINER_INTERFACE extends BaseContainerInterface> { protected final Context mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); @@ -106,13 +104,12 @@ public abstract class AbsSwipeUpHandlerTestCase< /* minimizedHomeBounds= */ null, new Bundle()); - protected RecentsWindowManager mRecentsWindowManager; protected TaskAnimationManager mTaskAnimationManager; - @Mock protected ACTIVITY_INTERFACE mActivityInterface; + @Mock protected CONTAINER_INTERFACE mActivityInterface; @Mock protected ActivityInitListener mActivityInitListener; @Mock protected RecentsAnimationController mRecentsAnimationController; - @Mock protected STATE mState; + @Mock protected STATE_TYPE mState; @Mock protected ViewTreeObserver mViewTreeObserver; @Mock protected DragLayer mDragLayer; @Mock protected LauncherRootView mRootView; @@ -122,16 +119,6 @@ public abstract class AbsSwipeUpHandlerTestCase< @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); - @Before - public void setUpTaskAnimationManager() { - runOnMainSync(() -> { - if(Flags.enableFallbackOverviewInWindow()){ - mRecentsWindowManager = new RecentsWindowManager(mContext); - } - mTaskAnimationManager = new TaskAnimationManager(mContext, mRecentsWindowManager); - }); - } - @Before public void setUpRunningTaskInfo() { mRunningTaskInfo.baseIntent = new Intent(Intent.ACTION_MAIN) @@ -162,6 +149,7 @@ public abstract class AbsSwipeUpHandlerTestCase< @Before public void setUpRecentsContainer() { + mTaskAnimationManager = new TaskAnimationManager(mContext, getRecentsWindowManager()); RecentsViewContainer recentsContainer = getRecentsContainer(); RECENTS_VIEW recentsView = getRecentsView(); @@ -263,13 +251,12 @@ public abstract class AbsSwipeUpHandlerTestCase< private void onRecentsAnimationStart(SWIPE_HANDLER absSwipeUpHandler) { when(mActivityInterface.getOverviewWindowBounds(any(), any())).thenReturn(new Rect()); - doNothing().when(mActivityInterface).setOnDeferredActivityLaunchCallback(any()); runOnMainSync(() -> absSwipeUpHandler.onRecentsAnimationStart( mRecentsAnimationController, mRecentsAnimationTargets)); } - private static void runOnMainSync(Runnable runnable) { + protected static void runOnMainSync(Runnable runnable) { InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable); } @@ -278,6 +265,11 @@ public abstract class AbsSwipeUpHandlerTestCase< return createSwipeHandler(SystemClock.uptimeMillis(), false); } + @Nullable + protected RecentsWindowManager getRecentsWindowManager() { + return null; + } + @NonNull protected abstract SWIPE_HANDLER createSwipeHandler( long touchTimeMs, boolean continuingLastGesture); diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/FallbackSwipeHandlerTestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/FallbackSwipeHandlerTestCase.java index 8d6906fca4..88197e5473 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/FallbackSwipeHandlerTestCase.java +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/FallbackSwipeHandlerTestCase.java @@ -16,6 +16,7 @@ package com.android.quickstep; +import androidx.annotation.NonNull; import androidx.test.filters.SmallTest; import com.android.launcher3.util.LauncherMultivalentJUnit; @@ -28,15 +29,14 @@ import org.mockito.Mock; @SmallTest @RunWith(LauncherMultivalentJUnit.class) public class FallbackSwipeHandlerTestCase extends AbsSwipeUpHandlerTestCase< - RecentsActivity, RecentsState, - FallbackRecentsView, RecentsActivity, - FallbackActivityInterface, - FallbackSwipeHandler> { + FallbackRecentsView, + FallbackSwipeHandler, + FallbackActivityInterface> { @Mock private RecentsActivity mRecentsActivity; - @Mock private FallbackRecentsView mRecentsView; + @Mock private FallbackRecentsView mRecentsView; @Override @@ -52,13 +52,15 @@ public class FallbackSwipeHandlerTestCase extends AbsSwipeUpHandlerTestCase< mInputConsumerController); } + @NonNull @Override protected RecentsActivity getRecentsContainer() { return mRecentsActivity; } + @NonNull @Override - protected FallbackRecentsView getRecentsView() { + protected FallbackRecentsView getRecentsView() { return mRecentsView; } } diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2TestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2TestCase.java index 653dc01306..ec1dc8b008 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2TestCase.java +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2TestCase.java @@ -19,6 +19,7 @@ package com.android.quickstep; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.when; +import androidx.annotation.NonNull; import androidx.test.filters.SmallTest; import com.android.launcher3.Hotseat; @@ -38,12 +39,11 @@ import org.mockito.Mock; @SmallTest @RunWith(LauncherMultivalentJUnit.class) public class LauncherSwipeHandlerV2TestCase extends AbsSwipeUpHandlerTestCase< - QuickstepLauncher, LauncherState, - RecentsView, QuickstepLauncher, - LauncherActivityInterface, - LauncherSwipeHandlerV2> { + RecentsView, + LauncherSwipeHandlerV2, + LauncherActivityInterface> { @Mock private QuickstepLauncher mQuickstepLauncher; @Mock private RecentsView mRecentsView; @@ -67,6 +67,7 @@ public class LauncherSwipeHandlerV2TestCase extends AbsSwipeUpHandlerTestCase< when(mWorkspace.getStateTransitionAnimation()).thenReturn(mTransitionAnimation); } + @NonNull @Override protected LauncherSwipeHandlerV2 createSwipeHandler( long touchTimeMs, boolean continuingLastGesture) { @@ -80,11 +81,13 @@ public class LauncherSwipeHandlerV2TestCase extends AbsSwipeUpHandlerTestCase< mInputConsumerController); } + @NonNull @Override protected QuickstepLauncher getRecentsContainer() { return mQuickstepLauncher; } + @NonNull @Override protected RecentsView getRecentsView() { return mRecentsView; diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsWindowSwipeHandlerTestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsWindowSwipeHandlerTestCase.java new file mode 100644 index 0000000000..1bdf273ddf --- /dev/null +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsWindowSwipeHandlerTestCase.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2024 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.quickstep; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.test.filters.SmallTest; + +import com.android.launcher3.util.LauncherMultivalentJUnit; +import com.android.quickstep.fallback.FallbackRecentsView; +import com.android.quickstep.fallback.RecentsState; +import com.android.quickstep.fallback.window.RecentsWindowManager; +import com.android.quickstep.fallback.window.RecentsWindowSwipeHandler; +import com.android.quickstep.views.RecentsViewContainer; + +import org.junit.runner.RunWith; +import org.mockito.Mock; + +@SmallTest +@RunWith(LauncherMultivalentJUnit.class) +public class RecentsWindowSwipeHandlerTestCase extends AbsSwipeUpHandlerTestCase< + RecentsState, + RecentsWindowManager, + FallbackRecentsView, + RecentsWindowSwipeHandler, + FallbackWindowInterface> { + + @Mock private RecentsWindowManager mRecentsWindowManager; + @Mock private FallbackRecentsView mRecentsView; + + @NonNull + @Override + protected RecentsWindowSwipeHandler createSwipeHandler(long touchTimeMs, + boolean continuingLastGesture) { + return new RecentsWindowSwipeHandler( + mContext, + mRecentsAnimationDeviceState, + mTaskAnimationManager, + mGestureState, + touchTimeMs, + continuingLastGesture, + mInputConsumerController, + mRecentsWindowManager); + } + + @Nullable + @Override + protected RecentsWindowManager getRecentsWindowManager() { + return mRecentsWindowManager; + } + + @NonNull + @Override + protected RecentsViewContainer getRecentsContainer() { + return mRecentsWindowManager; + } + + @NonNull + @Override + protected FallbackRecentsView getRecentsView() { + return mRecentsView; + } +} diff --git a/res/drawable/all_apps_tabs_background.xml b/res/drawable/all_apps_tabs_background.xml index 62927afeb7..d200b9f961 100644 --- a/res/drawable/all_apps_tabs_background.xml +++ b/res/drawable/all_apps_tabs_background.xml @@ -13,36 +13,25 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - + - - \ No newline at end of file + + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/all_apps_tabs_background_selected.xml b/res/drawable/all_apps_tabs_background_selected.xml new file mode 100644 index 0000000000..47f95dd745 --- /dev/null +++ b/res/drawable/all_apps_tabs_background_selected.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/all_apps_tabs_background_selected_focused.xml b/res/drawable/all_apps_tabs_background_selected_focused.xml new file mode 100644 index 0000000000..e3d86c04fe --- /dev/null +++ b/res/drawable/all_apps_tabs_background_selected_focused.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/all_apps_tabs_background_unselected.xml b/res/drawable/all_apps_tabs_background_unselected.xml new file mode 100644 index 0000000000..ab592a8304 --- /dev/null +++ b/res/drawable/all_apps_tabs_background_unselected.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/all_apps_tabs_background_unselected_focused.xml b/res/drawable/all_apps_tabs_background_unselected_focused.xml new file mode 100644 index 0000000000..0016102ef0 --- /dev/null +++ b/res/drawable/all_apps_tabs_background_unselected_focused.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/all_apps_personal_work_tabs.xml b/res/layout/all_apps_personal_work_tabs.xml index e04b207a3e..ecc5a1404a 100644 --- a/res/layout/all_apps_personal_work_tabs.xml +++ b/res/layout/all_apps_personal_work_tabs.xml @@ -21,8 +21,8 @@ android:layout_width="match_parent" android:layout_height="@dimen/all_apps_header_pill_height" android:layout_gravity="center_horizontal" - android:paddingTop="@dimen/all_apps_tabs_vertical_padding" - android:paddingBottom="@dimen/all_apps_tabs_vertical_padding" + android:paddingTop="@dimen/all_apps_tabs_vertical_padding_focus" + android:paddingBottom="@dimen/all_apps_tabs_vertical_padding_focus" android:layout_marginTop="@dimen/all_apps_tabs_margin_top" android:orientation="horizontal" style="@style/TextHeadline" diff --git a/res/values/dimens.xml b/res/values/dimens.xml index f8c075fa5f..d1e905da48 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -126,6 +126,10 @@ 20dp 4dp 6dp + 1dp + 5dp + 3dp + 2dp 8dp 2dp 128dp