From 0c2f0faef11a3d6397b96097c32d45f34a191dbc Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Fri, 10 Dec 2021 11:33:58 -0800 Subject: [PATCH 1/4] Display in-memory icon for app close while AdaptiveIcon loads. - We already display the BubbleTextView icon during app close since we need the shadows to ensure a clean handoff. - Previously, we waited until the icon and the AdaptiveIcon were both loaded to show the FloatingIconView. - This change immediately shows the BubbleTextView icon so that we can have something displayed in the cases where AdaptiveIcon is slow to load (ie. immediately after killing/restarting launcher). Currently there are cases where we defer some BubbleTextView drawing to ClipIconView. We can refactor in master so that ClipIconView is only used when drawable is an AdaptiveIcon. Bug: 207389002 Test: manual Change-Id: Ie54642fef4258862a155ab0aba6e49cea9c9ead0 --- .../launcher3/views/FloatingIconView.java | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index 8b7ad46dfb..41e3da2a65 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -88,7 +88,6 @@ public class FloatingIconView extends FrameLayout implements private IconLoadResult mIconLoadResult; - // Draw the drawable of the BubbleTextView behind ClipIconView to reveal the built in shadow. private View mBtvDrawable; private ClipIconView mClipIconView; @@ -349,10 +348,23 @@ public class FloatingIconView extends FrameLayout implements } } - if (!mIsOpening && btvIcon != null) { + setOriginalDrawableBackground(btvIcon); + invalidate(); + } + + /** + * Draws the drawable of the BubbleTextView behind ClipIconView + * + * This is used to: + * - Have icon displayed while Adaptive Icon is loading + * - Displays the built in shadow to ensure a clean handoff + * + * Allows nullable as this may be cleared when drawing is deferred to ClipIconView. + */ + private void setOriginalDrawableBackground(@Nullable Drawable btvIcon) { + if (!mIsOpening) { mBtvDrawable.setBackground(btvIcon); } - invalidate(); } /** @@ -457,7 +469,9 @@ public class FloatingIconView extends FrameLayout implements @Override public void onAnimationStart(Animator animator) { - if (mIconLoadResult != null && mIconLoadResult.isIconLoaded) { + if ((mIconLoadResult != null && mIconLoadResult.isIconLoaded) + || (!mIsOpening && mBtvDrawable.getBackground() != null)) { + // No need to wait for icon load since we can display the BubbleTextView drawable. setVisibility(View.VISIBLE); } if (!mIsOpening) { @@ -520,6 +534,7 @@ public class FloatingIconView extends FrameLayout implements IconLoadResult result = new IconLoadResult(info, btvIcon == null ? false : btvIcon.isThemed()); + result.btvDrawable = btvIcon; final long fetchIconId = sFetchIconId++; MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(() -> { @@ -558,6 +573,7 @@ public class FloatingIconView extends FrameLayout implements view.mIconLoadResult = fetchIcon(launcher, originalView, (ItemInfo) originalView.getTag(), isOpening); } + view.setOriginalDrawableBackground(view.mIconLoadResult.btvDrawable); } sIconLoadResult = null; From ab26c62c4af187cca1d5b03f5fd060b7aaf82429 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Fri, 10 Dec 2021 18:54:49 +0000 Subject: [PATCH 2/4] Allow restore across form factors - Removed deviceTypeCompatible check and allow restore across for mfactors - In AOSP default device_profile, mark 3x3, 4x4, and 5x5 as phone only. On tablets they'll reflow to 6x5. Bug: 198575341 Bug: 210129187 Test: Only 3x3, 4x4 and 5x5 are enabled on phone Test: Only 6x5 is enabled on tablet Test: Phone backup of 4x4 get restored and reflow to 6x5 on tablet Change-Id: I36a641d47fcee86ace0fea3d9194d61d12517f13 --- res/xml/device_profiles.xml | 11 +++++++---- src/com/android/launcher3/LauncherFiles.java | 2 ++ src/com/android/launcher3/model/DeviceGridState.java | 10 ---------- src/com/android/launcher3/provider/RestoreDbTask.java | 6 ------ 4 files changed, 9 insertions(+), 20 deletions(-) diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml index b4bb43e9a9..08698e7d9d 100644 --- a/res/xml/device_profiles.xml +++ b/res/xml/device_profiles.xml @@ -25,7 +25,8 @@ launcher:numFolderColumns="3" launcher:numHotseatIcons="3" launcher:dbFile="launcher_3_by_3.db" - launcher:defaultLayoutId="@xml/default_workspace_3x3" > + launcher:defaultLayoutId="@xml/default_workspace_3x3" + launcher:deviceCategory="phone|multi_display" > + launcher:defaultLayoutId="@xml/default_workspace_4x4" + launcher:deviceCategory="phone|multi_display" > + launcher:defaultLayoutId="@xml/default_workspace_5x5" + launcher:deviceCategory="phone|multi_display" > + launcher:deviceCategory="tablet" > GRID_DB_FILES = Collections.unmodifiableList(Arrays.asList( LAUNCHER_DB, + LAUNCHER_6_BY_5_DB, LAUNCHER_4_BY_5_DB, LAUNCHER_4_BY_4_DB, LAUNCHER_3_BY_3_DB, diff --git a/src/com/android/launcher3/model/DeviceGridState.java b/src/com/android/launcher3/model/DeviceGridState.java index 01ebc5347b..fa11d4e395 100644 --- a/src/com/android/launcher3/model/DeviceGridState.java +++ b/src/com/android/launcher3/model/DeviceGridState.java @@ -17,7 +17,6 @@ package com.android.launcher3.model; import static com.android.launcher3.InvariantDeviceProfile.DeviceType; -import static com.android.launcher3.InvariantDeviceProfile.TYPE_MULTI_DISPLAY; import static com.android.launcher3.InvariantDeviceProfile.TYPE_PHONE; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_2; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_3; @@ -31,7 +30,6 @@ import android.text.TextUtils; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.Utilities; import com.android.launcher3.logging.StatsLogManager.LauncherEvent; -import com.android.launcher3.util.IntSet; import java.util.Locale; import java.util.Objects; @@ -45,13 +43,6 @@ public class DeviceGridState { public static final String KEY_HOTSEAT_COUNT = "migration_src_hotseat_count"; public static final String KEY_DEVICE_TYPE = "migration_src_device_type"; - private static final IntSet COMPATIBLE_TYPES = IntSet.wrap(TYPE_PHONE, TYPE_MULTI_DISPLAY); - - public static boolean deviceTypeCompatible(@DeviceType int typeA, @DeviceType int typeB) { - return typeA == typeB - || (COMPATIBLE_TYPES.contains(typeA) && COMPATIBLE_TYPES.contains(typeB)); - } - private final String mGridSizeString; private final int mNumHotseat; private final @DeviceType int mDeviceType; @@ -123,7 +114,6 @@ public class DeviceGridState { if (this == other) return true; if (other == null) return false; return mNumHotseat == other.mNumHotseat - && deviceTypeCompatible(mDeviceType, other.mDeviceType) && Objects.equals(mGridSizeString, other.mGridSizeString); } } diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java index 4c0930bb32..d994dbec77 100644 --- a/src/com/android/launcher3/provider/RestoreDbTask.java +++ b/src/com/android/launcher3/provider/RestoreDbTask.java @@ -87,12 +87,6 @@ public class RestoreDbTask { } private static boolean performRestore(Context context, DatabaseHelper helper) { - if (!DeviceGridState.deviceTypeCompatible( - new DeviceGridState(LauncherAppState.getIDP(context)).getDeviceType(), - Utilities.getPrefs(context).getInt(RESTORED_DEVICE_TYPE, TYPE_PHONE))) { - // DO NOT restore if the device types are incompatible. - return false; - } SQLiteDatabase db = helper.getWritableDatabase(); try (SQLiteTransaction t = new SQLiteTransaction(db)) { RestoreDbTask task = new RestoreDbTask(); From 4c98374d99a78bf6f0524cbf51d2e332065391f6 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Fri, 10 Dec 2021 13:09:53 +0000 Subject: [PATCH 3/4] DeviceProfile.overviewRowSpacing should exclude extra top margin on grid tasks Bug: 207350366 Bug: 210158657 Test: manual Change-Id: I28116407c4267259a75fd39637104cea9db73fe3 --- .../src/com/android/quickstep/TaplTestsQuickstep.java | 4 +++- src/com/android/launcher3/DeviceProfile.java | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java index 7c503be4a1..237e426fb6 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java @@ -37,6 +37,7 @@ import com.android.launcher3.tapl.LauncherInstrumentation.NavigationModel; import com.android.launcher3.tapl.Overview; import com.android.launcher3.tapl.OverviewActions; import com.android.launcher3.tapl.OverviewTask; +import com.android.launcher3.tapl.TestHelpers; import com.android.launcher3.ui.TaplTestsLauncher3; import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord; import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch; @@ -321,7 +322,8 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest { @Test @PortraitLandscape public void testOverviewForTablet() throws Exception { - if (!mLauncher.isTablet()) { + // TODO(b/210158657): Re-enable for OOP + if (!mLauncher.isTablet() || !TestHelpers.isInLauncherProcess()) { return; } for (int i = 2; i <= 14; i++) { diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 6a399ac50f..d2b9dfe0e5 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -394,7 +394,13 @@ public class DeviceProfile { } overviewActionsMarginThreeButtonPx = res.getDimensionPixelSize( R.dimen.overview_actions_margin_three_button); - overviewRowSpacing = res.getDimensionPixelSize(R.dimen.overview_grid_row_spacing); + // Grid task's top margin is only overviewTaskIconSizePx + overviewTaskMarginGridPx, but + // overviewTaskThumbnailTopMarginPx is applied to all TaskThumbnailView, so exclude the + // extra margin when calculating row spacing. + int extraTopMargin = overviewTaskThumbnailTopMarginPx - overviewTaskIconSizePx + - overviewTaskMarginGridPx; + overviewRowSpacing = res.getDimensionPixelSize(R.dimen.overview_grid_row_spacing) + - extraTopMargin; overviewGridSideMargin = isLandscape ? res.getDimensionPixelSize(R.dimen.overview_grid_side_margin_landscape) : res.getDimensionPixelSize(R.dimen.overview_grid_side_margin_portrait); From c7b8957bbb80f3132d304b4af4affa9b27770741 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Fri, 10 Dec 2021 22:02:37 +0000 Subject: [PATCH 4/4] Report contentInsets only based on what they will be inside apps This avoids changing them when going from an app to launcher (most obvious when going to overview). This also allows us to not change insets on apps when opening/closing IME, which reduces potential jumpiness. Finally, also use this logic for 3P launchers by calling directly from TaskbarDragLayerController instead of TaskbarUIController (which was only overridden by LauncherTaskbarUIController). This fixes some bad issues like sending fullscreen insets when opening a folder from taskbar. Test: Open Calculator, unstash taskbar, go to overview and ensure no jump as taskbar stashes. Fixes: 200805319 Change-Id: I4f1cc187398d0051863ff44ea90b7ab9c6aaa8f9 --- .../taskbar/LauncherTaskbarUIController.java | 8 -------- .../taskbar/TaskbarDragLayerController.java | 7 +++++-- .../taskbar/TaskbarStashController.java | 16 +++++++++++++--- .../launcher3/taskbar/TaskbarUIController.java | 3 --- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index 2622700871..5e8db69f2b 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -20,7 +20,6 @@ import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_EXTR import android.animation.Animator; import android.annotation.ColorInt; -import android.graphics.Rect; import android.os.RemoteException; import android.util.Log; import android.view.MotionEvent; @@ -114,13 +113,6 @@ public class LauncherTaskbarUIController extends TaskbarUIController { return !mTaskbarLauncherStateController.isAnimatingToLauncher(); } - @Override - protected void updateContentInsets(Rect outContentInsets) { - int contentHeight = mControllers.taskbarStashController.getContentHeight(); - TaskbarDragLayer dragLayer = mControllers.taskbarActivityContext.getDragLayer(); - outContentInsets.top = dragLayer.getHeight() - contentHeight; - } - /** * Should be called from onResume() and onPause(), and animates the Taskbar accordingly. */ diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java index 806b39093f..a918016cc6 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java @@ -181,10 +181,13 @@ public class TaskbarDragLayerController { } /** - * Called to update the {@link InsetsInfo#contentInsets}. + * Called to update the {@link InsetsInfo#contentInsets}. This is reported to apps but our + * internal launcher will ignore these insets. */ public void updateContentInsets(Rect outContentInsets) { - mControllers.uiController.updateContentInsets(outContentInsets); + int contentHeight = mControllers.taskbarStashController + .getContentHeightToReportToApps(); + outContentInsets.top = mTaskbarDragLayer.getHeight() - contentHeight; } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index a3ad83504c..5c31e05996 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -53,10 +53,17 @@ public class TaskbarStashController { public static final int FLAG_IN_STASHED_LAUNCHER_STATE = 1 << 6; // If we're in an app and any of these flags are enabled, taskbar should be stashed. - public static final int FLAGS_STASHED_IN_APP = FLAG_STASHED_IN_APP_MANUAL + private static final int FLAGS_STASHED_IN_APP = FLAG_STASHED_IN_APP_MANUAL | FLAG_STASHED_IN_APP_PINNED | FLAG_STASHED_IN_APP_EMPTY | FLAG_STASHED_IN_APP_SETUP | FLAG_STASHED_IN_APP_IME; + // If any of these flags are enabled, inset apps by our stashed height instead of our unstashed + // height. This way the reported insets are consistent even during transitions out of the app. + // Currently any flag that causes us to stash in an app is included, except for IME since that + // covers the underlying app anyway and thus the app shouldn't change insets. + private static final int FLAGS_REPORT_STASHED_INSETS_TO_APP = FLAGS_STASHED_IN_APP + & ~FLAG_STASHED_IN_APP_IME; + /** * How long to stash/unstash when manually invoked via long press. */ @@ -239,8 +246,11 @@ public class TaskbarStashController { return !mIsStashed && (mState & FLAG_IN_APP) != 0; } - public int getContentHeight() { - if (isStashed()) { + /** + * Returns the height that taskbar will inset when inside apps. + */ + public int getContentHeightToReportToApps() { + if (hasAnyFlag(FLAGS_REPORT_STASHED_INSETS_TO_APP)) { boolean isAnimating = mAnimator != null && mAnimator.isStarted(); return mControllers.stashedHandleViewController.isStashedHandleVisible() || isAnimating ? mStashedHeight : 0; diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java index f6bc785a14..abad9060ab 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java @@ -15,7 +15,6 @@ */ package com.android.launcher3.taskbar; -import android.graphics.Rect; import android.view.View; import androidx.annotation.CallSuper; @@ -49,8 +48,6 @@ public class TaskbarUIController { return true; } - protected void updateContentInsets(Rect outContentInsets) { } - protected void onStashedInAppChanged() { } public Stream getAppIconsForEdu() {