diff --git a/quickstep/res/drawable/ic_all_set.xml b/quickstep/res/drawable/ic_all_set.xml index 656c59669c..f718b8b64b 100644 --- a/quickstep/res/drawable/ic_all_set.xml +++ b/quickstep/res/drawable/ic_all_set.xml @@ -14,10 +14,10 @@ limitations under the License. --> + android:width="48dp" + android:height="48dp" + android:viewportWidth="24" + android:viewportHeight="24"> diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index a2c0a7dee9..9b402e3cb5 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -114,8 +114,8 @@ 40dp - 28dp - 80dp + 24dp + 32dp 52dp 24dp diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java index 052e66267e..475f06109e 100644 --- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java @@ -20,11 +20,11 @@ import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON; import static com.android.launcher3.LauncherState.FLAG_HIDE_BACK_BUTTON; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.NO_OFFSET; +import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID; import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS; -import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY; import android.animation.AnimatorSet; @@ -185,7 +185,7 @@ public abstract class BaseQuickstepLauncher extends Launcher @Override protected void onScreenOff() { super.onScreenOff(); - if (LIVE_TILE.get()) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { RecentsView recentsView = getOverviewPanel(); recentsView.finishRecentsAnimation(true /* toRecents */, null); } @@ -483,7 +483,7 @@ public abstract class BaseQuickstepLauncher extends Launcher super.onDisplayInfoChanged(context, info, flags); // When changing screens with live tile active, finish the recents animation to close // overview as it should be an interim state - if ((flags & CHANGE_ACTIVE_SCREEN) != 0 && LIVE_TILE.get()) { + if ((flags & CHANGE_ACTIVE_SCREEN) != 0 && ENABLE_QUICKSTEP_LIVE_TILE.get()) { RecentsView recentsView = getOverviewPanel(); recentsView.finishRecentsAnimation(/* toRecents= */ true, null); } diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index f8cfe173ec..ebf8fb79d7 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -725,7 +725,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener floatingIconBounds.bottom += offsetY; if (initOnly) { - floatingView.update(mIconAlpha.value, 255, floatingIconBounds, percent, 0f, + // For the init pass, we want full alpha since the window is not yet ready. + floatingView.update(1f, 255, floatingIconBounds, percent, 0f, mWindowRadius.value * scale, true /* isOpening */); return; } diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java index 521dd233b8..86c42caa7b 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java @@ -25,8 +25,8 @@ import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback; import static com.android.launcher3.anim.Interpolators.DEACCEL_3; import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_EDU; +import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE; -import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import android.animation.ValueAnimator; @@ -140,7 +140,7 @@ public class NavBarToHomeTouchController implements TouchController, AnimatorControllerWithResistance.createRecentsResistanceFromOverviewAnim(mLauncher, builder); - if (LIVE_TILE.get()) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { builder.addOnFrameCallback(recentsView::redrawLiveTile); } @@ -189,7 +189,7 @@ public class NavBarToHomeTouchController implements TouchController, boolean success = interpolatedProgress >= SUCCESS_TRANSITION_PROGRESS || (velocity < 0 && fling); if (success) { - if (LIVE_TILE.get()) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { RecentsView recentsView = mLauncher.getOverviewPanel(); recentsView.switchToScreenshot(null, () -> recentsView.finishRecentsAnimation(true /* toRecents */, null)); diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index e2e03ce6fa..6423352376 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -25,6 +25,7 @@ import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAG import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2; +import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE; @@ -45,7 +46,6 @@ import static com.android.quickstep.GestureState.STATE_END_TARGET_SET; import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_CANCELED; import static com.android.quickstep.GestureState.STATE_RECENTS_SCROLLING_FINISHED; import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; -import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE; import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME; @@ -327,7 +327,7 @@ public abstract class AbsSwipeUpHandler, mStateCallback.runOnceAtState(STATE_HANDLER_INVALIDATED | STATE_FINISH_WITH_NO_END, this::resetStateForAnimationCancel); - if (!LIVE_TILE.get()) { + if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) { mStateCallback.addChangeListener(STATE_APP_CONTROLLER_RECEIVED | STATE_LAUNCHER_PRESENT | STATE_SCREENSHOT_VIEW_SHOWN | STATE_CAPTURE_SCREENSHOT, (b) -> mRecentsView.setRunningTaskHidden(!b)); @@ -384,10 +384,10 @@ public abstract class AbsSwipeUpHandler, // Set up a entire animation lifecycle callback to notify the current recents view when // the animation is canceled mGestureState.runOnceAtState(STATE_RECENTS_ANIMATION_CANCELED, () -> { - ThumbnailData snapshot = mGestureState.getRecentsAnimationCanceledSnapshot(); + ThumbnailData snapshot = mGestureState.consumeRecentsAnimationCanceledSnapshot(); if (snapshot != null) { - RecentsModel.INSTANCE.get(mContext).onTaskSnapshotChanged( - mRecentsView.getRunningTaskId(), snapshot); + mRecentsView.switchToScreenshot(snapshot, + () -> mRecentsAnimationController.cleanupScreenshot()); mRecentsView.onRecentsAnimationComplete(); } }); @@ -490,7 +490,7 @@ public abstract class AbsSwipeUpHandler, } private void onDeferredActivityLaunch() { - if (LIVE_TILE.get()) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { mActivityInterface.switchRunningTaskViewToScreenshot( null, () -> { mTaskAnimationManager.finishRunningRecentsAnimation(true /* toHome */); @@ -1430,7 +1430,7 @@ public abstract class AbsSwipeUpHandler, } private void invalidateHandler() { - if (!LIVE_TILE.get() || !mActivityInterface.isInLiveTileMode() + if (!ENABLE_QUICKSTEP_LIVE_TILE.get() || !mActivityInterface.isInLiveTileMode() || mGestureState.getEndTarget() != RECENTS) { mInputConsumerProxy.destroy(); mTaskAnimationManager.setLiveTileCleanUpHandler(null); @@ -1475,7 +1475,7 @@ public abstract class AbsSwipeUpHandler, */ private void resetLauncherListeners() { // Reset the callback for deferred activity launches - if (!LIVE_TILE.get()) { + if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) { mActivityInterface.setOnDeferredActivityLaunchCallback(null); } mActivity.getRootView().setOnApplyWindowInsetsListener(null); @@ -1499,7 +1499,7 @@ public abstract class AbsSwipeUpHandler, mStateCallback.setStateOnUiThread(STATE_SCREENSHOT_CAPTURED); } else { final int runningTaskId = mGestureState.getRunningTaskId(); - final boolean refreshView = !LIVE_TILE.get() /* refreshView */; + final boolean refreshView = !ENABLE_QUICKSTEP_LIVE_TILE.get() /* refreshView */; boolean finishTransitionPosted = false; if (mRecentsAnimationController != null) { // Update the screenshot of the task @@ -1555,7 +1555,7 @@ public abstract class AbsSwipeUpHandler, } private void finishCurrentTransitionToRecents() { - if (LIVE_TILE.get()) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED); if (mRecentsAnimationController != null) { mRecentsAnimationController.detachNavigationBarFromApp(true); @@ -1609,7 +1609,7 @@ public abstract class AbsSwipeUpHandler, } endLauncherTransitionController(); mRecentsView.onSwipeUpAnimationSuccess(); - if (LIVE_TILE.get()) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { mTaskAnimationManager.setLiveTileCleanUpHandler(mInputConsumerProxy::destroy); mTaskAnimationManager.enableLiveTileRestartListener(); } diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java index 906599f560..f29d68a72a 100644 --- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java +++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java @@ -15,6 +15,7 @@ */ package com.android.quickstep; +import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; import static com.android.quickstep.fallback.RecentsState.BACKGROUND_APP; import static com.android.quickstep.fallback.RecentsState.DEFAULT; @@ -105,8 +106,12 @@ public final class FallbackActivityInterface extends @Override public RecentsView getVisibleRecentsView() { RecentsActivity activity = getCreatedActivity(); - if (activity != null && activity.hasBeenResumed()) { - return activity.getOverviewPanel(); + if (activity != null) { + RecentsView recentsView = activity.getOverviewPanel(); + if (activity.hasBeenResumed() || (ENABLE_QUICKSTEP_LIVE_TILE.get() && isInLiveTileMode() + && recentsView.getRunningTaskId() == -1)) { + return recentsView; + } } return null; } diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java index a302a07bca..015002f0e1 100644 --- a/quickstep/src/com/android/quickstep/GestureState.java +++ b/quickstep/src/com/android/quickstep/GestureState.java @@ -376,11 +376,14 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL } /** - * Returns the canceled animation thumbnail data. This call only returns a value while - * STATE_RECENTS_ANIMATION_CANCELED state is being set. + * Returns and clears the canceled animation thumbnail data. This call only returns a value + * while STATE_RECENTS_ANIMATION_CANCELED state is being set, and the caller is responsible for + * calling {@link RecentsAnimationController#cleanupScreenshot()}. */ - ThumbnailData getRecentsAnimationCanceledSnapshot() { - return mRecentsAnimationCanceledSnapshot; + ThumbnailData consumeRecentsAnimationCanceledSnapshot() { + ThumbnailData data = mRecentsAnimationCanceledSnapshot; + mRecentsAnimationCanceledSnapshot = null; + return data; } void setSwipeUpStartTimeMs(long uptimeMs) { diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java index 09474a1ac2..94a47e6cd0 100644 --- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java +++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java @@ -21,6 +21,7 @@ import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.QUICK_SWITCH; import static com.android.launcher3.anim.AnimatorListeners.forEndCallback; import static com.android.launcher3.anim.Interpolators.LINEAR; +import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import android.animation.Animator; @@ -184,16 +185,24 @@ public final class LauncherActivityInterface extends @Override public RecentsView getVisibleRecentsView() { Launcher launcher = getVisibleLauncher(); - return launcher != null && launcher.getStateManager().getState().overviewUi - ? launcher.getOverviewPanel() : null; + RecentsView recentsView = + launcher != null && launcher.getStateManager().getState().overviewUi + ? launcher.getOverviewPanel() : null; + if (recentsView == null || (!launcher.hasBeenResumed() + && recentsView.getRunningTaskId() == -1)) { + // If live tile has ended, return null. + return null; + } + return recentsView; } @Nullable @UiThread private Launcher getVisibleLauncher() { Launcher launcher = getCreatedActivity(); - return (launcher != null) && launcher.isStarted() && launcher.hasBeenResumed() - ? launcher : null; + return (launcher != null) && launcher.isStarted() + && ((ENABLE_QUICKSTEP_LIVE_TILE.get() && isInLiveTileMode()) + || launcher.hasBeenResumed()) ? launcher : null; } @Override @@ -202,6 +211,12 @@ public final class LauncherActivityInterface extends if (launcher == null) { return false; } + if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isInLiveTileMode()) { + RecentsView recentsView = getVisibleRecentsView(); + if (recentsView == null) { + return false; + } + } closeOverlay(); launcher.getStateManager().goToState(OVERVIEW, diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java index 2beef0a7ce..742d02d204 100644 --- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java +++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java @@ -15,6 +15,7 @@ */ package com.android.quickstep; +import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.quickstep.util.ActiveGestureLog.INTENT_EXTRA_LOG_TRACE_ID; diff --git a/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java b/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java index 192738f76a..65847f11bb 100644 --- a/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java +++ b/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java @@ -15,8 +15,6 @@ */ package com.android.quickstep; -import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE; - import android.annotation.TargetApi; import android.content.Context; import android.content.pm.PackageManager; @@ -61,8 +59,6 @@ public class QuickstepProcessInitializer extends MainProcessInitializer { super.init(context); - LIVE_TILE.initialize(context); - // Elevate GPU priority for Quickstep and Remote animations. ThreadedRendererCompat.setContextPriority( ThreadedRendererCompat.EGL_CONTEXT_PRIORITY_HIGH_IMG); diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java index fa5ab1cb7b..9dfcd12dde 100644 --- a/quickstep/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/src/com/android/quickstep/RecentsActivity.java @@ -23,10 +23,10 @@ import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSI import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_PRE_DELAY; import static com.android.launcher3.Utilities.createHomeIntent; import static com.android.launcher3.graphics.SysUiScrim.SYSUI_PROGRESS; +import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL; import static com.android.quickstep.TaskUtils.taskIsATargetWithMode; import static com.android.quickstep.TaskViewUtils.createRecentsWindowAnimator; -import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING; @@ -359,7 +359,7 @@ public final class RecentsActivity extends StatefulActivity { } public void startHome() { - if (LIVE_TILE.get()) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { RecentsView recentsView = getOverviewPanel(); recentsView.switchToScreenshot(() -> recentsView.finishRecentsAnimation(true, this::startHomeInternal)); diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java index ae2328e643..33718a3cac 100644 --- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java +++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java @@ -15,11 +15,11 @@ */ package com.android.quickstep; +import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_INITIALIZED; import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_STARTED; -import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE; import android.app.ActivityManager; import android.content.Context; @@ -65,7 +65,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn return; } BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface(); - if (LIVE_TILE.get() && activityInterface.isInLiveTileMode() + if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityInterface.isInLiveTileMode() && activityInterface.getCreatedActivity() != null) { RecentsView recentsView = activityInterface.getCreatedActivity().getOverviewPanel(); if (recentsView != null) { @@ -139,7 +139,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn @Override public void onTaskAppeared(RemoteAnimationTargetCompat appearedTaskTarget) { BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface(); - if (LIVE_TILE.get() && activityInterface.isInLiveTileMode() + if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityInterface.isInLiveTileMode() && activityInterface.getCreatedActivity() != null) { RecentsView recentsView = activityInterface.getCreatedActivity().getOverviewPanel(); diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java index 729710715a..ffa254d14c 100644 --- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java +++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java @@ -18,7 +18,7 @@ package com.android.quickstep; import static android.view.Surface.ROTATION_0; -import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE; +import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.quickstep.views.OverviewActionsView.DISABLED_NO_THUMBNAIL; import static com.android.quickstep.views.OverviewActionsView.DISABLED_ROTATED; @@ -188,7 +188,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride { * @param callback callback to run, after switching to screenshot */ public void endLiveTileMode(@NonNull Runnable callback) { - if (LIVE_TILE.get()) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { RecentsView recentsView = mThumbnailView.getTaskView().getRecentsView(); recentsView.switchToScreenshot( () -> recentsView.finishRecentsAnimation(true /* toRecents */, diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java index 3293810582..37fda73d44 100644 --- a/quickstep/src/com/android/quickstep/TaskViewUtils.java +++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java @@ -34,7 +34,6 @@ import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLAT import static com.android.launcher3.anim.Interpolators.clampToProgress; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.statehandlers.DepthController.DEPTH; -import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING; @@ -155,7 +154,7 @@ public final class TaskViewUtils { boolean isRunningTask = v.isRunningTask(); TransformParams params = null; TaskViewSimulator tsv = null; - if (LIVE_TILE.get() && isRunningTask) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask) { params = v.getRecentsView().getLiveTileParams(); tsv = v.getRecentsView().getLiveTileTaskViewSimulator(); } @@ -176,7 +175,8 @@ public final class TaskViewUtils { boolean isQuickSwitch = v.isEndQuickswitchCuj(); v.setEndQuickswitchCuj(false); - boolean inLiveTileMode = LIVE_TILE.get() && v.getRecentsView().getRunningTaskIndex() != -1; + boolean inLiveTileMode = + ENABLE_QUICKSTEP_LIVE_TILE.get() && v.getRecentsView().getRunningTaskIndex() != -1; final RemoteAnimationTargets targets = new RemoteAnimationTargets(appTargets, wallpaperTargets, nonAppTargets, inLiveTileMode ? MODE_CLOSING : MODE_OPENING); @@ -531,7 +531,7 @@ public final class TaskViewUtils { }; } pa.add(launcherAnim); - if (LIVE_TILE.get() && recentsView.getRunningTaskIndex() != -1) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get() && recentsView.getRunningTaskIndex() != -1) { pa.addOnFrameCallback(recentsView::redrawLiveTile); } anim.play(pa.buildAnim()); diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index e8324f70e0..af1a01a4ec 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -21,9 +21,9 @@ import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_UP; import static com.android.launcher3.config.FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS; +import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.quickstep.GestureState.DEFAULT_STATE; -import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_ONE_HANDED; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_PIP; @@ -765,7 +765,8 @@ public class TouchInteractionService extends Service implements PluginListener, T extends StatefulAct @Override public void onKeyEvent(KeyEvent ev) { - if (LIVE_TILE.get()) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { switch (ev.getKeyCode()) { case KeyEvent.KEYCODE_VOLUME_DOWN: case KeyEvent.KEYCODE_VOLUME_UP: diff --git a/quickstep/src/com/android/quickstep/util/NavigationModeFeatureFlag.java b/quickstep/src/com/android/quickstep/util/NavigationModeFeatureFlag.java deleted file mode 100644 index 60c7add38f..0000000000 --- a/quickstep/src/com/android/quickstep/util/NavigationModeFeatureFlag.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2021 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.util; - -import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; - -import android.content.Context; - -import com.android.quickstep.SysUINavigationMode; - -import java.util.function.Predicate; -import java.util.function.Supplier; - -/** A feature flag that listens to navigation mode changes. */ -public class NavigationModeFeatureFlag implements - SysUINavigationMode.NavigationModeChangeListener { - - public static final NavigationModeFeatureFlag LIVE_TILE = new NavigationModeFeatureFlag( - ENABLE_QUICKSTEP_LIVE_TILE::get, mode -> mode.hasGestures); - - private final Supplier mBasePredicate; - private final Predicate mModePredicate; - private boolean mSupported; - - private NavigationModeFeatureFlag(Supplier basePredicate, - Predicate modePredicate) { - mBasePredicate = basePredicate; - mModePredicate = modePredicate; - } - - public boolean get() { - return mBasePredicate.get() && mSupported; - } - - public void initialize(Context context) { - onNavigationModeChanged(SysUINavigationMode.INSTANCE.get(context).getMode()); - SysUINavigationMode.INSTANCE.get(context).addModeChangeListener(this); - } - - @Override - public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) { - mSupported = mModePredicate.test(newMode); - } -} diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index d59b4596d6..538f626f86 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -37,6 +37,7 @@ import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.clampToProgress; +import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_CLEAR_ALL; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN; @@ -46,7 +47,6 @@ 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.SystemUiController.UI_STATE_FULLSCREEN_TASK; import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId; -import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE; import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION; import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_RECENTS; import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS; @@ -129,6 +129,7 @@ import com.android.launcher3.util.IntSet; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.ResourceBasedOverride.Overrides; import com.android.launcher3.util.SplitConfigurationOptions; +import com.android.launcher3.util.RunnableList; import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; import com.android.launcher3.util.Themes; import com.android.launcher3.util.TranslateEdgeEffect; @@ -504,6 +505,7 @@ public abstract class RecentsView 0) { setCurrentPage(indexOfChild(getTaskViewAt(0))); } + } else if (currentTaskId != -1) { + currentTaskView = getTaskView(currentTaskId); + if (currentTaskView != null) { + setCurrentPage(indexOfChild(currentTaskView)); + } } if (mIgnoreResetTaskId != -1 && getTaskView(mIgnoreResetTaskId) != ignoreResetTaskView) { @@ -1196,7 +1227,7 @@ public abstract class RecentsView 0 ? getTaskViewAt(0).getTaskId() : -1; if (mRecentsAnimationController != null) { - if (LIVE_TILE.get() && mEnableDrawingLiveTile) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile) { // We are still drawing the live tile, finish it now to clean up. finishRecentsAnimation(true /* toRecents */, null); } else { @@ -1746,7 +1783,7 @@ public abstract class RecentsView { mLiveTileTaskViewSimulator.taskSecondaryTranslation.value = mOrientationHandler.getSecondaryValue( @@ -2336,7 +2375,8 @@ public abstract class RecentsView { mLiveTileTaskViewSimulator.taskPrimaryTranslation.value = @@ -2406,8 +2446,8 @@ public abstract class RecentsView() { @Override public void accept(Boolean success) { - if (LIVE_TILE.get() && mEnableDrawingLiveTile && dismissedTaskView.isRunningTask() - && success) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile + && dismissedTaskView.isRunningTask() && success) { finishRecentsAnimation(true /* toRecents */, false /* shouldPip */, () -> onEnd(success)); } else { @@ -2420,7 +2460,8 @@ public abstract class RecentsView removeTaskInternal(dismissedTaskId)); } else { @@ -2865,7 +2906,8 @@ public abstract class RecentsView { if (isSuccess) { - if (LIVE_TILE.get() && tv.isRunningTask()) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get() && tv.isRunningTask()) { finishRecentsAnimation(false /* toRecents */, null); onTaskLaunchAnimationEnd(true /* success */); } else { @@ -3439,7 +3481,7 @@ public abstract class RecentsView { - if (LIVE_TILE.get() && isRunningTask()) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask()) { RecentsView recentsView = getRecentsView(); recentsView.switchToScreenshot( () -> recentsView.finishRecentsAnimation(true /* toRecents */, diff --git a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java index 4f27e21ae8..dc73a9a51c 100644 --- a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java +++ b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java @@ -16,7 +16,7 @@ package com.android.quickstep; -import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE; +import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static org.junit.Assert.assertTrue; @@ -75,7 +75,7 @@ public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest { private boolean isInLiveTileMode(Launcher launcher, LauncherInstrumentation.ContainerType expectedContainerType) { - if (!LIVE_TILE.get() + if (!ENABLE_QUICKSTEP_LIVE_TILE.get() || expectedContainerType != LauncherInstrumentation.ContainerType.OVERVIEW) { return false; } diff --git a/src/com/android/launcher3/folder/PreviewItemManager.java b/src/com/android/launcher3/folder/PreviewItemManager.java index a6674fcb08..8bef6ad7ff 100644 --- a/src/com/android/launcher3/folder/PreviewItemManager.java +++ b/src/com/android/launcher3/folder/PreviewItemManager.java @@ -269,6 +269,9 @@ public class PreviewItemManager { setDrawable(p, items.get(i)); if (!animate) { + if (p.anim != null) { + p.anim.cancel(); + } computePreviewItemDrawingParams(i, numItemsInFirstPagePreview, p); if (mReferenceDrawable == null) { mReferenceDrawable = p.drawable; diff --git a/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java b/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java index 867c770278..4ec7e60c86 100644 --- a/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java +++ b/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java @@ -417,7 +417,8 @@ public class DatabaseWidgetPreviewLoader implements WidgetPreviewLoader { previewHeight = drawable.getIntrinsicHeight(); } else { DeviceProfile dp = launcher.getDeviceProfile(); - Size widgetSize = WidgetSizes.getWidgetSizePx(dp, spanX, spanY); + Size widgetSize = WidgetSizes.getWidgetPaddedSizePx(mContext, info.provider, dp, spanX, + spanY); previewWidth = widgetSize.getWidth(); previewHeight = widgetSize.getHeight(); } diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java index bfe1587dbf..fb6de9fb5e 100644 --- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java +++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java @@ -52,7 +52,6 @@ import com.android.launcher3.views.BaseDragLayer.TouchCompleteListener; import com.android.launcher3.widget.dragndrop.AppWidgetHostViewDragListener; import java.util.List; -import java.util.Optional; /** * {@inheritDoc} @@ -99,7 +98,8 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView private final ViewGroupFocusHelper mDragLayerRelativeCoordinateHelper; private long mDeferUpdatesUntilMillis = 0; private RemoteViews mDeferredRemoteViews; - private Optional mDeferredColorChange = Optional.empty(); + private boolean mHasDeferredColorChange = false; + private @Nullable SparseIntArray mDeferredColorChange = null; private boolean mEnableColorExtraction = true; public LauncherAppWidgetHostView(Context context) { @@ -217,18 +217,23 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView */ public void endDeferringUpdates() { RemoteViews remoteViews; - Optional deferredColors; + SparseIntArray deferredColors; + boolean hasDeferredColors; synchronized (mUpdateLock) { mDeferUpdatesUntilMillis = 0; remoteViews = mDeferredRemoteViews; mDeferredRemoteViews = null; deferredColors = mDeferredColorChange; - mDeferredColorChange = Optional.empty(); + hasDeferredColors = mHasDeferredColorChange; + mDeferredColorChange = null; + mHasDeferredColorChange = false; } if (remoteViews != null) { updateAppWidget(remoteViews); } - deferredColors.ifPresent(colors -> onColorsChanged(null /* rectF */, colors)); + if (hasDeferredColors) { + onColorsChanged(null /* rectF */, deferredColors); + } } public boolean onInterceptTouchEvent(MotionEvent ev) { @@ -394,10 +399,12 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView public void onColorsChanged(RectF rectF, SparseIntArray colors) { synchronized (mUpdateLock) { if (isDeferringUpdates()) { - mDeferredColorChange = Optional.ofNullable(colors); + mDeferredColorChange = colors; + mHasDeferredColorChange = true; return; } - mDeferredColorChange = Optional.empty(); + mDeferredColorChange = null; + mHasDeferredColorChange = false; } // setColorResources will reapply the view, which must happen in the UI thread. diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java index 8798332c85..c3edcce95a 100644 --- a/src/com/android/launcher3/widget/WidgetCell.java +++ b/src/com/android/launcher3/widget/WidgetCell.java @@ -363,7 +363,9 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { /** Sets the widget preview image size, in number of cells, and preview scale. */ public Size setPreviewSize(int spanX, int spanY, float previewScale) { DeviceProfile deviceProfile = mActivity.getDeviceProfile(); - Size widgetSize = WidgetSizes.getWidgetSizePx(deviceProfile, spanX, spanY); + Size widgetSize = + mItem != null ? WidgetSizes.getWidgetItemSizePx(getContext(), deviceProfile, mItem) + : WidgetSizes.getWidgetSizePx(deviceProfile, spanX, spanY); mPreviewWidth = widgetSize.getWidth(); mPreviewHeight = widgetSize.getHeight(); mPreviewScale = previewScale; diff --git a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java index 08a2263eff..1125b82150 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java +++ b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java @@ -296,11 +296,8 @@ public class WidgetsListAdapter extends Adapter implements OnHeaderC for (int i = 0; i < entry.mWidgets.size(); i++) { WidgetItem widgetItem = entry.mWidgets.get(i); DeviceProfile deviceProfile = activity.getDeviceProfile(); - Size widgetSize = - WidgetSizes.getWidgetSizePx( - deviceProfile, - widgetItem.spanX, - widgetItem.spanY); + Size widgetSize = WidgetSizes.getWidgetItemSizePx(mContext, deviceProfile, + widgetItem); if (widgetItem.isShortcut()) { widgetSize = new Size( diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java index 6fc684862d..3800ede169 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java +++ b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java @@ -155,8 +155,8 @@ public final class WidgetsRecommendationTableLayout extends TableLayout { float rowHeight = 0; for (int j = 0; j < widgetItems.size(); j++) { WidgetItem widgetItem = widgetItems.get(j); - Size widgetSize = WidgetSizes.getWidgetSizePx( - deviceProfile, widgetItem.spanX, widgetItem.spanY); + Size widgetSize = WidgetSizes.getWidgetItemSizePx(getContext(), deviceProfile, + widgetItem); float previewHeight = widgetSize.getHeight() * previewScale; rowHeight = Math.max(rowHeight, previewHeight + mWidgetCellTextViewsHeight + mWidgetCellVerticalPadding); diff --git a/src/com/android/launcher3/widget/util/WidgetSizes.java b/src/com/android/launcher3/widget/util/WidgetSizes.java index 5c8ea7299b..e2c84b5770 100644 --- a/src/com/android/launcher3/widget/util/WidgetSizes.java +++ b/src/com/android/launcher3/widget/util/WidgetSizes.java @@ -17,9 +17,7 @@ package com.android.launcher3.widget.util; import static android.appwidget.AppWidgetHostView.getDefaultPaddingForWidget; -import static com.android.launcher3.Utilities.ATLEAST_S; -import android.annotation.SuppressLint; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetManager; import android.content.ComponentName; @@ -34,24 +32,34 @@ import androidx.annotation.Nullable; import com.android.launcher3.DeviceProfile; import com.android.launcher3.LauncherAppState; +import com.android.launcher3.model.WidgetItem; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; /** A utility class for widget sizes related calculations. */ public final class WidgetSizes { /** * Returns the list of all possible sizes, in dp, for a widget of given spans on this device. + * + *

The returned sizes already take into account the system padding, and whether it is applied + * or not in that specific configuration. */ - public static ArrayList getWidgetSizes(Context context, int spanX, int spanY) { + public static ArrayList getWidgetPaddedSizes(Context context, ComponentName provider, + int spanX, int spanY) { + Rect padding = getDefaultPaddingForWidget(context, provider, /* padding= */ null); + ArrayList sizes = new ArrayList<>(2); final float density = context.getResources().getDisplayMetrics().density; final Point cellSize = new Point(); for (DeviceProfile profile : LauncherAppState.getIDP(context).supportedProfiles) { Size widgetSizePx = getWidgetSizePx(profile, spanX, spanY, cellSize); + if (!profile.shouldInsetWidgets()) { + widgetSizePx = new Size(widgetSizePx.getWidth() - padding.left - padding.right, + widgetSizePx.getHeight() - padding.top - padding.bottom); + } sizes.add(new SizeF(widgetSizePx.getWidth() / density, widgetSizePx.getHeight() / density)); } @@ -63,6 +71,32 @@ public final class WidgetSizes { return getWidgetSizePx(profile, spanX, spanY, /* recycledCellSize= */ null); } + /** + * Returns the size, in pixels and removing padding, a widget of given spans & {@code profile}. + */ + public static Size getWidgetPaddedSizePx(Context context, ComponentName component, + DeviceProfile profile, int spanX, int spanY) { + Size size = getWidgetSizePx(profile, spanX, spanY); + if (profile.shouldInsetWidgets()) { + return size; + } + Rect padding = getDefaultPaddingForWidget(context, component, /* padding= */ null); + return new Size(size.getWidth() - padding.left - padding.right, + size.getHeight() - padding.top - padding.bottom); + } + + /** + * Returns the size of a WidgetItem. + */ + public static Size getWidgetItemSizePx(Context context, DeviceProfile profile, + WidgetItem widgetItem) { + if (widgetItem.isShortcut()) { + return getWidgetSizePx(profile, widgetItem.spanX, widgetItem.spanY); + } + return getWidgetPaddedSizePx(context, widgetItem.componentName, profile, widgetItem.spanX, + widgetItem.spanY); + } + private static Size getWidgetSizePx(DeviceProfile profile, int spanX, int spanY, @Nullable Point recycledCellSize) { final int hBorderSpacing = (spanX - 1) * profile.cellLayoutBorderSpacingPx; @@ -81,17 +115,22 @@ public final class WidgetSizes { *

On Android S+, it also updates the given {@code widgetView} with a list of sizes derived * from {@code spanX}, {@code spanY} in all supported device profiles. */ - @SuppressLint("NewApi") // Already added API check. public static void updateWidgetSizeRanges(AppWidgetHostView widgetView, Context context, int spanX, int spanY) { - List sizes = getWidgetSizes(context, spanX, spanY); - if (ATLEAST_S) { - widgetView.updateAppWidgetSize(new Bundle(), sizes); - } else { - Rect bounds = getMinMaxSizes(sizes); - widgetView.updateAppWidgetSize(new Bundle(), bounds.left, bounds.top, bounds.right, - bounds.bottom); + AppWidgetManager widgetManager = AppWidgetManager.getInstance(context); + int widgetId = widgetView.getAppWidgetId(); + if (widgetId <= 0) { + return; } + Bundle sizeOptions = getWidgetSizeOptions(context, widgetView.getAppWidgetInfo().provider, + spanX, spanY); + if (sizeOptions.getParcelableArrayList( + AppWidgetManager.OPTION_APPWIDGET_SIZES).equals( + widgetManager.getAppWidgetOptions(widgetId).getParcelableArrayList( + AppWidgetManager.OPTION_APPWIDGET_SIZES))) { + return; + } + widgetManager.updateAppWidgetOptions(widgetId, sizeOptions); } /** @@ -99,17 +138,7 @@ public final class WidgetSizes { */ public static Bundle getWidgetSizeOptions(Context context, ComponentName provider, int spanX, int spanY) { - ArrayList sizes = getWidgetSizes(context, spanX, spanY); - Rect padding = getDefaultPaddingForWidget(context, provider, null); - float density = context.getResources().getDisplayMetrics().density; - float xPaddingDips = (padding.left + padding.right) / density; - float yPaddingDips = (padding.top + padding.bottom) / density; - - ArrayList paddedSizes = sizes.stream() - .map(size -> new SizeF( - Math.max(0.f, size.getWidth() - xPaddingDips), - Math.max(0.f, size.getHeight() - yPaddingDips))) - .collect(Collectors.toCollection(ArrayList::new)); + ArrayList paddedSizes = getWidgetPaddedSizes(context, provider, spanX, spanY); Rect rect = getMinMaxSizes(paddedSizes); Bundle options = new Bundle();