diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml index 4fd2e4075c..4e72260e9c 100644 --- a/AndroidManifest-common.xml +++ b/AndroidManifest-common.xml @@ -116,8 +116,7 @@ android:theme="@style/AppItemActivityTheme" android:excludeFromRecents="true" android:autoRemoveFromRecents="true" - android:exported="true" - android:label="@string/action_add_to_workspace" > + android:exported="true"> diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index 750f673625..e1456b17ad 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -25,6 +25,7 @@ import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA; import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS; import static com.android.quickstep.views.RecentsView.TASK_MODALNESS; import static com.android.quickstep.views.SplitPlaceholderView.ALPHA_FLOAT; +import static com.android.quickstep.views.TaskView.FLAG_UPDATE_ALL; import android.annotation.TargetApi; import android.os.Build; @@ -73,7 +74,7 @@ public final class RecentsViewStateController extends if (toState.overviewUi) { // While animating into recents, update the visible task data as needed - builder.addOnFrameCallback(mRecentsView::loadVisibleTaskData); + builder.addOnFrameCallback(() -> mRecentsView.loadVisibleTaskData(FLAG_UPDATE_ALL)); mRecentsView.updateEmptyMessage(); } else { builder.addListener( diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java index fb58bf6422..aa770d289a 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java @@ -81,20 +81,6 @@ public class BackgroundAppState extends OverviewState { return false; } - @Override - public ScaleAndTranslation getHotseatScaleAndTranslation(Launcher launcher) { - if ((getVisibleElements(launcher) & HOTSEAT_ICONS) != 0) { - // Translate hotseat offscreen if we show it in overview. - RecentsView recentsView = launcher.getOverviewPanel(); - ScaleAndTranslation scaleAndTranslation = super.getHotseatScaleAndTranslation(launcher); - scaleAndTranslation.translationY += LayoutUtils.getShelfTrackingDistance(launcher, - launcher.getDeviceProfile(), - recentsView.getPagedOrientationHandler()); - return scaleAndTranslation; - } - return super.getHotseatScaleAndTranslation(launcher); - } - @Override protected float getDepthUnchecked(Context context) { return 1f; diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java index 5a28cfdc0e..d8a5f9bdfe 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java @@ -77,40 +77,11 @@ public class OverviewState extends LauncherState { return new ScaleAndTranslation(scale, 0, -getDefaultSwipeHeight(launcher) * parallaxFactor); } - @Override - public ScaleAndTranslation getHotseatScaleAndTranslation(Launcher launcher) { - if ((getVisibleElements(launcher) & HOTSEAT_ICONS) != 0) { - DeviceProfile dp = launcher.getDeviceProfile(); - if (dp.allAppsIconSizePx >= dp.iconSizePx) { - return new ScaleAndTranslation(1, 0, 0); - } else { - float scale = ((float) dp.allAppsIconSizePx) / dp.iconSizePx; - // Distance between the screen center (which is the pivotY for hotseat) and the - // bottom of the hotseat (which we want to preserve) - float distanceFromBottom = dp.heightPx / 2 - dp.hotseatBarBottomPaddingPx; - // On scaling, the bottom edge is moved closer to the pivotY. We move the - // hotseat back down so that the bottom edge's position is preserved. - float translationY = distanceFromBottom * (1 - scale); - return new ScaleAndTranslation(scale, 0, translationY); - } - } - return getWorkspaceScaleAndTranslation(launcher); - } - @Override public float[] getOverviewScaleAndOffset(Launcher launcher) { return new float[] {NO_SCALE, NO_OFFSET}; } - @Override - public ScaleAndTranslation getQsbScaleAndTranslation(Launcher launcher) { - if (this == OVERVIEW) { - // Treat the QSB as part of the hotseat so they move together. - return getHotseatScaleAndTranslation(launcher); - } - return super.getQsbScaleAndTranslation(launcher); - } - @Override public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) { return new PageAlphaProvider(DEACCEL_2) { diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java index 54f6ce6dc6..82bfa9b9a9 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java @@ -29,6 +29,7 @@ import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS; import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY; import static com.android.quickstep.views.RecentsView.TASK_MODALNESS; import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION; +import static com.android.quickstep.views.TaskView.FLAG_UPDATE_ALL; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PropertySetter; @@ -70,7 +71,7 @@ public class FallbackRecentsStateController implements StateHandler mRecentsView.loadVisibleTaskData(FLAG_UPDATE_ALL)); mRecentsView.updateEmptyMessage(); setProperties(toState, config, setter); diff --git a/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java index 3faf72a006..ce0ad77da3 100644 --- a/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java +++ b/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java @@ -83,34 +83,25 @@ public class StaggeredWorkspaceAnim { DeviceProfile grid = launcher.getDeviceProfile(); Workspace workspace = launcher.getWorkspace(); - CellLayout cellLayout = (CellLayout) workspace.getChildAt(workspace.getCurrentPage()); - ShortcutAndWidgetContainer currentPage = cellLayout.getShortcutsAndWidgets(); Hotseat hotseat = launcher.getHotseat(); + // Hotseat and QSB takes up two additional rows. + int totalRows = grid.inv.numRows + (grid.isVerticalBarLayout() ? 0 : 2); + + // Add animation for all the visible workspace pages + workspace.getVisiblePages() + .forEach(page -> addAnimationForPage((CellLayout) page, totalRows)); + boolean workspaceClipChildren = workspace.getClipChildren(); boolean workspaceClipToPadding = workspace.getClipToPadding(); - boolean cellLayoutClipChildren = cellLayout.getClipChildren(); - boolean cellLayoutClipToPadding = cellLayout.getClipToPadding(); boolean hotseatClipChildren = hotseat.getClipChildren(); boolean hotseatClipToPadding = hotseat.getClipToPadding(); workspace.setClipChildren(false); workspace.setClipToPadding(false); - cellLayout.setClipChildren(false); - cellLayout.setClipToPadding(false); hotseat.setClipChildren(false); hotseat.setClipToPadding(false); - // Hotseat and QSB takes up two additional rows. - int totalRows = grid.inv.numRows + (grid.isVerticalBarLayout() ? 0 : 2); - - // Set up springs on workspace items. - for (int i = currentPage.getChildCount() - 1; i >= 0; i--) { - View child = currentPage.getChildAt(i); - CellLayout.LayoutParams lp = ((CellLayout.LayoutParams) child.getLayoutParams()); - addStaggeredAnimationForView(child, lp.cellY + lp.cellVSpan, totalRows); - } - // Set up springs for the hotseat and qsb. ViewGroup hotseatIcons = hotseat.getShortcutsAndWidgets(); if (grid.isVerticalBarLayout()) { @@ -155,14 +146,37 @@ public class StaggeredWorkspaceAnim { public void onAnimationEnd(Animator animation) { workspace.setClipChildren(workspaceClipChildren); workspace.setClipToPadding(workspaceClipToPadding); - cellLayout.setClipChildren(cellLayoutClipChildren); - cellLayout.setClipToPadding(cellLayoutClipToPadding); hotseat.setClipChildren(hotseatClipChildren); hotseat.setClipToPadding(hotseatClipToPadding); } }); } + private void addAnimationForPage(CellLayout page, int totalRows) { + ShortcutAndWidgetContainer itemsContainer = page.getShortcutsAndWidgets(); + + boolean pageClipChildren = page.getClipChildren(); + boolean pageClipToPadding = page.getClipToPadding(); + + page.setClipChildren(false); + page.setClipToPadding(false); + + // Set up springs on workspace items. + for (int i = itemsContainer.getChildCount() - 1; i >= 0; i--) { + View child = itemsContainer.getChildAt(i); + CellLayout.LayoutParams lp = ((CellLayout.LayoutParams) child.getLayoutParams()); + addStaggeredAnimationForView(child, lp.cellY + lp.cellVSpan, totalRows); + } + + mAnimators.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + page.setClipChildren(pageClipChildren); + page.setClipToPadding(pageClipToPadding); + } + }); + } + /** * Setup workspace with 0 duration to prepare for our staggered animation. */ diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index f216985a94..4d8176c7e5 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -315,6 +315,10 @@ public abstract class RecentsView extends PagedView private final ClearAllButton mClearAllButton; private final Rect mClearAllButtonDeadZoneRect = new Rect(); private final Rect mTaskViewDeadZoneRect = new Rect(); + /** + * Reflects if Recents is currently in the middle of a gesture + */ + private boolean mGestureActive; private final ScrollState mScrollState = new ScrollState(); // Keeps track of the previously known visible tasks for purposes of loading/unloading task data @@ -624,8 +628,8 @@ public abstract class RecentsView extends PagedView return; } mModel.getIconCache().clear(); - unloadVisibleTaskData(); - loadVisibleTaskData(); + unloadVisibleTaskData(TaskView.FLAG_UPDATE_ICON); + loadVisibleTaskData(TaskView.FLAG_UPDATE_ICON); } public void init(OverviewActionsView actionsView, SplitPlaceholderView splitPlaceholderView) { @@ -908,7 +912,7 @@ public abstract class RecentsView extends PagedView } // Unload existing visible task data - unloadVisibleTaskData(); + unloadVisibleTaskData(TaskView.FLAG_UPDATE_ALL); TaskView ignoreResetTaskView = mIgnoreResetTaskId == -1 ? null : getTaskView(mIgnoreResetTaskId); @@ -1031,7 +1035,7 @@ public abstract class RecentsView extends PagedView updateCurveProperties(); // Update the set of visible task's data - loadVisibleTaskData(); + loadVisibleTaskData(TaskView.FLAG_UPDATE_ALL); setTaskModalness(0); } @@ -1147,7 +1151,7 @@ public abstract class RecentsView extends PagedView } // After scrolling, update the visible task's data - loadVisibleTaskData(); + loadVisibleTaskData(TaskView.FLAG_UPDATE_ALL); } // Update the high res thumbnail loader state @@ -1210,7 +1214,7 @@ public abstract class RecentsView extends PagedView * Iterates through all the tasks, and loads the associated task data for newly visible tasks, * and unloads the associated task data for tasks that are no longer visible. */ - public void loadVisibleTaskData() { + public void loadVisibleTaskData(@TaskView.TaskDataChanges int dataChanges) { if (!mOverviewStateEnabled || mTaskListChangeId == -1) { // Skip loading visible task data if we've already left the overview state, or if the // task list hasn't been loaded yet (the task views will not reflect the task list) @@ -1252,12 +1256,18 @@ public abstract class RecentsView extends PagedView continue; } if (!mHasVisibleTaskData.get(task.key.id)) { - taskView.onTaskListVisibilityChanged(true /* visible */); + // Ignore thumbnail update if it's current running task during the gesture + // We snapshot at end of gesture, it will update then + int changes = dataChanges; + if (taskView == getRunningTaskView() && mGestureActive) { + changes &= ~TaskView.FLAG_UPDATE_THUMBNAIL; + } + taskView.onTaskListVisibilityChanged(true /* visible */, changes); } mHasVisibleTaskData.put(task.key.id, visible); } else { if (mHasVisibleTaskData.get(task.key.id)) { - taskView.onTaskListVisibilityChanged(false /* visible */); + taskView.onTaskListVisibilityChanged(false /* visible */, dataChanges); } mHasVisibleTaskData.delete(task.key.id); } @@ -1267,12 +1277,12 @@ public abstract class RecentsView extends PagedView /** * Unloads any associated data from the currently visible tasks */ - private void unloadVisibleTaskData() { + private void unloadVisibleTaskData(@TaskView.TaskDataChanges int dataChanges) { for (int i = 0; i < mHasVisibleTaskData.size(); i++) { if (mHasVisibleTaskData.valueAt(i)) { TaskView taskView = getTaskView(mHasVisibleTaskData.keyAt(i)); if (taskView != null) { - taskView.onTaskListVisibilityChanged(false /* visible */); + taskView.onTaskListVisibilityChanged(false /* visible */, dataChanges); } } } @@ -1310,7 +1320,7 @@ public abstract class RecentsView extends PagedView mRecentsAnimationController = null; mLiveTileParams.setTargetSet(null); - unloadVisibleTaskData(); + unloadVisibleTaskData(TaskView.FLAG_UPDATE_ALL); setCurrentPage(0); mDwbToastShown = false; mActivity.getSystemUiController().updateUiState(UI_STATE_OVERVIEW, 0); @@ -1358,6 +1368,7 @@ public abstract class RecentsView extends PagedView * Called when a gesture from an app is starting. */ public void onGestureAnimationStart(RunningTaskInfo runningTaskInfo) { + mGestureActive = true; // This needs to be called before the other states are set since it can create the task view if (mOrientationState.setGestureActive(true)) { updateOrientationHandler(); @@ -1428,6 +1439,7 @@ public abstract class RecentsView extends PagedView * Called when a gesture from an app has finished, and the animation to the target has ended. */ public void onGestureAnimationEnd() { + mGestureActive = false; if (mOrientationState.setGestureActive(false)) { updateOrientationHandler(); } @@ -2733,7 +2745,7 @@ public abstract class RecentsView extends PagedView @Override protected void notifyPageSwitchListener(int prevPage) { super.notifyPageSwitchListener(prevPage); - loadVisibleTaskData(); + loadVisibleTaskData(TaskView.FLAG_UPDATE_ALL); updateEnabledOverlays(); } diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index 2b7e6fd059..a2acab880f 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -42,6 +42,8 @@ import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE; +import static java.lang.annotation.RetentionPolicy.SOURCE; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; @@ -67,6 +69,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; import android.widget.Toast; +import androidx.annotation.IntDef; import androidx.annotation.NonNull; import com.android.launcher3.DeviceProfile; @@ -106,6 +109,7 @@ import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.ActivityOptionsCompat; import com.android.systemui.shared.system.QuickStepContract; +import java.lang.annotation.Retention; import java.util.Collections; import java.util.List; import java.util.function.Consumer; @@ -117,6 +121,19 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { private static final String TAG = TaskView.class.getSimpleName(); + public static final int FLAG_UPDATE_ICON = 1; + public static final int FLAG_UPDATE_THUMBNAIL = FLAG_UPDATE_ICON << 1; + + public static final int FLAG_UPDATE_ALL = FLAG_UPDATE_ICON | FLAG_UPDATE_THUMBNAIL; + + /** + * Used in conjunction with {@link #onTaskListVisibilityChanged(boolean, int)}, providing more + * granularity on which components of this task require an update + */ + @Retention(SOURCE) + @IntDef({FLAG_UPDATE_ALL, FLAG_UPDATE_ICON, FLAG_UPDATE_THUMBNAIL}) + public @interface TaskDataChanges {} + /** * The alpha of a black scrim on a page in the carousel as it leaves the screen. * In the resting position of the carousel, the adjacent pages have about half this scrim. @@ -557,7 +574,19 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { } } + /** + * See {@link TaskDataChanges} + * @param visible If this task view will be visible to the user in overview or hidden + */ public void onTaskListVisibilityChanged(boolean visible) { + onTaskListVisibilityChanged(visible, FLAG_UPDATE_ALL); + } + + /** + * See {@link TaskDataChanges} + * @param visible If this task view will be visible to the user in overview or hidden + */ + public void onTaskListVisibilityChanged(boolean visible, @TaskDataChanges int changes) { if (mTask == null) { return; } @@ -568,22 +597,37 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { RecentsModel model = RecentsModel.INSTANCE.get(getContext()); TaskThumbnailCache thumbnailCache = model.getThumbnailCache(); TaskIconCache iconCache = model.getIconCache(); - mThumbnailLoadRequest = thumbnailCache.updateThumbnailInBackground( - mTask, thumbnail -> mSnapshotView.setThumbnail(mTask, thumbnail)); - mIconLoadRequest = iconCache.updateIconInBackground(mTask, - (task) -> { - setIcon(task.icon); - mDigitalWellBeingToast.initialize(mTask); - }); + + if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) { + mThumbnailLoadRequest = thumbnailCache.updateThumbnailInBackground( + mTask, thumbnail -> { + mSnapshotView.setThumbnail(mTask, thumbnail); + }); + } + if (needsUpdate(changes, FLAG_UPDATE_ICON)) { + mIconLoadRequest = iconCache.updateIconInBackground(mTask, + (task) -> { + setIcon(task.icon); + mDigitalWellBeingToast.initialize(mTask); + }); + } } else { - mSnapshotView.setThumbnail(null, null); - setIcon(null); - // Reset the task thumbnail reference as well (it will be fetched from the cache or - // reloaded next time we need it) - mTask.thumbnail = null; + if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) { + mSnapshotView.setThumbnail(null, null); + // Reset the task thumbnail reference as well (it will be fetched from the cache or + // reloaded next time we need it) + mTask.thumbnail = null; + } + if (needsUpdate(changes, FLAG_UPDATE_ICON)) { + setIcon(null); + } } } + private boolean needsUpdate(@TaskDataChanges int dataChange, @TaskDataChanges int flag) { + return (dataChange & flag) == flag; + } + private void cancelPendingLoadTasks() { if (mThumbnailLoadRequest != null) { mThumbnailLoadRequest.cancel(); diff --git a/res/drawable/add_item_dialog_background.xml b/res/drawable/add_item_dialog_background.xml new file mode 100644 index 0000000000..04bde8f5a7 --- /dev/null +++ b/res/drawable/add_item_dialog_background.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/res/drawable/add_item_dialog_button_background.xml b/res/drawable/add_item_dialog_button_background.xml new file mode 100644 index 0000000000..1b4591f8c1 --- /dev/null +++ b/res/drawable/add_item_dialog_button_background.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/add_item_confirmation_activity.xml b/res/layout/add_item_confirmation_activity.xml index b1a1efe0ac..d5e7333614 100644 --- a/res/layout/add_item_confirmation_activity.xml +++ b/res/layout/add_item_confirmation_activity.xml @@ -17,70 +17,51 @@ */ --> - + + - - - - - - - - - - - - - - - + android:layout_marginVertical="16dp" /> + android:padding="8dp" + android:orientation="horizontal">