Snap for 12458821 from 644aad280b to 25Q1-release

Change-Id: Ie758ce691e187cd7b1b1f60f3e2363d5428a0853
This commit is contained in:
Android Build Coastguard Worker
2024-10-05 01:23:05 +00:00
22 changed files with 423 additions and 123 deletions
+1 -1
View File
@@ -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 {
@@ -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<Launcher> {
private final PopupDataProvider mPopupDataProvider;
private final boolean mSharingEnabledForUser;
private final Set<View> 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;
}
}
/**
@@ -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();
}
@@ -278,7 +278,10 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
// If Bubble bar is present, TaskbarControllers depends on it so build it first.
Optional<BubbleControllers> bubbleControllersOptional = Optional.empty();
BubbleBarController.onTaskbarRecreated();
if (BubbleBarController.isBubbleBarEnabled() && bubbleBarView != null) {
if (BubbleBarController.isBubbleBarEnabled()
&& !mDeviceProfile.isPhone
&& bubbleBarView != null
) {
Optional<BubbleStashedHandleViewController> bubbleHandleController = Optional.empty();
Optional<BubbleBarSwipeController> bubbleBarSwipeController = Optional.empty();
if (isTransientTaskbar) {
@@ -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();
}
@@ -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;
@@ -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
@@ -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?,
@@ -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();
}
}
@@ -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) {
@@ -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<Integer> 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) {
@@ -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>,
STATE extends BaseState<STATE>, RECENTS_VIEW extends RecentsView<RECENTS_CONTAINER, STATE>,
ACTIVITY_TYPE extends StatefulActivity<STATE> & RecentsViewContainer,
ACTIVITY_INTERFACE extends BaseActivityInterface<STATE, ACTIVITY_TYPE>,
SWIPE_HANDLER extends AbsSwipeUpHandler<RECENTS_CONTAINER, RECENTS_VIEW, STATE>> {
STATE_TYPE extends BaseState<STATE_TYPE>,
RECENTS_CONTAINER extends Context & RecentsViewContainer & StatefulContainer<STATE_TYPE>,
RECENTS_VIEW extends RecentsView<RECENTS_CONTAINER, STATE_TYPE>,
SWIPE_HANDLER extends AbsSwipeUpHandler<RECENTS_CONTAINER, RECENTS_VIEW, STATE_TYPE>,
CONTAINER_INTERFACE extends BaseContainerInterface<STATE_TYPE, RECENTS_CONTAINER>> {
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);
@@ -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>,
RecentsActivity,
FallbackActivityInterface,
FallbackSwipeHandler> {
FallbackRecentsView<RecentsActivity>,
FallbackSwipeHandler,
FallbackActivityInterface> {
@Mock private RecentsActivity mRecentsActivity;
@Mock private FallbackRecentsView mRecentsView;
@Mock private FallbackRecentsView<RecentsActivity> 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<RecentsActivity> getRecentsView() {
return mRecentsView;
}
}
@@ -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, LauncherState>,
QuickstepLauncher,
LauncherActivityInterface,
LauncherSwipeHandlerV2> {
RecentsView<QuickstepLauncher, LauncherState>,
LauncherSwipeHandlerV2,
LauncherActivityInterface> {
@Mock private QuickstepLauncher mQuickstepLauncher;
@Mock private RecentsView<QuickstepLauncher, LauncherState> 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<QuickstepLauncher, LauncherState> getRecentsView() {
return mRecentsView;
@@ -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<RecentsWindowManager>,
RecentsWindowSwipeHandler,
FallbackWindowInterface> {
@Mock private RecentsWindowManager mRecentsWindowManager;
@Mock private FallbackRecentsView<RecentsWindowManager> 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<RecentsWindowManager> getRecentsView() {
return mRecentsView;
}
}
+20 -31
View File
@@ -13,36 +13,25 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/accent_ripple_color">
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
<corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
<solid android:color="@color/accent_ripple_color" />
</shape>
</item>
<item>
<selector android:enterFadeDuration="100">
<item
android:id="@+id/unselected"
android:state_selected="false">
<shape android:shape="rectangle">
<corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
<solid android:color="?attr/materialColorSurfaceBright" />
</shape>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/all_apps_tabs_background_unselected_focused" android:state_focused="true" android:state_selected="false" />
<item android:drawable="@drawable/all_apps_tabs_background_selected_focused" android:state_focused="true" android:state_selected="true" />
<item android:id="@+id/unselected" android:state_focused="false" android:state_selected="false">
<ripple android:color="@color/accent_ripple_color">
<item>
<selector android:enterFadeDuration="100">
<item android:drawable="@drawable/all_apps_tabs_background_unselected" />
</selector>
</item>
<item
android:id="@+id/selected"
android:state_selected="true">
<shape android:shape="rectangle">
<corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
<solid android:color="?attr/materialColorPrimary" />
</shape>
</item>
</selector>
</ripple>
</item>
</ripple>
<item android:id="@+id/selected" android:state_focused="false" android:state_selected="true">
<ripple android:color="@color/accent_ripple_color">
<item>
<selector android:enterFadeDuration="100">
<item android:drawable="@drawable/all_apps_tabs_background_selected" />
</selector>
</item>
</ripple>
</item>
</selector>
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?><!--
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.
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="@dimen/all_apps_tabs_focus_width"
android:end="@dimen/all_apps_tabs_focus_width"
android:start="@dimen/all_apps_tabs_focus_width"
android:top="@dimen/all_apps_tabs_focus_width">
<shape android:shape="rectangle">
<corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
<solid android:color="?attr/materialColorPrimary" />
</shape>
</item>
</layer-list>
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?><!--
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.
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<corners android:radius="16dp" />
<solid android:color="?attr/materialColorPrimary" />
</shape>
</item>
<item
android:bottom="@dimen/all_apps_tabs_focus_border"
android:end="@dimen/all_apps_tabs_focus_border"
android:start="@dimen/all_apps_tabs_focus_border"
android:top="@dimen/all_apps_tabs_focus_border">
<shape android:shape="rectangle">
<corners android:radius="13dp" />
<solid android:color="?attr/materialColorPrimary" />
<stroke
android:width="@dimen/all_apps_tabs_focus_padding"
android:color="?attr/materialColorSurfaceDim" />
</shape>
</item>
</layer-list>
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?><!--
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.
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="@dimen/all_apps_tabs_focus_width"
android:end="@dimen/all_apps_tabs_focus_width"
android:start="@dimen/all_apps_tabs_focus_width"
android:top="@dimen/all_apps_tabs_focus_width">
<shape android:shape="rectangle">
<corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
<solid android:color="?attr/materialColorSurfaceBright" />
</shape>
</item>
</layer-list>
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?><!--
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.
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<corners android:radius="16dp" />
<solid android:color="?attr/materialColorPrimary" />
</shape>
</item>
<item
android:bottom="@dimen/all_apps_tabs_focus_border"
android:end="@dimen/all_apps_tabs_focus_border"
android:start="@dimen/all_apps_tabs_focus_border"
android:top="@dimen/all_apps_tabs_focus_border">
<shape android:shape="rectangle">
<corners android:radius="13dp" />
<solid android:color="?attr/materialColorSurfaceBright" />
<stroke
android:width="@dimen/all_apps_tabs_focus_padding"
android:color="?attr/materialColorSurfaceDim" />
</shape>
</item>
</layer-list>
+2 -2
View File
@@ -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"
+4
View File
@@ -126,6 +126,10 @@
<dimen name="all_apps_work_profile_tab_footer_bottom_padding">20dp</dimen>
<dimen name="all_apps_tabs_button_horizontal_padding">4dp</dimen>
<dimen name="all_apps_tabs_vertical_padding">6dp</dimen>
<dimen name="all_apps_tabs_vertical_padding_focus">1dp</dimen>
<dimen name="all_apps_tabs_focus_width">5dp</dimen>
<dimen name="all_apps_tabs_focus_border">3dp</dimen>
<dimen name="all_apps_tabs_focus_padding">2dp</dimen>
<dimen name="all_apps_tabs_margin_top">8dp</dimen>
<dimen name="all_apps_divider_height">2dp</dimen>
<dimen name="all_apps_divider_width">128dp</dimen>